From bf626395735369e4c9b4abd8e6bd0077857592db Mon Sep 17 00:00:00 2001 From: Mao Mr <49724027+hairyf@users.noreply.github.com> Date: Sat, 28 Feb 2026 17:09:00 +0800 Subject: [PATCH] fix(chat): show loading when run from console and when sending in app (#228) --- src/pages/Chat/index.tsx | 2 +- src/stores/chat.ts | 20 +++++++++++++++++++- src/stores/gateway.ts | 15 +++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/pages/Chat/index.tsx b/src/pages/Chat/index.tsx index 4874a36ad..4a2c65d2a 100644 --- a/src/pages/Chat/index.tsx +++ b/src/pages/Chat/index.tsx @@ -110,7 +110,7 @@ export function Chat() { {/* Messages Area */}
- {loading ? ( + {loading && !sending ? (
diff --git a/src/stores/chat.ts b/src/stores/chat.ts index 2928ffe94..2c475112e 100644 --- a/src/stores/chat.ts +++ b/src/stores/chat.ts @@ -1305,7 +1305,11 @@ export const useChatStore = create((set, get) => ({ handleChatEvent: (event: Record) => { const runId = String(event.runId || ''); const eventState = String(event.state || ''); - const { activeRunId } = get(); + const eventSessionKey = event.sessionKey != null ? String(event.sessionKey) : null; + const { activeRunId, currentSessionKey } = get(); + + // Only process events for the current session (when sessionKey is present) + if (eventSessionKey != null && eventSessionKey !== currentSessionKey) return; // Only process events for the active run (or if no active run set) if (activeRunId && runId && runId !== activeRunId) return; @@ -1332,9 +1336,23 @@ export const useChatStore = create((set, get) => ({ || resolvedState === 'error' || resolvedState === 'aborted'; if (hasUsefulData) { clearHistoryPoll(); + // Adopt run started from another client (e.g. console at 127.0.0.1:18789): + // show loading/streaming in the app when this session has an active run. + const { sending } = get(); + if (!sending && runId) { + set({ sending: true, activeRunId: runId, error: null }); + } } switch (resolvedState) { + case 'started': { + // Run just started (e.g. from console); show loading immediately. + const { sending: currentSending } = get(); + if (!currentSending && runId) { + set({ sending: true, activeRunId: runId, error: null }); + } + break; + } case 'delta': { // If we're receiving new deltas, the Gateway has recovered from any // prior error — cancel the error finalization timer and clear the diff --git a/src/stores/gateway.ts b/src/stores/gateway.ts index 76d5a1a91..1ee8c03f9 100644 --- a/src/stores/gateway.ts +++ b/src/stores/gateway.ts @@ -94,6 +94,21 @@ export const useGatewayStore = create((set, get) => ({ .catch(() => {}); } + // When a run starts (e.g. user clicked Send on console), show loading in the app immediately. + const runId = p.runId ?? data.runId; + const sessionKey = p.sessionKey ?? data.sessionKey; + if (phase === 'started' && runId != null && sessionKey != null) { + import('./chat') + .then(({ useChatStore }) => { + useChatStore.getState().handleChatEvent({ + state: 'started', + runId, + sessionKey, + }); + }) + .catch(() => {}); + } + // When the agent run completes, reload history to get the final response. if (phase === 'completed' || phase === 'done' || phase === 'finished' || phase === 'end') { import('./chat')