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,6 +239,7 @@ export const RightPanel: React.FC<RightPanelProps> = ({ isVisible, onClose, mess
const renderStatusBadge = () => { const renderStatusBadge = () => {
const isOnLatest = currentSnapshotIndex === totalSnapshots - 1; const isOnLatest = currentSnapshotIndex === totalSnapshots - 1;
if (isLiveMode) {
if (isGenerating) { if (isGenerating) {
return ( return (
<View style={[styles.statusBadge, { <View style={[styles.statusBadge, {
@ -246,19 +247,34 @@ export const RightPanel: React.FC<RightPanelProps> = ({ isVisible, onClose, mess
borderColor: theme.primary + '30' borderColor: theme.primary + '30'
}]}> }]}>
<View style={[styles.statusDot, { backgroundColor: theme.primary }]} /> <View style={[styles.statusDot, { backgroundColor: theme.primary }]} />
<Caption style={[styles.statusText, { color: theme.primary }]}>Live</Caption> <Caption style={[styles.statusText, { color: theme.primary }]}>Live Updates</Caption>
</View> </View>
); );
} else if (isOnLatest) { } else {
return ( return (
<View style={[styles.statusBadge, { <View style={[styles.statusBadge, {
backgroundColor: theme.accent + '10', backgroundColor: theme.accent + '10',
borderColor: theme.accent + '30' borderColor: theme.accent + '30'
}]}> }]}>
<View style={[styles.statusDot, { backgroundColor: theme.accent }]} /> <View style={[styles.statusDot, { backgroundColor: theme.accent }]} />
<Caption style={[styles.statusText, { color: theme.accent }]}>Latest</Caption> <Caption style={[styles.statusText, { color: theme.accent }]}>Latest Tool</Caption>
</View> </View>
); );
}
} else {
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 { } else {
return ( return (
<TouchableOpacity <TouchableOpacity
@ -273,6 +289,7 @@ export const RightPanel: React.FC<RightPanelProps> = ({ isVisible, onClose, mess
</TouchableOpacity> </TouchableOpacity>
); );
} }
}
}; };
if (!isVisible) return null; if (!isVisible) return null;

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) {