Spaces:
Paused
Paused
| 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"); | |
| }); | |
| }); | |