live updates fix v1

This commit is contained in:
Chaitanya045 2025-09-01 22:26:56 +05:30
parent 2fea768be9
commit 7686feac2b
3 changed files with 73 additions and 34 deletions

View File

@ -239,39 +239,56 @@ export const RightPanel: React.FC<RightPanelProps> = ({ isVisible, onClose, mess
const renderStatusBadge = () => { const renderStatusBadge = () => {
const isOnLatest = currentSnapshotIndex === totalSnapshots - 1; const isOnLatest = currentSnapshotIndex === totalSnapshots - 1;
if (isGenerating) { if (isLiveMode) {
return ( if (isGenerating) {
<View style={[styles.statusBadge, { return (
backgroundColor: theme.primary + '10', <View style={[styles.statusBadge, {
borderColor: theme.primary + '30' 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 style={[styles.statusDot, { backgroundColor: theme.primary }]} />
</View> <Caption style={[styles.statusText, { color: theme.primary }]}>Live Updates</Caption>
); </View>
} else if (isOnLatest) { );
return ( } else {
<View style={[styles.statusBadge, { return (
backgroundColor: theme.accent + '10', <View style={[styles.statusBadge, {
borderColor: theme.accent + '30' 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 style={[styles.statusDot, { backgroundColor: theme.accent }]} />
</View> <Caption style={[styles.statusText, { color: theme.accent }]}>Latest Tool</Caption>
); </View>
);
}
} else { } else {
return ( if (isGenerating) {
<TouchableOpacity return (
style={[styles.statusBadge, { <TouchableOpacity
backgroundColor: theme.muted + '20', style={[styles.statusBadge, {
borderColor: theme.border backgroundColor: theme.primary + '10',
}]} borderColor: theme.primary + '30'
onPress={handleJumpToLatest} }]}
> onPress={handleJumpToLatest}
<View style={[styles.statusDot, { backgroundColor: theme.mutedForeground }]} /> >
<Caption style={[styles.statusText, { color: theme.mutedForeground }]}>Jump to latest</Caption> <View style={[styles.statusDot, { backgroundColor: theme.primary }]} />
</TouchableOpacity> <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>
);
}
} }
}; };

View File

@ -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 // Legacy time playback functions
startTimePlayback: (messages) => set((state) => ({ startTimePlayback: (messages) => set((state) => ({
toolViewState: { toolViewState: {

View File

@ -395,6 +395,7 @@ export function ToolCallSidePanel({
} }
setIsInitialized(true); setIsInitialized(true);
} else if (hasNewSnapshots && navigationMode === 'live') { } else if (hasNewSnapshots && navigationMode === 'live') {
// When in live mode and new snapshots arrive, always follow the latest
const latestSnapshot = newSnapshots[newSnapshots.length - 1]; const latestSnapshot = newSnapshots[newSnapshots.length - 1];
const isLatestStreaming = latestSnapshot?.toolCall.toolResult?.content === 'STREAMING'; const isLatestStreaming = latestSnapshot?.toolCall.toolResult?.content === 'STREAMING';
if (isLatestStreaming) { if (isLatestStreaming) {
@ -416,8 +417,16 @@ export function ToolCallSidePanel({
setInternalIndex(newSnapshots.length - 1); setInternalIndex(newSnapshots.length - 1);
} }
} else if (hasNewSnapshots && navigationMode === 'manual') { } 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(() => { React.useEffect(() => {
// This is used to sync the internal index to the current index // 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]; const lastCompletedSnapshot = completedToolCalls[completedToolCalls.length - 1];
displayToolCall = lastCompletedSnapshot.toolCall; displayToolCall = lastCompletedSnapshot.toolCall;
displayIndex = totalCompletedCalls - 1; displayIndex = totalCompletedCalls - 1;
displayTotalCalls = totalCompletedCalls; displayTotalCalls = totalCalls; // Show all calls including streaming
} else if (!isCurrentToolStreaming) { } else if (!isCurrentToolStreaming) {
const completedIndex = completedToolCalls.findIndex(snapshot => snapshot.id === currentSnapshot?.id); const completedIndex = completedToolCalls.findIndex(snapshot => snapshot.id === currentSnapshot?.id);
if (completedIndex >= 0) { if (completedIndex >= 0) {