From 119e329dfb5980b791c456b062774c9b61139344 Mon Sep 17 00:00:00 2001 From: wuyang6 Date: Thu, 14 May 2026 18:12:11 +0800 Subject: [PATCH] Fix live activity timer --- backend/api/server.py | 6 +++++- frontend/app/components/assistant-ui/thread.tsx | 14 +++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/backend/api/server.py b/backend/api/server.py index b125373..206e082 100644 --- a/backend/api/server.py +++ b/backend/api/server.py @@ -485,6 +485,7 @@ class RunManager: 'current_stage': record.current_stage, 'started_at': record.started_at, 'updated_at': record.updated_at, + 'elapsed_ms': max(0, int((time.time() - record.started_at) * 1000)), 'pending_prompt': record.pending_prompt, 'error': record.error, 'events': [dict(event) for event in record.events], @@ -1612,7 +1613,10 @@ def create_app(state: AgentState) -> FastAPI: merged['events'] = stored_snapshot.get('events') if memory_snapshot.get('current_stage'): merged['current_stage'] = memory_snapshot.get('current_stage') - if stored_snapshot.get('elapsed_ms') is not None: + if ( + memory_snapshot.get('status') not in ACTIVE_RUN_STATUSES + and stored_snapshot.get('elapsed_ms') is not None + ): merged['elapsed_ms'] = stored_snapshot.get('elapsed_ms') if stored_snapshot.get('finished_at') is not None: merged['finished_at'] = stored_snapshot.get('finished_at') diff --git a/frontend/app/components/assistant-ui/thread.tsx b/frontend/app/components/assistant-ui/thread.tsx index 9cdeeb4..fce6998 100644 --- a/frontend/app/components/assistant-ui/thread.tsx +++ b/frontend/app/components/assistant-ui/thread.tsx @@ -2014,6 +2014,7 @@ const ActivityChainSummary: FC<{ }); const initialStartedAtMs = metadataRunStartedAtMs ?? contentRunStartedAtMs ?? messageCreatedAtMs; + const liveStartedAtRef = useRef(initialStartedAtMs); const [elapsedMs, setElapsedMs] = useState(() => { if (storedElapsedMs !== null) return storedElapsedMs; if (initialStartedAtMs !== null) { @@ -2041,11 +2042,14 @@ const ActivityChainSummary: FC<{ setElapsedMs(storedElapsedMs); return; } - const startedAt = - metadataRunStartedAtMs ?? - contentRunStartedAtMs ?? - messageCreatedAtMs ?? - (storedElapsedMs === null ? null : Date.now() - storedElapsedMs); + const explicitStartedAt = + metadataRunStartedAtMs ?? contentRunStartedAtMs ?? messageCreatedAtMs; + if (explicitStartedAt !== null) { + liveStartedAtRef.current = explicitStartedAt; + } else if (liveStartedAtRef.current === null && storedElapsedMs !== null) { + liveStartedAtRef.current = Date.now() - storedElapsedMs; + } + const startedAt = liveStartedAtRef.current; if (startedAt === null) { setElapsedMs(storedElapsedMs); return;