





















@@ -116,6 +116,107 @@ describe("deepseek provider plugin", () => {
116116});
117117});
118118119+it("preserves replayed reasoning_content when DeepSeek V4 thinking is enabled", async () => {
120+let capturedPayload: Record<string, unknown> | undefined;
121+const model = {
122+provider: "deepseek",
123+id: "deepseek-v4-flash",
124+name: "DeepSeek V4 Flash",
125+api: "openai-completions",
126+baseUrl: "https://api.deepseek.com",
127+reasoning: true,
128+input: ["text"],
129+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
130+contextWindow: 1_000_000,
131+maxTokens: 384_000,
132+compat: {
133+supportsUsageInStreaming: true,
134+supportsReasoningEffort: true,
135+maxTokensField: "max_tokens",
136+},
137+} as Model<"openai-completions">;
138+const context = {
139+messages: [
140+{ role: "user", content: "hi", timestamp: 1 },
141+{
142+role: "assistant",
143+api: "openai-completions",
144+provider: "deepseek",
145+model: "deepseek-v4-flash",
146+content: [
147+{
148+type: "thinking",
149+thinking: "call reasoning",
150+thinkingSignature: "reasoning_content",
151+},
152+{ type: "toolCall", id: "call_1", name: "read", arguments: {} },
153+],
154+usage: {
155+input: 0,
156+output: 0,
157+cacheRead: 0,
158+cacheWrite: 0,
159+totalTokens: 0,
160+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
161+},
162+stopReason: "toolUse",
163+timestamp: 2,
164+},
165+{
166+role: "toolResult",
167+toolCallId: "call_1",
168+toolName: "read",
169+content: [{ type: "text", text: "ok" }],
170+isError: false,
171+timestamp: 3,
172+},
173+],
174+tools: [
175+{
176+name: "read",
177+description: "Read data",
178+parameters: { type: "object", properties: {}, required: [], additionalProperties: false },
179+},
180+],
181+} as Context;
182+const baseStreamFn = (
183+streamModel: Model<"openai-completions">,
184+streamContext: Context,
185+options?: { onPayload?: (payload: unknown, model: unknown) => unknown },
186+) => {
187+capturedPayload = buildOpenAICompletionsParams(streamModel, streamContext, {
188+reasoning: "high",
189+} as never);
190+options?.onPayload?.(capturedPayload, streamModel);
191+const stream = createAssistantMessageEventStream();
192+queueMicrotask(() => stream.end());
193+return stream;
194+};
195+196+const wrapThinkingHigh = createDeepSeekV4ThinkingWrapper(baseStreamFn as never, "high");
197+expect(wrapThinkingHigh).toBeDefined();
198+wrapThinkingHigh?.(model, context, {});
199+200+expect(capturedPayload).toMatchObject({
201+thinking: { type: "enabled" },
202+reasoning_effort: "high",
203+});
204+expect((capturedPayload?.messages as Array<Record<string, unknown>>)[1]).toMatchObject({
205+role: "assistant",
206+reasoning_content: "call reasoning",
207+tool_calls: [
208+{
209+id: "call_1",
210+type: "function",
211+function: {
212+name: "read",
213+arguments: "{}",
214+},
215+},
216+],
217+});
218+});
219+119220it("strips replayed reasoning_content when DeepSeek V4 thinking is disabled", async () => {
120221let capturedPayload: Record<string, unknown> | undefined;
121222const model = {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。