mirror of https://github.com/openclaw/openclaw.git
141 lines
3.9 KiB
TypeScript
141 lines
3.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { OpenClawConfig } from "../config/config.js";
|
|
import type { ModelProviderConfig } from "../config/types.models.js";
|
|
import {
|
|
buildPairedProviderApiKeyCatalog,
|
|
buildSingleProviderApiKeyCatalog,
|
|
findCatalogTemplate,
|
|
} from "./provider-catalog.js";
|
|
import type { ProviderCatalogContext } from "./types.js";
|
|
|
|
function createProviderConfig(overrides: Partial<ModelProviderConfig> = {}): ModelProviderConfig {
|
|
return {
|
|
api: "openai-completions",
|
|
baseUrl: "https://default.example/v1",
|
|
models: [],
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function createCatalogContext(params: {
|
|
config?: OpenClawConfig;
|
|
apiKeys?: Record<string, string | undefined>;
|
|
}): ProviderCatalogContext {
|
|
return {
|
|
config: params.config ?? {},
|
|
env: {},
|
|
resolveProviderApiKey: (providerId) => ({
|
|
apiKey: providerId ? params.apiKeys?.[providerId] : undefined,
|
|
}),
|
|
resolveProviderAuth: (providerId) => ({
|
|
apiKey: providerId ? params.apiKeys?.[providerId] : undefined,
|
|
mode: providerId && params.apiKeys?.[providerId] ? "api_key" : "none",
|
|
source: providerId && params.apiKeys?.[providerId] ? "env" : "none",
|
|
}),
|
|
};
|
|
}
|
|
|
|
describe("buildSingleProviderApiKeyCatalog", () => {
|
|
it("matches provider templates case-insensitively", () => {
|
|
const result = findCatalogTemplate({
|
|
entries: [
|
|
{ provider: "OpenAI", id: "gpt-5.2" },
|
|
{ provider: "other", id: "fallback" },
|
|
],
|
|
providerId: "openai",
|
|
templateIds: ["missing", "GPT-5.2"],
|
|
});
|
|
|
|
expect(result).toEqual({ provider: "OpenAI", id: "gpt-5.2" });
|
|
});
|
|
|
|
it("returns null when api key is missing", async () => {
|
|
const result = await buildSingleProviderApiKeyCatalog({
|
|
ctx: createCatalogContext({}),
|
|
providerId: "test-provider",
|
|
buildProvider: () => createProviderConfig(),
|
|
});
|
|
|
|
expect(result).toBeNull();
|
|
});
|
|
|
|
it("adds api key to the built provider", async () => {
|
|
const result = await buildSingleProviderApiKeyCatalog({
|
|
ctx: createCatalogContext({
|
|
apiKeys: { "test-provider": "secret-key" },
|
|
}),
|
|
providerId: "test-provider",
|
|
buildProvider: async () => createProviderConfig(),
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
provider: {
|
|
api: "openai-completions",
|
|
baseUrl: "https://default.example/v1",
|
|
models: [],
|
|
apiKey: "secret-key",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("prefers explicit base url when allowed", async () => {
|
|
const result = await buildSingleProviderApiKeyCatalog({
|
|
ctx: createCatalogContext({
|
|
apiKeys: { "test-provider": "secret-key" },
|
|
config: {
|
|
models: {
|
|
providers: {
|
|
"test-provider": {
|
|
baseUrl: " https://override.example/v1/ ",
|
|
models: [],
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
providerId: "test-provider",
|
|
buildProvider: () => createProviderConfig(),
|
|
allowExplicitBaseUrl: true,
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
provider: {
|
|
api: "openai-completions",
|
|
baseUrl: "https://override.example/v1/",
|
|
models: [],
|
|
apiKey: "secret-key",
|
|
},
|
|
});
|
|
});
|
|
|
|
it("adds api key to each paired provider", async () => {
|
|
const result = await buildPairedProviderApiKeyCatalog({
|
|
ctx: createCatalogContext({
|
|
apiKeys: { "test-provider": "secret-key" },
|
|
}),
|
|
providerId: "test-provider",
|
|
buildProviders: async () => ({
|
|
alpha: createProviderConfig(),
|
|
beta: createProviderConfig(),
|
|
}),
|
|
});
|
|
|
|
expect(result).toEqual({
|
|
providers: {
|
|
alpha: {
|
|
api: "openai-completions",
|
|
baseUrl: "https://default.example/v1",
|
|
models: [],
|
|
apiKey: "secret-key",
|
|
},
|
|
beta: {
|
|
api: "openai-completions",
|
|
baseUrl: "https://default.example/v1",
|
|
models: [],
|
|
apiKey: "secret-key",
|
|
},
|
|
},
|
|
});
|
|
});
|
|
});
|