Update files
This commit is contained in:
@@ -2,7 +2,6 @@ import {
|
|||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
Pressable,
|
Pressable,
|
||||||
Animated,
|
|
||||||
ActivityIndicator,
|
ActivityIndicator,
|
||||||
StyleProp,
|
StyleProp,
|
||||||
ViewStyle,
|
ViewStyle,
|
||||||
@@ -19,6 +18,14 @@ import {
|
|||||||
useContext,
|
useContext,
|
||||||
} from "react";
|
} from "react";
|
||||||
import type { ReactNode, ComponentType } 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 Markdown, { MarkdownIt } from "react-native-markdown-display";
|
||||||
import * as Linking from "expo-linking";
|
import * as Linking from "expo-linking";
|
||||||
import {
|
import {
|
||||||
@@ -980,38 +987,23 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
const hasDetails = Boolean(renderDetails);
|
const hasDetails = Boolean(renderDetails);
|
||||||
const detailContent = hasDetails && isExpanded ? renderDetails?.() : null;
|
const detailContent = hasDetails && isExpanded ? renderDetails?.() : null;
|
||||||
|
|
||||||
const spinAnim = useRef(new Animated.Value(0)).current;
|
const rotation = useSharedValue(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let loop: Animated.CompositeAnimation | null = null;
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
spinAnim.setValue(0);
|
rotation.value = 0;
|
||||||
loop = Animated.loop(
|
rotation.value = withRepeat(
|
||||||
Animated.timing(spinAnim, {
|
withTiming(360, { duration: 1400, easing: Easing.linear }),
|
||||||
toValue: 1,
|
-1
|
||||||
duration: 1400,
|
|
||||||
useNativeDriver: true,
|
|
||||||
easing: (t) => t,
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
loop.start();
|
|
||||||
} else {
|
} else {
|
||||||
spinAnim.stopAnimation();
|
cancelAnimation(rotation);
|
||||||
}
|
}
|
||||||
|
}, [isLoading]);
|
||||||
|
|
||||||
return () => {
|
const spinStyle = useAnimatedStyle(() => ({
|
||||||
loop?.stop();
|
transform: [{ rotate: `${rotation.value}deg` }],
|
||||||
};
|
}));
|
||||||
}, [isLoading, spinAnim]);
|
|
||||||
|
|
||||||
const spin = useMemo(
|
|
||||||
() =>
|
|
||||||
spinAnim.interpolate({
|
|
||||||
inputRange: [0, 1],
|
|
||||||
outputRange: ["0deg", "360deg"],
|
|
||||||
}),
|
|
||||||
[spinAnim]
|
|
||||||
);
|
|
||||||
|
|
||||||
const IconComponent = icon;
|
const IconComponent = icon;
|
||||||
const iconColor = isError
|
const iconColor = isError
|
||||||
@@ -1021,7 +1013,7 @@ const ExpandableBadge = memo(function ExpandableBadge({
|
|||||||
let iconNode: ReactNode = null;
|
let iconNode: ReactNode = null;
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
iconNode = (
|
iconNode = (
|
||||||
<Animated.View style={{ transform: [{ rotate: spin }] }}>
|
<Animated.View style={spinStyle}>
|
||||||
<Loader2 size={12} color={iconColor} />
|
<Loader2 size={12} color={iconColor} />
|
||||||
</Animated.View>
|
</Animated.View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -799,7 +799,6 @@ export class AgentManager {
|
|||||||
// Await the generator's .return() to ensure the finally block runs
|
// Await the generator's .return() to ensure the finally block runs
|
||||||
// and pendingRun is properly cleared before we return.
|
// and pendingRun is properly cleared before we return.
|
||||||
await pendingRun.return(undefined as unknown as AgentStreamEvent);
|
await pendingRun.return(undefined as unknown as AgentStreamEvent);
|
||||||
return true;
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
{ err: error, agentId },
|
{ err: error, agentId },
|
||||||
@@ -807,6 +806,24 @@ export class AgentManager {
|
|||||||
);
|
);
|
||||||
throw error;
|
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[] {
|
getPendingPermissions(agentId: string): AgentPermissionRequest[] {
|
||||||
|
|||||||
Reference in New Issue
Block a user