From 53d2843fbc8c548a739d4aff35a7b06f9fc449d7 Mon Sep 17 00:00:00 2001 From: "kiloconnect[bot]" <240665456+kiloconnect[bot]@users.noreply.github.com> Date: Thu, 26 Feb 2026 09:05:03 +0000 Subject: [PATCH] fix: only resolve run-session when root session goes idle, not subagent sessions The onSessionStatusChanged callback in run-session.ts resolved the session as done when *any* session went idle. When a subagent (child session) finished, it emitted an idle status event too, causing premature resolution with the subagent's partial result. Pass sessionID through the onSessionStatusChanged callback so consumers can distinguish which session changed status, and check that only the root session's idle event triggers resolution in run-session.ts. --- .../app-builder/project-manager/sessions/v2/streaming.ts | 2 +- src/components/cloud-agent-next/useCloudAgentStream.ts | 2 +- src/lib/cloud-agent-next/processor/event-processor.ts | 4 ++-- src/lib/cloud-agent-next/processor/types.ts | 2 +- src/lib/cloud-agent-next/run-session.ts | 5 +++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/components/app-builder/project-manager/sessions/v2/streaming.ts b/src/components/app-builder/project-manager/sessions/v2/streaming.ts index fdf327183..cca323c95 100644 --- a/src/components/app-builder/project-manager/sessions/v2/streaming.ts +++ b/src/components/app-builder/project-manager/sessions/v2/streaming.ts @@ -180,7 +180,7 @@ export function createV2StreamingCoordinator(config: V2StreamingConfig): V2Strea }); }, - onSessionStatusChanged: status => { + onSessionStatusChanged: (status, _sessionId) => { if (status.type === 'idle') { store.setState({ isStreaming: false }); onStreamComplete?.(); diff --git a/src/components/cloud-agent-next/useCloudAgentStream.ts b/src/components/cloud-agent-next/useCloudAgentStream.ts index 7ac88150f..6ab07dba0 100644 --- a/src/components/cloud-agent-next/useCloudAgentStream.ts +++ b/src/components/cloud-agent-next/useCloudAgentStream.ts @@ -239,7 +239,7 @@ export function useCloudAgentStream({ } }, - onSessionStatusChanged: status => { + onSessionStatusChanged: (status, _sessionId) => { setSessionStatus(status); // Handle streaming state based on status diff --git a/src/lib/cloud-agent-next/processor/event-processor.ts b/src/lib/cloud-agent-next/processor/event-processor.ts index b745ca8e2..e795e4102 100644 --- a/src/lib/cloud-agent-next/processor/event-processor.ts +++ b/src/lib/cloud-agent-next/processor/event-processor.ts @@ -309,9 +309,9 @@ export function createEventProcessor(config: EventProcessorConfig = {}): EventPr * Handle session.status events. */ function handleSessionStatus(data: EventSessionStatus['properties']): void { - const { status } = data; + const { status, sessionID } = data; - callbacks.onSessionStatusChanged?.(status); + callbacks.onSessionStatusChanged?.(status, sessionID); // Update streaming state based on status if (status.type === 'idle') { diff --git a/src/lib/cloud-agent-next/processor/types.ts b/src/lib/cloud-agent-next/processor/types.ts index 7fd73e911..dc3e83121 100644 --- a/src/lib/cloud-agent-next/processor/types.ts +++ b/src/lib/cloud-agent-next/processor/types.ts @@ -70,7 +70,7 @@ export type EventProcessorCallbacks = { ) => void; /** Called when session status changes (idle/busy/retry) */ - onSessionStatusChanged?: (status: SessionStatus) => void; + onSessionStatusChanged?: (status: SessionStatus, sessionId: string) => void; /** Called when a new session is created (session.created event) */ onSessionCreated?: (sessionInfo: Session) => void; diff --git a/src/lib/cloud-agent-next/run-session.ts b/src/lib/cloud-agent-next/run-session.ts index 3fd979720..baa49d136 100644 --- a/src/lib/cloud-agent-next/run-session.ts +++ b/src/lib/cloud-agent-next/run-session.ts @@ -242,8 +242,9 @@ export async function runSessionToCompletion(input: RunSessionInput): Promise { - if (status.type === 'idle') resolveOnce(); + onSessionStatusChanged: (status, eventSessionId) => { + // Only resolve when the root session goes idle, not subagent/child sessions. + if (status.type === 'idle' && eventSessionId === sessionId) resolveOnce(); }, onError: error => { hasError = true;