From a7a00a1a260a5950f078814624640924f75b7fa4 Mon Sep 17 00:00:00 2001 From: DoSun Date: Tue, 19 May 2026 19:30:12 +0800 Subject: [PATCH] fix: use callID matching for task progress part updates Remove mainPartID/mainMessageID from SubagentToolState. Emit message.part.updated with random id and callID for task progress, so consumer can match by callID when part IDs differ after tab switch. --- src/server/sessionMessageRouter.ts | 52 ++++++++++++------------------ 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/src/server/sessionMessageRouter.ts b/src/server/sessionMessageRouter.ts index 29da3fc3a..b518d6a33 100644 --- a/src/server/sessionMessageRouter.ts +++ b/src/server/sessionMessageRouter.ts @@ -12,8 +12,6 @@ type SubagentToolState = { emittedToolCount: number assistantMessageID: string toolPartIDs: Map - mainPartID: string - mainMessageID: string mainToolUseID: string progressLines: string[] } @@ -702,8 +700,6 @@ function emitTaskStarted(msg: StdoutMessage, ctx: MessageRouterCtx): void { emittedToolCount: 0, assistantMessageID, toolPartIDs: new Map(), - mainPartID: '', - mainMessageID: '', mainToolUseID: toolUseIdForMain ?? '', progressLines: [], }) @@ -771,39 +767,33 @@ function emitTaskProgress(msg: StdoutMessage, ctx: MessageRouterCtx): void { const toolState = subagentToolState.get(agentId) if (!toolState) return - if (!toolState.mainPartID && toolState.mainToolUseID) { - const info = getCompletedToolInfo(ctx.sessionId, toolState.mainToolUseID) - if (info) { - toolState.mainPartID = info.partID - toolState.mainMessageID = info.messageID - } - } - - if (description && toolState.mainPartID) { + if (description) { const lines = toolState.progressLines lines.push(description) if (lines.length > 3) lines.splice(0, lines.length - 3) toolState.progressLines = lines - const mainToolInfo = getCompletedToolInfo(ctx.sessionId, toolState.mainToolUseID) - ctx.emitOpencodeEvent('message.part.updated', { - sessionID: ctx.sessionId, - part: { - type: 'tool', - id: toolState.mainPartID, - callID: toolState.mainToolUseID, - tool: mainToolInfo?.toolName ? normalizeToolName(mainToolInfo.toolName) : 'task', - state: { - status: 'running', - input: mainToolInfo?.input ?? {}, - title: mainToolInfo?.title ?? '', - time: { start: mainToolInfo?.startTime ?? Date.now() }, - progress: toolState.progressLines, - }, - messageID: toolState.mainMessageID, + if (toolState.mainToolUseID) { + const mainToolInfo = getCompletedToolInfo(ctx.sessionId, toolState.mainToolUseID) + ctx.emitOpencodeEvent('message.part.updated', { sessionID: ctx.sessionId, - }, - }) + part: { + type: 'tool', + id: randomUUID(), + callID: toolState.mainToolUseID, + tool: mainToolInfo?.toolName ? normalizeToolName(mainToolInfo.toolName) : 'task', + state: { + status: 'running', + input: mainToolInfo?.input ?? {}, + title: mainToolInfo?.title ?? '', + time: { start: mainToolInfo?.startTime ?? Date.now() }, + progress: toolState.progressLines, + }, + messageID: mainToolInfo?.messageID ?? '', + sessionID: ctx.sessionId, + }, + }) + } } while (toolState.emittedToolCount < toolUses) {