Files
Moltbot/src/agents/pi-embedded-runner/model.test.ts
2026-01-31 06:45:57 +01:00

131 lines
3.5 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
vi.mock("../pi-model-discovery.js", () => ({
discoverAuthStorage: vi.fn(() => ({ mocked: true })),
discoverModels: vi.fn(() => ({ find: vi.fn(() => null) })),
}));
import type { OpenClawConfig } from "../../config/config.js";
import { buildInlineProviderModels, resolveModel } from "./model.js";
const makeModel = (id: string) => ({
id,
name: id,
reasoning: false,
input: ["text"] as const,
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 1,
maxTokens: 1,
});
describe("buildInlineProviderModels", () => {
it("attaches provider ids to inline models", () => {
const providers = {
" alpha ": { baseUrl: "http://alpha.local", models: [makeModel("alpha-model")] },
beta: { baseUrl: "http://beta.local", models: [makeModel("beta-model")] },
};
const result = buildInlineProviderModels(providers);
expect(result).toEqual([
{
...makeModel("alpha-model"),
provider: "alpha",
baseUrl: "http://alpha.local",
api: undefined,
},
{
...makeModel("beta-model"),
provider: "beta",
baseUrl: "http://beta.local",
api: undefined,
},
]);
});
it("inherits baseUrl from provider when model does not specify it", () => {
const providers = {
custom: {
baseUrl: "http://localhost:8000",
models: [makeModel("custom-model")],
},
};
const result = buildInlineProviderModels(providers);
expect(result).toHaveLength(1);
expect(result[0].baseUrl).toBe("http://localhost:8000");
});
it("inherits api from provider when model does not specify it", () => {
const providers = {
custom: {
baseUrl: "http://localhost:8000",
api: "anthropic-messages",
models: [makeModel("custom-model")],
},
};
const result = buildInlineProviderModels(providers);
expect(result).toHaveLength(1);
expect(result[0].api).toBe("anthropic-messages");
});
it("model-level api takes precedence over provider-level api", () => {
const providers = {
custom: {
baseUrl: "http://localhost:8000",
api: "openai-responses",
models: [{ ...makeModel("custom-model"), api: "anthropic-messages" as const }],
},
};
const result = buildInlineProviderModels(providers);
expect(result).toHaveLength(1);
expect(result[0].api).toBe("anthropic-messages");
});
it("inherits both baseUrl and api from provider config", () => {
const providers = {
custom: {
baseUrl: "http://localhost:10000",
api: "anthropic-messages",
models: [makeModel("claude-opus-4.5")],
},
};
const result = buildInlineProviderModels(providers);
expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
provider: "custom",
baseUrl: "http://localhost:10000",
api: "anthropic-messages",
name: "claude-opus-4.5",
});
});
});
describe("resolveModel", () => {
it("includes provider baseUrl in fallback model", () => {
const cfg = {
models: {
providers: {
custom: {
baseUrl: "http://localhost:9000",
models: [],
},
},
},
} as OpenClawConfig;
const result = resolveModel("custom", "missing-model", "/tmp/agent", cfg);
expect(result.model?.baseUrl).toBe("http://localhost:9000");
expect(result.model?.provider).toBe("custom");
expect(result.model?.id).toBe("missing-model");
});
});