From 41f07ecb60d12039c890e9a575c8bdacd8d10da0 Mon Sep 17 00:00:00 2001 From: erkkiat Date: Tue, 28 Jul 2026 22:33:03 +0300 Subject: [PATCH] fix: continue session loop when response is truncated by length When a model's finish reason is "length" (hit the output token cap mid-turn) and no tool call was started, the session loop currently ends and goes idle, requiring the user to manually type "continue". This treats "length" like "tool-calls" so the loop keeps going automatically instead. --- packages/opencode/src/session/prompt.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index eb116f6b960f..e3c021b574e0 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -1108,7 +1108,18 @@ const layer = Layer.effect( (part) => part.type === "tool" && !part.metadata?.providerExecuted && !isOrphanedInterruptedTool(part), ) ?? false - if ( + if (lastAssistant?.finish === "length" && !hasToolCalls && lastUser.id < lastAssistant.id) { + // The model hit its output token cap mid-turn (e.g. a heavy reasoning + // model burning its budget on thinking with no room left for the + // answer/tool call). Treat this like "tool-calls": keep looping so a + // fresh step continues from where the truncated message left off, + // instead of silently going idle and waiting for the user to type + // "continue". + yield* Effect.logWarning("continuing loop after truncated (length) finish reason", { + "session.id": sessionID, + messageID: lastAssistant.id, + }) + } else if ( lastAssistant?.finish && !["tool-calls"].includes(lastAssistant.finish) && !hasToolCalls &&