test: share models config merge helpers

This commit is contained in:
Peter Steinberger 2026-03-14 02:24:58 +00:00
parent 7aedb6d442
commit 8622395c8b
1 changed files with 98 additions and 97 deletions

View File

@ -60,13 +60,31 @@ function createMergeConfigProvider() {
};
}
async function runCustomProviderMergeTest(params: {
seedProvider: {
baseUrl: string;
apiKey: string;
api: string;
models: Array<{ id: string; name: string; input: string[]; api?: string }>;
type MergeSeedProvider = {
baseUrl: string;
apiKey: string;
api: string;
models: Array<{ id: string; name: string; input: string[]; api?: string }>;
};
type MergeConfigApiKeyRef = {
source: "env";
provider: "default";
id: string;
};
function createAgentSeedProvider(overrides: Partial<MergeSeedProvider> = {}): MergeSeedProvider {
return {
baseUrl: "https://agent.example/v1",
apiKey: "AGENT_KEY", // pragma: allowlist secret
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
...overrides,
};
}
async function runCustomProviderMergeTest(params: {
seedProvider: MergeSeedProvider;
existingProviderKey?: string;
configProviderKey?: string;
}) {
@ -86,6 +104,56 @@ async function runCustomProviderMergeTest(params: {
}>();
}
async function expectCustomProviderMergeResult(params: {
seedProvider?: MergeSeedProvider;
existingProviderKey?: string;
configProviderKey?: string;
expectedApiKey: string;
expectedBaseUrl: string;
}) {
await withTempHome(async () => {
const parsed = await runCustomProviderMergeTest({
seedProvider: params.seedProvider ?? createAgentSeedProvider(),
existingProviderKey: params.existingProviderKey,
configProviderKey: params.configProviderKey,
});
expect(parsed.providers.custom?.apiKey).toBe(params.expectedApiKey);
expect(parsed.providers.custom?.baseUrl).toBe(params.expectedBaseUrl);
});
}
async function expectCustomProviderApiKeyRewrite(params: {
existingApiKey: string;
configuredApiKey: string | MergeConfigApiKeyRef;
expectedApiKey: string;
}) {
await withTempHome(async () => {
await writeAgentModelsJson({
providers: {
custom: createAgentSeedProvider({ apiKey: params.existingApiKey }),
},
});
await ensureOpenClawModelsJson({
models: {
mode: "merge",
providers: {
custom: {
...createMergeConfigProvider(),
apiKey: params.configuredApiKey,
},
},
},
});
const parsed = await readGeneratedModelsJson<{
providers: Record<string, { apiKey?: string; baseUrl?: string }>;
}>();
expect(parsed.providers.custom?.apiKey).toBe(params.expectedApiKey);
expect(parsed.providers.custom?.baseUrl).toBe("https://config.example/v1");
});
}
function createMoonshotConfig(overrides: {
contextWindow: number;
maxTokens: number;
@ -301,49 +369,26 @@ describe("models-config", () => {
});
it("preserves non-empty agent apiKey but lets explicit config baseUrl win in merge mode", async () => {
await withTempHome(async () => {
const parsed = await runCustomProviderMergeTest({
seedProvider: {
baseUrl: "https://agent.example/v1",
apiKey: "AGENT_KEY", // pragma: allowlist secret
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
},
});
expect(parsed.providers.custom?.apiKey).toBe("AGENT_KEY");
expect(parsed.providers.custom?.baseUrl).toBe("https://config.example/v1");
await expectCustomProviderMergeResult({
expectedApiKey: "AGENT_KEY",
expectedBaseUrl: "https://config.example/v1",
});
});
it("lets explicit config baseUrl win in merge mode when the config provider key is normalized", async () => {
await withTempHome(async () => {
const parsed = await runCustomProviderMergeTest({
seedProvider: {
baseUrl: "https://agent.example/v1",
apiKey: "AGENT_KEY", // pragma: allowlist secret
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
},
existingProviderKey: "custom",
configProviderKey: " custom ",
});
expect(parsed.providers.custom?.apiKey).toBe("AGENT_KEY");
expect(parsed.providers.custom?.baseUrl).toBe("https://config.example/v1");
await expectCustomProviderMergeResult({
existingProviderKey: "custom",
configProviderKey: " custom ",
expectedApiKey: "AGENT_KEY",
expectedBaseUrl: "https://config.example/v1",
});
});
it("replaces stale merged baseUrl when the provider api changes", async () => {
await withTempHome(async () => {
const parsed = await runCustomProviderMergeTest({
seedProvider: {
baseUrl: "https://agent.example/v1",
apiKey: "AGENT_KEY", // pragma: allowlist secret
api: "openai-completions",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
},
});
expect(parsed.providers.custom?.apiKey).toBe("AGENT_KEY");
expect(parsed.providers.custom?.baseUrl).toBe("https://config.example/v1");
await expectCustomProviderMergeResult({
seedProvider: createAgentSeedProvider({ api: "openai-completions" }),
expectedApiKey: "AGENT_KEY",
expectedBaseUrl: "https://config.example/v1",
});
});
@ -370,34 +415,14 @@ describe("models-config", () => {
});
it("replaces stale merged apiKey when provider is SecretRef-managed in current config", async () => {
await withTempHome(async () => {
await writeAgentModelsJson({
providers: {
custom: {
baseUrl: "https://agent.example/v1",
apiKey: "STALE_AGENT_KEY", // pragma: allowlist secret
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
},
},
});
await ensureOpenClawModelsJson({
models: {
mode: "merge",
providers: {
custom: {
...createMergeConfigProvider(),
apiKey: { source: "env", provider: "default", id: "CUSTOM_PROVIDER_API_KEY" }, // pragma: allowlist secret
},
},
},
});
const parsed = await readGeneratedModelsJson<{
providers: Record<string, { apiKey?: string; baseUrl?: string }>;
}>();
expect(parsed.providers.custom?.apiKey).toBe("CUSTOM_PROVIDER_API_KEY"); // pragma: allowlist secret
expect(parsed.providers.custom?.baseUrl).toBe("https://config.example/v1");
await expectCustomProviderApiKeyRewrite({
existingApiKey: "STALE_AGENT_KEY", // pragma: allowlist secret
configuredApiKey: {
source: "env",
provider: "default",
id: "CUSTOM_PROVIDER_API_KEY", // pragma: allowlist secret
},
expectedApiKey: "CUSTOM_PROVIDER_API_KEY", // pragma: allowlist secret
});
});
@ -449,34 +474,10 @@ describe("models-config", () => {
});
it("replaces stale non-env marker when provider transitions back to plaintext config", async () => {
await withTempHome(async () => {
await writeAgentModelsJson({
providers: {
custom: {
baseUrl: "https://agent.example/v1",
apiKey: NON_ENV_SECRETREF_MARKER,
api: "openai-responses",
models: [{ id: "agent-model", name: "Agent model", input: ["text"] }],
},
},
});
await ensureOpenClawModelsJson({
models: {
mode: "merge",
providers: {
custom: {
...createMergeConfigProvider(),
apiKey: "ALLCAPS_SAMPLE", // pragma: allowlist secret
},
},
},
});
const parsed = await readGeneratedModelsJson<{
providers: Record<string, { apiKey?: string }>;
}>();
expect(parsed.providers.custom?.apiKey).toBe("ALLCAPS_SAMPLE");
await expectCustomProviderApiKeyRewrite({
existingApiKey: NON_ENV_SECRETREF_MARKER,
configuredApiKey: "ALLCAPS_SAMPLE", // pragma: allowlist secret
expectedApiKey: "ALLCAPS_SAMPLE", // pragma: allowlist secret
});
});