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 5f063ed7..64741ba4 100644 --- a/internal/providers/qoder/direct.go +++ b/internal/providers/qoder/direct.go @@ -337,6 +337,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]) + } +}