From 418fe78f5db2c6c746f8cf8448369a64dd6d3a08 Mon Sep 17 00:00:00 2001 From: Alex Alecu Date: Fri, 24 Apr 2026 18:05:45 +0300 Subject: [PATCH] fix(cli): sync processor cost after subagent propagation finish-step and cleanup previously re-wrote the parent assistant message with a stale in-memory cost, clobbering the subagent cost written by task.ts during tool execution. Refresh from DB before each write so the propagated cost is preserved across steps. Verified live via side-by-side `kilo serve` vs dev `bun serve` with 2 parallel subagents; parent now shows own LLM + children, matching real spend. --- packages/opencode/src/session/processor.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/opencode/src/session/processor.ts b/packages/opencode/src/session/processor.ts index 6a825cd3fc0..1dd7c2ded2b 100644 --- a/packages/opencode/src/session/processor.ts +++ b/packages/opencode/src/session/processor.ts @@ -410,6 +410,14 @@ export const layer: Layer.Layer< }) // kilocode_change end ctx.assistantMessage.finish = value.finishReason + // kilocode_change start - capture any subagent cost propagated by tool calls during this step (#6321) + const fresh = yield* Effect.sync(() => + MessageV2.get({ sessionID: ctx.assistantMessage.sessionID, messageID: ctx.assistantMessage.id }), + ) + if (fresh.info.role === "assistant" && fresh.info.cost > ctx.assistantMessage.cost) { + ctx.assistantMessage.cost = fresh.info.cost + } + // kilocode_change end ctx.assistantMessage.cost += usage.cost ctx.assistantMessage.tokens = usage.tokens yield* session.updatePart({ @@ -567,6 +575,14 @@ export const layer: Layer.Layer< ctx.toolcalls = {} KiloSessionProcessor.guardEmptyToolCalls(ctx.assistantMessage, MessageV2.parts(ctx.assistantMessage.id)) // kilocode_change ctx.assistantMessage.time.completed = Date.now() + // kilocode_change start - reconcile cost with any subagent propagation written during tool calls (#6321) + const fresh = yield* Effect.sync(() => + MessageV2.get({ sessionID: ctx.assistantMessage.sessionID, messageID: ctx.assistantMessage.id }), + ) + if (fresh.info.role === "assistant" && fresh.info.cost > ctx.assistantMessage.cost) { + ctx.assistantMessage.cost = fresh.info.cost + } + // kilocode_change end yield* session.updateMessage(ctx.assistantMessage) })