Skip to content

Commit b6001a2

Browse files
committed
fix(tarko-agent-ui): enhance agent status monitoring after websocket removal
- Reduce status check cache TTL from 2s to 1s for more responsive updates - Add session-specific processing state updates to prevent cross-session interference - Implement enhanced status monitoring with different frequencies for processing vs idle states - Add status consistency checks after send/abort operations - Improve error handling to prevent UI state inconsistencies - Add debug logging for agent run start/end events
1 parent 21d59fb commit b6001a2

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

multimodal/tarko/agent-ui/src/common/hooks/useSession.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ export function useSession() {
5959
const checkSessionStatus = useSetAtom(checkSessionStatusAction);
6060

6161
const statusCheckTimeoutRef = useRef<NodeJS.Timeout | null>(null);
62+
const statusCheckIntervalRef = useRef<NodeJS.Timeout | null>(null);
6263

64+
// Initial status check when session changes
6365
useEffect(() => {
6466
if (!activeSessionId || !connectionStatus.connected || isReplayMode) return;
6567

@@ -80,6 +82,40 @@ export function useSession() {
8082
};
8183
}, [activeSessionId, connectionStatus.connected, checkSessionStatus, isReplayMode]);
8284

85+
// Enhanced status monitoring when processing
86+
useEffect(() => {
87+
if (!activeSessionId || !connectionStatus.connected || isReplayMode) {
88+
if (statusCheckIntervalRef.current) {
89+
clearInterval(statusCheckIntervalRef.current);
90+
statusCheckIntervalRef.current = null;
91+
}
92+
return;
93+
}
94+
95+
if (isProcessing) {
96+
// More frequent checks when processing (every 500ms)
97+
statusCheckIntervalRef.current = setInterval(() => {
98+
if (activeSessionId && connectionStatus.connected && !isReplayMode) {
99+
checkSessionStatus(activeSessionId);
100+
}
101+
}, 500);
102+
} else {
103+
// Less frequent checks when idle (every 3 seconds)
104+
statusCheckIntervalRef.current = setInterval(() => {
105+
if (activeSessionId && connectionStatus.connected && !isReplayMode) {
106+
checkSessionStatus(activeSessionId);
107+
}
108+
}, 3000);
109+
}
110+
111+
return () => {
112+
if (statusCheckIntervalRef.current) {
113+
clearInterval(statusCheckIntervalRef.current);
114+
statusCheckIntervalRef.current = null;
115+
}
116+
};
117+
}, [activeSessionId, connectionStatus.connected, isReplayMode, isProcessing, checkSessionStatus]);
118+
83119
const sessionState = useMemo(
84120
() => ({
85121
sessions,

multimodal/tarko/agent-ui/src/common/state/actions/eventProcessors/handlers/AgentRunHandler.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isProcessingAtom } from '@/common/state/atoms/ui';
2+
import { activeSessionIdAtom } from '@/common/state/atoms/session';
23
import { AgentEventStream } from '@/common/types';
34
import { EventHandler, EventHandlerContext } from '../types';
45
import { shouldUpdateProcessingState } from '../utils/panelContentUpdater';
@@ -13,11 +14,13 @@ export class AgentRunStartHandler implements EventHandler<AgentEventStream.Agent
1314
sessionId: string,
1415
event: AgentEventStream.AgentRunStartEvent,
1516
): void {
16-
const { set } = context;
17+
const { get, set } = context;
1718

18-
// Update processing state
19-
if (shouldUpdateProcessingState(sessionId)) {
19+
// Only update processing state for the active session
20+
const activeSessionId = get(activeSessionIdAtom);
21+
if (shouldUpdateProcessingState(sessionId) && sessionId === activeSessionId) {
2022
set(isProcessingAtom, true);
23+
console.debug(`Agent run started for session ${sessionId}`);
2124
}
2225
}
2326
}
@@ -28,11 +31,13 @@ export class AgentRunEndHandler implements EventHandler<AgentEventStream.Event>
2831
}
2932

3033
handle(context: EventHandlerContext, sessionId: string, event: AgentEventStream.Event): void {
31-
const { set } = context;
34+
const { get, set } = context;
3235

33-
// Update processing state
34-
if (shouldUpdateProcessingState(sessionId)) {
36+
// Only update processing state for the active session
37+
const activeSessionId = get(activeSessionIdAtom);
38+
if (shouldUpdateProcessingState(sessionId) && sessionId === activeSessionId) {
3539
set(isProcessingAtom, false);
40+
console.debug(`Agent run ended for session ${sessionId}`);
3641
}
3742
}
3843
}

multimodal/tarko/agent-ui/src/common/state/actions/sessionActions.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,14 @@ export const sendMessageAction = atom(
371371
console.error('Error sending message:', error);
372372
// Set processing to false on error
373373
set(isProcessingAtom, false);
374+
375+
// Trigger a status check to ensure state consistency
376+
setTimeout(() => {
377+
if (get(activeSessionIdAtom) === activeSessionId) {
378+
set(checkSessionStatusAction, activeSessionId);
379+
}
380+
}, 100);
381+
374382
throw error;
375383
}
376384
},
@@ -391,18 +399,33 @@ export const abortQueryAction = atom(null, async (get, set) => {
391399
set(isProcessingAtom, false);
392400
}
393401

402+
// Always check status after abort attempt to ensure consistency
403+
setTimeout(() => {
404+
if (get(activeSessionIdAtom) === activeSessionId) {
405+
set(checkSessionStatusAction, activeSessionId);
406+
}
407+
}, 100);
408+
394409
return success;
395410
} catch (error) {
396411
console.error('Error aborting query:', error);
397412
// Also set processing to false on error to ensure UI consistency
398413
set(isProcessingAtom, false);
414+
415+
// Check status even on error to ensure consistency
416+
setTimeout(() => {
417+
if (get(activeSessionIdAtom) === activeSessionId) {
418+
set(checkSessionStatusAction, activeSessionId);
419+
}
420+
}, 100);
421+
399422
return false;
400423
}
401424
});
402425

403426
// Cache to prevent frequent status checks for the same session
404427
const statusCheckCache = new Map<string, { timestamp: number; promise?: Promise<any> }>();
405-
const STATUS_CACHE_TTL = 2000; // 2 seconds cache
428+
const STATUS_CACHE_TTL = 1000; // Reduced to 1 second cache for more responsive updates
406429

407430
export const checkSessionStatusAction = atom(null, async (get, set, sessionId: string) => {
408431
if (!sessionId) return;
@@ -429,8 +452,11 @@ export const checkSessionStatusAction = atom(null, async (get, set, sessionId: s
429452

430453
const status = await promise;
431454

432-
// Update simple processing state
433-
set(isProcessingAtom, status.isProcessing);
455+
// Only update processing state if this is the active session
456+
const activeSessionId = get(activeSessionIdAtom);
457+
if (sessionId === activeSessionId) {
458+
set(isProcessingAtom, status.isProcessing);
459+
}
434460

435461
// Clear the promise and update timestamp
436462
statusCheckCache.set(sessionId, { timestamp: now });
@@ -440,5 +466,7 @@ export const checkSessionStatusAction = atom(null, async (get, set, sessionId: s
440466
console.error('Failed to check session status:', error);
441467
// Clear the failed request
442468
statusCheckCache.delete(sessionId);
469+
// Don't throw to prevent breaking the UI
470+
return null;
443471
}
444472
});

0 commit comments

Comments
 (0)