Files
openclaw/extensions/openrouter/index.test.ts
Vincent Koc 791dbf4f9d fix(openrouter): heal stale provider base urls (#68574)
* fix(openrouter): heal stale provider base urls

* chore(changelog): fix openrouter baseurl entry placement

* fix(arcee): keep catalog config optional
2026-04-18 08:42:51 -07:00

123 lines
3.5 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { registerSingleProviderPlugin } from "../../test/helpers/plugins/plugin-registration.js";
import { expectPassthroughReplayPolicy } from "../../test/helpers/provider-replay-policy.ts";
import openrouterPlugin from "./index.js";
describe("openrouter provider hooks", () => {
it("owns passthrough-gemini replay policy for Gemini-backed models", async () => {
await expectPassthroughReplayPolicy({
plugin: openrouterPlugin,
providerId: "openrouter",
modelId: "gemini-2.5-pro",
sanitizeThoughtSignatures: true,
});
await expectPassthroughReplayPolicy({
plugin: openrouterPlugin,
providerId: "openrouter",
modelId: "openai/gpt-5.4",
});
});
it("owns native reasoning output mode", async () => {
const provider = await registerSingleProviderPlugin(openrouterPlugin);
expect(
provider.resolveReasoningOutputMode?.({
provider: "openrouter",
modelApi: "openai-completions",
modelId: "openai/gpt-5.4",
} as never),
).toBe("native");
});
it("canonicalizes stale OpenRouter /v1 config and runtime metadata", async () => {
const provider = await registerSingleProviderPlugin(openrouterPlugin);
expect(
provider.normalizeConfig?.({
provider: "openrouter",
providerConfig: {
api: "openai-completions",
baseUrl: "https://openrouter.ai/v1/",
models: [],
},
} as never),
).toMatchObject({
baseUrl: "https://openrouter.ai/api/v1",
});
expect(
provider.normalizeResolvedModel?.({
provider: "openrouter",
model: {
provider: "openrouter",
id: "openai/gpt-5.4",
name: "openai/gpt-5.4",
api: "openai-completions",
baseUrl: "https://openrouter.ai/v1",
reasoning: true,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 200_000,
maxTokens: 8192,
},
} as never),
).toMatchObject({
baseUrl: "https://openrouter.ai/api/v1",
});
expect(
provider.normalizeTransport?.({
provider: "openrouter",
api: "openai-completions",
baseUrl: "https://openrouter.ai/v1",
} as never),
).toEqual({
api: "openai-completions",
baseUrl: "https://openrouter.ai/api/v1",
});
});
it("injects provider routing into compat before applying stream wrappers", async () => {
const provider = await registerSingleProviderPlugin(openrouterPlugin);
const baseStreamFn = vi.fn(
(..._args: Parameters<import("@mariozechner/pi-agent-core").StreamFn>) =>
({ async *[Symbol.asyncIterator]() {} }) as never,
);
const wrapped = provider.wrapStreamFn?.({
provider: "openrouter",
modelId: "openai/gpt-5.4",
extraParams: {
provider: {
order: ["moonshot"],
},
},
streamFn: baseStreamFn,
thinkingLevel: "high",
} as never);
void wrapped?.(
{
provider: "openrouter",
api: "openai-completions",
id: "openai/gpt-5.4",
compat: {},
} as never,
{ messages: [] } as never,
{},
);
expect(baseStreamFn).toHaveBeenCalledOnce();
const firstCall = baseStreamFn.mock.calls[0];
const firstModel = firstCall?.[0];
expect(firstModel).toMatchObject({
compat: {
openRouterRouting: {
order: ["moonshot"],
},
},
});
});
});