





















@@ -219,6 +219,127 @@ describe("openrouter provider hooks", () => {
219219expect(baseStreamFn).toHaveBeenCalledOnce();
220220});
221221222+it("fills DeepSeek V4 reasoning_content for OpenRouter replay turns", async () => {
223+const provider = await registerSingleProviderPlugin(openrouterPlugin);
224+let capturedPayload: Record<string, unknown> | undefined;
225+const baseStreamFn = vi.fn(
226+(
227+ ...args: Parameters<import("@mariozechner/pi-agent-core").StreamFn>
228+): ReturnType<import("@mariozechner/pi-agent-core").StreamFn> => {
229+const payload = {
230+messages: [
231+{ role: "user", content: "read file" },
232+{ role: "assistant", tool_calls: [{ id: "call_1", type: "function" }] },
233+{ role: "tool", content: "ok" },
234+{ role: "assistant", content: "done" },
235+],
236+};
237+void args[2]?.onPayload?.(payload, args[0]);
238+capturedPayload = payload;
239+return { async *[Symbol.asyncIterator]() {} } as never;
240+},
241+);
242+243+const wrapped = provider.wrapStreamFn?.({
244+provider: "openrouter",
245+modelId: "deepseek/deepseek-v4-flash",
246+streamFn: baseStreamFn,
247+thinkingLevel: "xhigh",
248+} as never);
249+250+void wrapped?.(
251+{
252+provider: "openrouter",
253+api: "openai-completions",
254+id: "deepseek/deepseek-v4-flash",
255+baseUrl: "https://openrouter.ai/api/v1",
256+compat: {},
257+} as never,
258+{ messages: [] } as never,
259+{},
260+);
261+262+expect(capturedPayload).toMatchObject({
263+thinking: { type: "enabled" },
264+reasoning_effort: "max",
265+messages: [
266+{ role: "user", content: "read file" },
267+{
268+role: "assistant",
269+tool_calls: [{ id: "call_1", type: "function" }],
270+reasoning_content: "",
271+},
272+{ role: "tool", content: "ok" },
273+{ role: "assistant", content: "done", reasoning_content: "" },
274+],
275+});
276+expect(baseStreamFn).toHaveBeenCalledOnce();
277+});
278+279+it("recognizes full OpenRouter DeepSeek V4 refs but skips custom proxy routes", async () => {
280+const provider = await registerSingleProviderPlugin(openrouterPlugin);
281+const payloads: Array<Record<string, unknown>> = [];
282+const baseStreamFn = vi.fn(
283+(
284+ ...args: Parameters<import("@mariozechner/pi-agent-core").StreamFn>
285+): ReturnType<import("@mariozechner/pi-agent-core").StreamFn> => {
286+const payload = {
287+messages: [{ role: "assistant", tool_calls: [{ id: "call_1", type: "function" }] }],
288+};
289+void args[2]?.onPayload?.(payload, args[0]);
290+payloads.push(payload);
291+return { async *[Symbol.asyncIterator]() {} } as never;
292+},
293+);
294+295+const fullRef = provider.wrapStreamFn?.({
296+provider: "openrouter",
297+modelId: "openrouter/deepseek/deepseek-v4-pro",
298+streamFn: baseStreamFn,
299+thinkingLevel: "high",
300+} as never);
301+void fullRef?.(
302+{
303+provider: "openrouter",
304+api: "openai-completions",
305+id: "openrouter/deepseek/deepseek-v4-pro",
306+baseUrl: "https://openrouter.ai/api/v1",
307+compat: {},
308+} as never,
309+{ messages: [] } as never,
310+{},
311+);
312+313+const customRoute = provider.wrapStreamFn?.({
314+provider: "openrouter",
315+modelId: "deepseek/deepseek-v4-pro",
316+streamFn: baseStreamFn,
317+thinkingLevel: "high",
318+} as never);
319+void customRoute?.(
320+{
321+provider: "openrouter",
322+api: "openai-completions",
323+id: "deepseek/deepseek-v4-pro",
324+baseUrl: "https://proxy.example.com/v1",
325+compat: {},
326+} as never,
327+{ messages: [] } as never,
328+{},
329+);
330+331+expect(payloads[0]?.messages).toEqual([
332+{
333+role: "assistant",
334+tool_calls: [{ id: "call_1", type: "function" }],
335+reasoning_content: "",
336+},
337+]);
338+expect(payloads[1]?.messages).toEqual([
339+{ role: "assistant", tool_calls: [{ id: "call_1", type: "function" }] },
340+]);
341+});
342+222343it("strips OpenRouter-routed Anthropic assistant prefill when reasoning is enabled", async () => {
223344const provider = await registerSingleProviderPlugin(openrouterPlugin);
224345let capturedPayload: Record<string, unknown> | undefined;
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。