mirror of https://github.com/kortix-ai/suna.git
live updates fix v1
This commit is contained in:
parent
2fea768be9
commit
7686feac2b
|
@ -239,39 +239,56 @@ export const RightPanel: React.FC<RightPanelProps> = ({ isVisible, onClose, mess
|
|||
const renderStatusBadge = () => {
|
||||
const isOnLatest = currentSnapshotIndex === totalSnapshots - 1;
|
||||
|
||||
if (isGenerating) {
|
||||
return (
|
||||
<View style={[styles.statusBadge, {
|
||||
backgroundColor: theme.primary + '10',
|
||||
borderColor: theme.primary + '30'
|
||||
}]}>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.primary }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.primary }]}>Live</Caption>
|
||||
</View>
|
||||
);
|
||||
} else if (isOnLatest) {
|
||||
return (
|
||||
<View style={[styles.statusBadge, {
|
||||
backgroundColor: theme.accent + '10',
|
||||
borderColor: theme.accent + '30'
|
||||
}]}>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.accent }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.accent }]}>Latest</Caption>
|
||||
</View>
|
||||
);
|
||||
if (isLiveMode) {
|
||||
if (isGenerating) {
|
||||
return (
|
||||
<View style={[styles.statusBadge, {
|
||||
backgroundColor: theme.primary + '10',
|
||||
borderColor: theme.primary + '30'
|
||||
}]}>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.primary }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.primary }]}>Live Updates</Caption>
|
||||
</View>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<View style={[styles.statusBadge, {
|
||||
backgroundColor: theme.accent + '10',
|
||||
borderColor: theme.accent + '30'
|
||||
}]}>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.accent }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.accent }]}>Latest Tool</Caption>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.statusBadge, {
|
||||
backgroundColor: theme.muted + '20',
|
||||
borderColor: theme.border
|
||||
}]}
|
||||
onPress={handleJumpToLatest}
|
||||
>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.mutedForeground }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.mutedForeground }]}>Jump to latest</Caption>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
if (isGenerating) {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.statusBadge, {
|
||||
backgroundColor: theme.primary + '10',
|
||||
borderColor: theme.primary + '30'
|
||||
}]}
|
||||
onPress={handleJumpToLatest}
|
||||
>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.primary }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.primary }]}>Jump to Live</Caption>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
style={[styles.statusBadge, {
|
||||
backgroundColor: theme.muted + '20',
|
||||
borderColor: theme.border
|
||||
}]}
|
||||
onPress={handleJumpToLatest}
|
||||
>
|
||||
<View style={[styles.statusDot, { backgroundColor: theme.mutedForeground }]} />
|
||||
<Caption style={[styles.statusText, { color: theme.mutedForeground }]}>Jump to latest</Caption>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -400,6 +400,19 @@ export const useUIStore = create<UIState>()(
|
|||
};
|
||||
}),
|
||||
|
||||
jumpToLive: () => set((state) => {
|
||||
const snapshots = state.toolViewState.toolCallSnapshots;
|
||||
if (snapshots.length === 0) return state;
|
||||
|
||||
return {
|
||||
toolViewState: {
|
||||
...state.toolViewState,
|
||||
currentSnapshotIndex: snapshots.length - 1,
|
||||
navigationMode: 'live',
|
||||
}
|
||||
};
|
||||
}),
|
||||
|
||||
// Legacy time playback functions
|
||||
startTimePlayback: (messages) => set((state) => ({
|
||||
toolViewState: {
|
||||
|
|
|
@ -395,6 +395,7 @@ export function ToolCallSidePanel({
|
|||
}
|
||||
setIsInitialized(true);
|
||||
} else if (hasNewSnapshots && navigationMode === 'live') {
|
||||
// When in live mode and new snapshots arrive, always follow the latest
|
||||
const latestSnapshot = newSnapshots[newSnapshots.length - 1];
|
||||
const isLatestStreaming = latestSnapshot?.toolCall.toolResult?.content === 'STREAMING';
|
||||
if (isLatestStreaming) {
|
||||
|
@ -416,8 +417,16 @@ export function ToolCallSidePanel({
|
|||
setInternalIndex(newSnapshots.length - 1);
|
||||
}
|
||||
} else if (hasNewSnapshots && navigationMode === 'manual') {
|
||||
// When in manual mode and new snapshots arrive, check if we should auto-switch to live
|
||||
// This happens when the user was at the latest snapshot before new ones arrived
|
||||
const wasAtLatest = internalIndex === toolCallSnapshots.length - 1;
|
||||
if (wasAtLatest && agentStatus === 'running') {
|
||||
// Auto-switch to live mode when new snapshots arrive and we were at the latest
|
||||
setNavigationMode('live');
|
||||
setInternalIndex(newSnapshots.length - 1);
|
||||
}
|
||||
}
|
||||
}, [toolCalls, navigationMode, toolCallSnapshots.length, isInitialized]);
|
||||
}, [toolCalls, navigationMode, toolCallSnapshots.length, isInitialized, internalIndex, agentStatus]);
|
||||
|
||||
React.useEffect(() => {
|
||||
// This is used to sync the internal index to the current index
|
||||
|
@ -444,7 +453,7 @@ export function ToolCallSidePanel({
|
|||
const lastCompletedSnapshot = completedToolCalls[completedToolCalls.length - 1];
|
||||
displayToolCall = lastCompletedSnapshot.toolCall;
|
||||
displayIndex = totalCompletedCalls - 1;
|
||||
displayTotalCalls = totalCompletedCalls;
|
||||
displayTotalCalls = totalCalls; // Show all calls including streaming
|
||||
} else if (!isCurrentToolStreaming) {
|
||||
const completedIndex = completedToolCalls.findIndex(snapshot => snapshot.id === currentSnapshot?.id);
|
||||
if (completedIndex >= 0) {
|
||||
|
|
Loading…
Reference in New Issue