test: add comprehensive tests for OpenRouter routing configuration and validation
This commit is contained in:
parent
56ccee35a0
commit
f62291a0eb
117
src/agents/models-config.openrouter-routing.test.ts
Normal file
117
src/agents/models-config.openrouter-routing.test.ts
Normal file
@ -0,0 +1,117 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { MoltbotConfig } from "../config/config.js";
|
||||
|
||||
describe("OpenRouter routing", () => {
|
||||
it("config accepts openRouterRouting with 'only' field", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
env: {
|
||||
OPENROUTER_API_KEY: "sk-or-test-key",
|
||||
},
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/anthropic/claude-sonnet-4-5" },
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-5": {
|
||||
alias: "Claude Sonnet",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
only: ["anthropic"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const modelKey = "openrouter/anthropic/claude-sonnet-4-5";
|
||||
const modelConfig = cfg.agents?.defaults?.models?.[modelKey];
|
||||
|
||||
expect(modelConfig?.compat?.openRouterRouting).toEqual({
|
||||
only: ["anthropic"],
|
||||
});
|
||||
});
|
||||
|
||||
it("config accepts openRouterRouting with 'order' field", () => {
|
||||
const cfg: MoltbotConfig = {
|
||||
env: {
|
||||
OPENROUTER_API_KEY: "sk-or-test-key",
|
||||
},
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/openai/gpt-5.2" },
|
||||
models: {
|
||||
"openrouter/openai/gpt-5.2": {
|
||||
alias: "GPT-5.2",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
order: ["anthropic", "openai"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const modelKey = "openrouter/openai/gpt-5.2";
|
||||
const modelConfig = cfg.agents?.defaults?.models?.[modelKey];
|
||||
|
||||
expect(modelConfig?.compat?.openRouterRouting).toEqual({
|
||||
order: ["anthropic", "openai"],
|
||||
});
|
||||
});
|
||||
|
||||
it("validates openRouterRouting config shape", () => {
|
||||
const testCases = [
|
||||
{
|
||||
name: "only with single provider",
|
||||
config: { only: ["anthropic"] },
|
||||
},
|
||||
{
|
||||
name: "only with multiple providers",
|
||||
config: { only: ["anthropic", "openai"] },
|
||||
},
|
||||
{
|
||||
name: "order with single provider",
|
||||
config: { order: ["anthropic"] },
|
||||
},
|
||||
{
|
||||
name: "order with multiple providers",
|
||||
config: { order: ["anthropic", "openai"] },
|
||||
},
|
||||
{
|
||||
name: "empty routing",
|
||||
config: {},
|
||||
},
|
||||
{
|
||||
name: "both only and order",
|
||||
config: { only: ["anthropic"], order: ["openai"] },
|
||||
},
|
||||
];
|
||||
|
||||
for (const testCase of testCases) {
|
||||
const cfg: MoltbotConfig = {
|
||||
env: { OPENROUTER_API_KEY: "sk-or-test-key" },
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/anthropic/claude-sonnet-4-5" },
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-5": {
|
||||
compat: {
|
||||
openRouterRouting: testCase.config,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(() => {
|
||||
const modelConfig =
|
||||
cfg.agents?.defaults?.models?.["openrouter/anthropic/claude-sonnet-4-5"];
|
||||
expect(modelConfig?.compat?.openRouterRouting).toEqual(testCase.config);
|
||||
}).not.toThrow();
|
||||
}
|
||||
});
|
||||
});
|
||||
42
src/config/openrouter-routing-example.test.ts
Normal file
42
src/config/openrouter-routing-example.test.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { expect, it } from "vitest";
|
||||
|
||||
it("example: openRouterRouting configuration", () => {
|
||||
const config = {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/anthropic/claude-sonnet-4-5" },
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-5": {
|
||||
alias: "Claude Sonnet",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
only: ["anthropic"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"openrouter/openai/gpt-5.2": {
|
||||
alias: "GPT-5.2",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
order: ["anthropic", "openai"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
config.agents.defaults.models?.["openrouter/anthropic/claude-sonnet-4-5"]?.compat
|
||||
?.openRouterRouting,
|
||||
).toEqual({
|
||||
only: ["anthropic"],
|
||||
});
|
||||
|
||||
expect(
|
||||
config.agents.defaults.models?.["openrouter/openai/gpt-5.2"]?.compat?.openRouterRouting,
|
||||
).toEqual({
|
||||
order: ["anthropic", "openai"],
|
||||
});
|
||||
});
|
||||
98
src/config/zod-schema.openrouter-routing.test.ts
Normal file
98
src/config/zod-schema.openrouter-routing.test.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { withTempHome } from "./test-helpers.js";
|
||||
|
||||
describe("OpenRouter routing integration", () => {
|
||||
it("validates and loads openRouterRouting config from moltbot.json", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const configDir = path.join(home, ".clawdbot");
|
||||
await fs.mkdir(configDir, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(configDir, "moltbot.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/anthropic/claude-sonnet-4-5" },
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-5": {
|
||||
alias: "Claude Sonnet",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
only: ["anthropic"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"openrouter/openai/gpt-5.2": {
|
||||
alias: "GPT-5.2",
|
||||
compat: {
|
||||
openRouterRouting: {
|
||||
order: ["anthropic", "openai"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const { loadConfig } = await import("./config.js");
|
||||
const cfg = loadConfig();
|
||||
|
||||
expect(cfg.agents?.defaults?.model?.primary).toBe("openrouter/anthropic/claude-sonnet-4-5");
|
||||
|
||||
const sonnetModel = cfg.agents?.defaults?.models?.["openrouter/anthropic/claude-sonnet-4-5"];
|
||||
expect(sonnetModel?.alias).toBe("Claude Sonnet");
|
||||
expect(sonnetModel?.compat?.openRouterRouting).toEqual({
|
||||
only: ["anthropic"],
|
||||
});
|
||||
|
||||
const gptModel = cfg.agents?.defaults?.models?.["openrouter/openai/gpt-5.2"];
|
||||
expect(gptModel?.alias).toBe("GPT-5.2");
|
||||
expect(gptModel?.compat?.openRouterRouting).toEqual({
|
||||
order: ["anthropic", "openai"],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("accepts openRouterRouting with empty config", async () => {
|
||||
await withTempHome(async (home) => {
|
||||
const configDir = path.join(home, ".clawdbot");
|
||||
await fs.mkdir(configDir, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(configDir, "moltbot.json"),
|
||||
JSON.stringify(
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "openrouter/anthropic/claude-sonnet-4-5" },
|
||||
models: {
|
||||
"openrouter/anthropic/claude-sonnet-4-5": {
|
||||
compat: {
|
||||
openRouterRouting: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const { loadConfig } = await import("./config.js");
|
||||
const cfg = loadConfig();
|
||||
|
||||
const model = cfg.agents?.defaults?.models?.["openrouter/anthropic/claude-sonnet-4-5"];
|
||||
expect(model?.compat?.openRouterRouting).toEqual({});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user