mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-21 22:21:33 +00:00
153 lines
4.2 KiB
TypeScript
153 lines
4.2 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
mergeProviderModels,
|
|
mergeProviders,
|
|
mergeWithExistingProviderSecrets,
|
|
type ExistingProviderConfig,
|
|
} from "./models-config.merge.js";
|
|
import type { ProviderConfig } from "./models-config.providers.js";
|
|
|
|
describe("models-config merge helpers", () => {
|
|
const preservedApiKey = "AGENT_KEY"; // pragma: allowlist secret
|
|
|
|
it("refreshes implicit model metadata while preserving explicit reasoning overrides", () => {
|
|
const merged = mergeProviderModels(
|
|
{
|
|
api: "openai-responses",
|
|
models: [
|
|
{
|
|
id: "gpt-5.4",
|
|
name: "GPT-5.4",
|
|
input: ["text"],
|
|
reasoning: true,
|
|
contextWindow: 1_000_000,
|
|
maxTokens: 100_000,
|
|
},
|
|
],
|
|
} as ProviderConfig,
|
|
{
|
|
api: "openai-responses",
|
|
models: [
|
|
{
|
|
id: "gpt-5.4",
|
|
name: "GPT-5.4",
|
|
input: ["image"],
|
|
reasoning: false,
|
|
contextWindow: 2_000_000,
|
|
maxTokens: 200_000,
|
|
},
|
|
],
|
|
} as ProviderConfig,
|
|
);
|
|
|
|
expect(merged.models).toEqual([
|
|
expect.objectContaining({
|
|
id: "gpt-5.4",
|
|
input: ["text"],
|
|
reasoning: false,
|
|
contextWindow: 2_000_000,
|
|
maxTokens: 200_000,
|
|
}),
|
|
]);
|
|
});
|
|
|
|
it("merges explicit providers onto trimmed keys", () => {
|
|
const merged = mergeProviders({
|
|
explicit: {
|
|
" custom ": {
|
|
api: "openai-responses",
|
|
models: [] as ProviderConfig["models"],
|
|
} as ProviderConfig,
|
|
},
|
|
});
|
|
|
|
expect(merged).toEqual({
|
|
custom: expect.objectContaining({ api: "openai-responses" }),
|
|
});
|
|
});
|
|
|
|
it("preserves implicit provider headers when explicit config adds extra headers", () => {
|
|
const merged = mergeProviderModels(
|
|
{
|
|
baseUrl: "https://api.example.com",
|
|
api: "anthropic-messages",
|
|
headers: { "User-Agent": "claude-code/0.1.0" },
|
|
models: [
|
|
{
|
|
id: "kimi-code",
|
|
name: "Kimi Code",
|
|
input: ["text", "image"],
|
|
reasoning: true,
|
|
},
|
|
],
|
|
} as unknown as ProviderConfig,
|
|
{
|
|
baseUrl: "https://api.example.com",
|
|
api: "anthropic-messages",
|
|
headers: { "X-Kimi-Tenant": "tenant-a" },
|
|
models: [
|
|
{
|
|
id: "kimi-code",
|
|
name: "Kimi Code",
|
|
input: ["text", "image"],
|
|
reasoning: true,
|
|
},
|
|
],
|
|
} as unknown as ProviderConfig,
|
|
);
|
|
|
|
expect(merged.headers).toEqual({
|
|
"User-Agent": "claude-code/0.1.0",
|
|
"X-Kimi-Tenant": "tenant-a",
|
|
});
|
|
});
|
|
|
|
it("replaces stale baseUrl when model api surface changes", () => {
|
|
const merged = mergeWithExistingProviderSecrets({
|
|
nextProviders: {
|
|
custom: {
|
|
baseUrl: "https://config.example/v1",
|
|
models: [{ id: "model", api: "openai-responses" }],
|
|
} as ProviderConfig,
|
|
},
|
|
existingProviders: {
|
|
custom: {
|
|
baseUrl: "https://agent.example/v1",
|
|
apiKey: preservedApiKey,
|
|
models: [{ id: "model", api: "openai-completions" }],
|
|
} as ExistingProviderConfig,
|
|
},
|
|
secretRefManagedProviders: new Set<string>(),
|
|
explicitBaseUrlProviders: new Set<string>(),
|
|
});
|
|
|
|
expect(merged.custom).toEqual(
|
|
expect.objectContaining({
|
|
apiKey: preservedApiKey,
|
|
baseUrl: "https://config.example/v1",
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("does not preserve stale plaintext apiKey when next entry is a marker", () => {
|
|
const merged = mergeWithExistingProviderSecrets({
|
|
nextProviders: {
|
|
custom: {
|
|
apiKey: "OPENAI_API_KEY", // pragma: allowlist secret
|
|
models: [{ id: "model", api: "openai-responses" }],
|
|
} as ProviderConfig,
|
|
},
|
|
existingProviders: {
|
|
custom: {
|
|
apiKey: preservedApiKey,
|
|
models: [{ id: "model", api: "openai-responses" }],
|
|
} as ExistingProviderConfig,
|
|
},
|
|
secretRefManagedProviders: new Set<string>(),
|
|
explicitBaseUrlProviders: new Set<string>(),
|
|
});
|
|
|
|
expect(merged.custom?.apiKey).toBe("OPENAI_API_KEY"); // pragma: allowlist secret
|
|
});
|
|
});
|