




















@@ -3,7 +3,10 @@ import { registerSingleProviderPlugin } from "../../test/helpers/plugins/plugin-
33import { registerProviderPlugin } from "../../test/helpers/plugins/provider-registration.js";
44import { expectPassthroughReplayPolicy } from "../../test/helpers/provider-replay-policy.ts";
55import openrouterPlugin from "./index.js";
6-import { buildOpenrouterProvider } from "./provider-catalog.js";
6+import {
7+buildOpenrouterProvider,
8+isOpenRouterProxyReasoningUnsupportedModel,
9+} from "./provider-catalog.js";
710811describe("openrouter provider hooks", () => {
912it("registers OpenRouter speech alongside model and media providers", async () => {
@@ -26,6 +29,18 @@ describe("openrouter provider hooks", () => {
2629);
2730});
283132+it("does not include retired stealth models in the bundled catalog", () => {
33+expect(buildOpenrouterProvider().models?.map((model) => model.id)).not.toEqual(
34+expect.arrayContaining(["openrouter/hunter-alpha", "openrouter/healer-alpha"]),
35+);
36+});
37+38+it("keeps stale Hunter Alpha configs out of OpenRouter proxy reasoning", () => {
39+expect(isOpenRouterProxyReasoningUnsupportedModel("openrouter/hunter-alpha")).toBe(true);
40+expect(isOpenRouterProxyReasoningUnsupportedModel("openrouter/hunter-alpha:free")).toBe(true);
41+expect(isOpenRouterProxyReasoningUnsupportedModel("openrouter/healer-alpha")).toBe(false);
42+});
43+2944it("owns passthrough-gemini replay policy for Gemini-backed models", async () => {
3045await expectPassthroughReplayPolicy({
3146plugin: openrouterPlugin,
@@ -88,6 +103,26 @@ describe("openrouter provider hooks", () => {
88103baseUrl: "https://openrouter.ai/api/v1",
89104});
90105106+expect(
107+provider.normalizeResolvedModel?.({
108+provider: "openrouter",
109+model: {
110+provider: "openrouter",
111+id: "openrouter/hunter-alpha",
112+name: "Hunter Alpha",
113+api: "openai-completions",
114+baseUrl: "https://openrouter.ai/api/v1",
115+reasoning: true,
116+input: ["text"],
117+cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
118+contextWindow: 1_048_576,
119+maxTokens: 65_536,
120+},
121+} as never),
122+).toMatchObject({
123+reasoning: false,
124+});
125+91126expect(
92127provider.normalizeTransport?.({
93128provider: "openrouter",
@@ -141,4 +176,43 @@ describe("openrouter provider hooks", () => {
141176},
142177});
143178});
179+180+it("does not inject OpenRouter reasoning for Hunter Alpha", async () => {
181+const provider = await registerSingleProviderPlugin(openrouterPlugin);
182+let capturedPayload: Record<string, unknown> | undefined;
183+const baseStreamFn = vi.fn(
184+(
185+ ...args: Parameters<import("@mariozechner/pi-agent-core").StreamFn>
186+): ReturnType<import("@mariozechner/pi-agent-core").StreamFn> => {
187+void args[2]?.onPayload?.({}, args[0]);
188+return { async *[Symbol.asyncIterator]() {} } as never;
189+},
190+);
191+192+const wrapped = provider.wrapStreamFn?.({
193+provider: "openrouter",
194+modelId: "openrouter/hunter-alpha",
195+streamFn: baseStreamFn,
196+thinkingLevel: "high",
197+} as never);
198+199+void wrapped?.(
200+{
201+provider: "openrouter",
202+api: "openai-completions",
203+id: "openrouter/hunter-alpha",
204+compat: {},
205+} as never,
206+{ messages: [] } as never,
207+{
208+onPayload: (payload: unknown) => {
209+capturedPayload = payload as Record<string, unknown>;
210+return payload;
211+},
212+} as never,
213+);
214+215+expect(capturedPayload).toEqual({});
216+expect(baseStreamFn).toHaveBeenCalledOnce();
217+});
144218});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。