Update files

This commit is contained in:
Mohamed Boudra
2026-02-08 09:15:39 +07:00
parent 061c084269
commit b4a93955e3
2 changed files with 37 additions and 28 deletions

View File

@@ -2,7 +2,6 @@ import {
View,
Text,
Pressable,
Animated,
ActivityIndicator,
StyleProp,
ViewStyle,
@@ -19,6 +18,14 @@ import {
useContext,
} from "react";
import type { ReactNode, ComponentType } from "react";
import Animated, {
useSharedValue,
useAnimatedStyle,
withRepeat,
withTiming,
Easing,
cancelAnimation,
} from "react-native-reanimated";
import Markdown, { MarkdownIt } from "react-native-markdown-display";
import * as Linking from "expo-linking";
import {
@@ -980,38 +987,23 @@ const ExpandableBadge = memo(function ExpandableBadge({
const hasDetails = Boolean(renderDetails);
const detailContent = hasDetails && isExpanded ? renderDetails?.() : null;
const spinAnim = useRef(new Animated.Value(0)).current;
const rotation = useSharedValue(0);
useEffect(() => {
let loop: Animated.CompositeAnimation | null = null;
if (isLoading) {
spinAnim.setValue(0);
loop = Animated.loop(
Animated.timing(spinAnim, {
toValue: 1,
duration: 1400,
useNativeDriver: true,
easing: (t) => t,
})
rotation.value = 0;
rotation.value = withRepeat(
withTiming(360, { duration: 1400, easing: Easing.linear }),
-1
);
loop.start();
} else {
spinAnim.stopAnimation();
cancelAnimation(rotation);
}
}, [isLoading]);
return () => {
loop?.stop();
};
}, [isLoading, spinAnim]);
const spin = useMemo(
() =>
spinAnim.interpolate({
inputRange: [0, 1],
outputRange: ["0deg", "360deg"],
}),
[spinAnim]
);
const spinStyle = useAnimatedStyle(() => ({
transform: [{ rotate: `${rotation.value}deg` }],
}));
const IconComponent = icon;
const iconColor = isError
@@ -1021,7 +1013,7 @@ const ExpandableBadge = memo(function ExpandableBadge({
let iconNode: ReactNode = null;
if (isLoading) {
iconNode = (
<Animated.View style={{ transform: [{ rotate: spin }] }}>
<Animated.View style={spinStyle}>
<Loader2 size={12} color={iconColor} />
</Animated.View>
);

View File

@@ -799,7 +799,6 @@ export class AgentManager {
// Await the generator's .return() to ensure the finally block runs
// and pendingRun is properly cleared before we return.
await pendingRun.return(undefined as unknown as AgentStreamEvent);
return true;
} catch (error) {
this.logger.error(
{ err: error, agentId },
@@ -807,6 +806,24 @@ export class AgentManager {
);
throw error;
}
// Clear any pending permissions that weren't cleaned up by handleStreamEvent.
// Due to microtask ordering, .return() may force the generator to its finally
// block before it consumes the turn_canceled event, skipping our cleanup code.
if (agent.pendingPermissions.size > 0) {
for (const [requestId] of agent.pendingPermissions) {
this.dispatchStream(agent.id, {
type: "permission_resolved",
provider: agent.provider,
requestId,
resolution: { behavior: "deny", message: "Interrupted" },
});
}
agent.pendingPermissions.clear();
this.emitState(agent);
}
return true;
}
getPendingPermissions(agentId: string): AgentPermissionRequest[] {