From 017f05b0a34b7464f179277ec9396578dc80a132 Mon Sep 17 00:00:00 2001 From: caigee-cmd <210803857+caigee-cmd@users.noreply.github.com> Date: Wed, 21 Oct 2026 16:25:01 +0800 Subject: [PATCH] fix(qoder): keep historical reasoning_content in rebuilt chat body --- .../qoder-history-reasoning-content.md | 7 +++++ internal/providers/qoder/direct.go | 3 +++ .../providers/qoder/history_reasoning_test.go | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 changelog/unreleased/qoder-history-reasoning-content.md create mode 100644 internal/providers/qoder/history_reasoning_test.go diff --git a/changelog/unreleased/qoder-history-reasoning-content.md b/changelog/unreleased/qoder-history-reasoning-content.md new file mode 100644 index 00000000..0d2ad198 --- /dev/null +++ b/changelog/unreleased/qoder-history-reasoning-content.md @@ -0,0 +1,7 @@ +### English + +- Qoder requests now keep the `reasoning_content` of earlier assistant messages instead of silently dropping it. + +### 中文 + +- Qoder 请求现在会保留历史 assistant 消息中的 `reasoning_content`,不再静默丢弃。 diff --git a/internal/providers/qoder/direct.go b/internal/providers/qoder/direct.go index 173e63dc..ac97c602 100644 --- a/internal/providers/qoder/direct.go +++ b/internal/providers/qoder/direct.go @@ -335,6 +335,9 @@ func BuildPlainChatBody(req translate.ChatRequest, now time.Time) map[string]any if message.ToolCallID != "" { item["tool_call_id"] = message.ToolCallID } + if message.ReasoningContent != "" { + item["reasoning_content"] = message.ReasoningContent + } if len(message.ToolCalls) > 0 { item["tool_calls"] = json.RawMessage(message.ToolCalls) } diff --git a/internal/providers/qoder/history_reasoning_test.go b/internal/providers/qoder/history_reasoning_test.go new file mode 100644 index 00000000..79d6a632 --- /dev/null +++ b/internal/providers/qoder/history_reasoning_test.go @@ -0,0 +1,26 @@ +package qoder + +import ( + "testing" + "time" + + "github.com/caigee-cmd/cli2api/internal/translate" +) + +// Regression for #330: client-supplied historical reasoning must survive the +// plaintext body rebuild. +func TestBuildPlainChatBodyKeepsHistoricalReasoning(t *testing.T) { + req := translate.ChatRequest{Model: "dfmodel", Messages: []translate.ChatMessage{ + {Role: "user", Content: "Use the synthetic snapshot."}, + {Role: "assistant", Content: "Snapshot checked.", ReasoningContent: "Synthetic marker: M1"}, + {Role: "user", Content: "Continue."}, + }} + body := BuildPlainChatBody(req, time.Unix(1, 0)) + messages := body["messages"].([]map[string]any) + if got := messages[1]["reasoning_content"]; got != "Synthetic marker: M1" { + t.Fatalf("historical reasoning lost: got %#v", got) + } + if _, ok := messages[0]["reasoning_content"]; ok { + t.Fatalf("empty reasoning_content should be omitted: %#v", messages[0]) + } +}