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