From 4287d761b183fa566dfa74b5360bf7f34fd89319 Mon Sep 17 00:00:00 2001 From: xujiejie <80671406+yingjiexu2002@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:52:51 +0800 Subject: [PATCH] feat(llmloop): backfill comment thinking from turn output (#773) * feat(llmloop): backfill comment thinking from the turn's reasoning or message Expose ChatResponse.ReasoningContent and backfill per-comment thinking with the current turn's reasoning content, falling back to the assistant message for models that do not expose reasoning, so --format json output carries thinking even when the model omits it. * fix(llmloop): drop content fallback for comment thinking backfill The turn's assistant message is usually a short user-facing preamble rather than real reasoning, so backfill per-comment thinking only from the model's native reasoning_content and leave it empty otherwise. Add a full-wiring RunPerFile test for the reasoning backfill and a regression test that fails if the content fallback returns. Sync the thinking docs across en/zh/ja/ru. * docs(llmloop): note that turn-level thinking is shared by design Document in the main loop and at the code_comment backfill site that the model emits reasoning once per turn, so every tool call and comment in the same turn intentionally shares the same thinking. --- internal/llmloop/loop_execute_more_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/llmloop/loop_execute_more_test.go b/internal/llmloop/loop_execute_more_test.go index a037887..e321403 100644 --- a/internal/llmloop/loop_execute_more_test.go +++ b/internal/llmloop/loop_execute_more_test.go @@ -61,7 +61,7 @@ func codeCommentResponse(reasoning, content string) *llm.ChatResponse { Type: "function", Function: llm.FunctionCall{ Name: tool.CodeComment.Name(), - Arguments: `{"comments":[{"content":"issue","existing_code":"x","path":"file.go"}]}`, + Arguments: `{"comments":[{"content":"issue","existing_code":"x"}]}`, }, }}, }}}, @@ -281,8 +281,8 @@ func TestExecuteToolCall_CodeCommentThinkingBackfill(t *testing.T) { Function: llm.FunctionCall{ Name: tool.CodeComment.Name(), Arguments: `{"comments":[` + - `{"content":"a","existing_code":"x","path":"file.go"},` + - `{"content":"b","existing_code":"y","thinking":"explicit","path":"file.go"}]}`, + `{"content":"a","existing_code":"x"},` + + `{"content":"b","existing_code":"y","thinking":"explicit"}]}`, }, }, nil, "turn reasoning") @@ -314,7 +314,7 @@ func TestExecuteToolCall_CodeCommentNoReasoning(t *testing.T) { cp := r.executeToolCall(context.Background(), "file.go", llm.ToolCall{ Function: llm.FunctionCall{ Name: tool.CodeComment.Name(), - Arguments: `{"comments":[{"content":"a","existing_code":"x","path":"file.go"}]}`, + Arguments: `{"comments":[{"content":"a","existing_code":"x"}]}`, }, }, nil, "")