


























@@ -5413,3 +5413,71 @@ describe("openai transport stream", () => {
54135413).rejects.toThrow("Exceeded tool-call argument buffer limit");
54145414});
54155415});
5416+5417+describe("buildOpenAICompletionsParams strips response-only reasoning fields", () => {
5418+// OpenRouter and other OpenAI-Completions providers echo `reasoning_details`
5419+// (array) and `reasoning_content` (string) in response choices to expose the
5420+// model's chain of thought. If those fields leak back into a follow-up
5421+// request, OpenRouter rejects the call with HTTP 500 ("Internal Server
5422+// Error"). buildOpenAICompletionsParams must scrub them before the wire.
5423+// Repro recipe (verified against live OpenRouter):
5424+// POST /chat/completions with messages[*].reasoning_details: "..." => 500
5425+// Same body without that key => 200
5426+5427+const baseModel = {
5428+id: "deepseek/deepseek-v4-flash",
5429+name: "DeepSeek v4 Flash",
5430+api: "openai-completions",
5431+provider: "openrouter",
5432+baseUrl: "https://openrouter.ai/api/v1",
5433+reasoning: true,
5434+input: ["text"],
5435+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
5436+contextWindow: 128_000,
5437+maxTokens: 8192,
5438+} satisfies Model<"openai-completions">;
5439+5440+function getAssistantMessage(params: { messages: unknown }) {
5441+expect(Array.isArray(params.messages)).toBe(true);
5442+const list = params.messages as Array<Record<string, unknown>>;
5443+const assistant = list.find((m) => m.role === "assistant");
5444+expect(assistant).toBeDefined();
5445+return assistant as Record<string, unknown>;
5446+}
5447+5448+it("removes reasoning_details, reasoning_content, and reasoning from assistant replay", () => {
5449+const params = buildOpenAICompletionsParams(
5450+baseModel,
5451+{
5452+systemPrompt: "system",
5453+messages: [
5454+{ role: "user", content: "你好" },
5455+{
5456+role: "assistant",
5457+provider: "openrouter",
5458+api: "openai-completions",
5459+model: "deepseek/deepseek-v4-flash",
5460+stopReason: "stop",
5461+timestamp: 0,
5462+content: [
5463+{
5464+type: "thinking",
5465+thinking: "User said hi, I should respond politely.",
5466+thinkingSignature: "considering",
5467+},
5468+{ type: "text", text: "Hello!" },
5469+],
5470+},
5471+{ role: "user", content: "再来一个" },
5472+],
5473+tools: [],
5474+} as never,
5475+undefined,
5476+) as { messages: unknown };
5477+5478+const assistant = getAssistantMessage(params);
5479+expect(assistant).not.toHaveProperty("reasoning_details");
5480+expect(assistant).not.toHaveProperty("reasoning_content");
5481+expect(assistant).not.toHaveProperty("reasoning");
5482+});
5483+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。