mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-03 20:20:22 +00:00
fix(agents): harden host-managed claude-cli auth path (#61276)
This commit is contained in:
74
src/plugins/provider-auth-choice-helpers.test.ts
Normal file
74
src/plugins/provider-auth-choice-helpers.test.ts
Normal file
@@ -0,0 +1,74 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { applyProviderAuthConfigPatch } from "./provider-auth-choice-helpers.js";
|
||||
|
||||
describe("applyProviderAuthConfigPatch", () => {
|
||||
it("replaces patched default model maps instead of recursively merging them", () => {
|
||||
const base = {
|
||||
agents: {
|
||||
defaults: {
|
||||
model: {
|
||||
primary: "anthropic/claude-sonnet-4-6",
|
||||
fallbacks: ["anthropic/claude-opus-4-6", "openai/gpt-5.2"],
|
||||
},
|
||||
models: {
|
||||
"anthropic/claude-sonnet-4-6": { alias: "Sonnet" },
|
||||
"anthropic/claude-opus-4-6": { alias: "Opus" },
|
||||
"openai/gpt-5.2": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const patch = {
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"claude-cli/claude-sonnet-4-6": { alias: "Sonnet" },
|
||||
"claude-cli/claude-opus-4-6": { alias: "Opus" },
|
||||
"openai/gpt-5.2": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const next = applyProviderAuthConfigPatch(base, patch);
|
||||
|
||||
expect(next.agents?.defaults?.models).toEqual(patch.agents.defaults.models);
|
||||
expect(next.agents?.defaults?.model).toEqual(base.agents?.defaults?.model);
|
||||
});
|
||||
|
||||
it("keeps normal recursive merges for unrelated provider auth patch fields", () => {
|
||||
const base = {
|
||||
agents: {
|
||||
defaults: {
|
||||
contextPruning: {
|
||||
mode: "cache-ttl",
|
||||
ttl: "30m",
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies OpenClawConfig;
|
||||
const patch = {
|
||||
agents: {
|
||||
defaults: {
|
||||
contextPruning: {
|
||||
ttl: "1h",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const next = applyProviderAuthConfigPatch(base, patch);
|
||||
|
||||
expect(next).toEqual({
|
||||
agents: {
|
||||
defaults: {
|
||||
contextPruning: {
|
||||
mode: "cache-ttl",
|
||||
ttl: "1h",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -58,6 +58,33 @@ export function mergeConfigPatch<T>(base: T, patch: unknown): T {
|
||||
return next as T;
|
||||
}
|
||||
|
||||
export function applyProviderAuthConfigPatch(cfg: OpenClawConfig, patch: unknown): OpenClawConfig {
|
||||
const merged = mergeConfigPatch(cfg, patch);
|
||||
if (!isPlainRecord(patch)) {
|
||||
return merged;
|
||||
}
|
||||
|
||||
const patchModels = (patch.agents as { defaults?: { models?: unknown } } | undefined)?.defaults
|
||||
?.models;
|
||||
if (!isPlainRecord(patchModels)) {
|
||||
return merged;
|
||||
}
|
||||
|
||||
return {
|
||||
...merged,
|
||||
agents: {
|
||||
...merged.agents,
|
||||
defaults: {
|
||||
...merged.agents?.defaults,
|
||||
// Provider auth migrations can intentionally replace the exact allowlist.
|
||||
models: patchModels as NonNullable<
|
||||
NonNullable<OpenClawConfig["agents"]>["defaults"]
|
||||
>["models"],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function applyDefaultModel(cfg: OpenClawConfig, model: string): OpenClawConfig {
|
||||
const models = { ...cfg.agents?.defaults?.models };
|
||||
models[model] = models[model] ?? {};
|
||||
|
||||
@@ -11,8 +11,8 @@ import type { RuntimeEnv } from "../runtime.js";
|
||||
import type { WizardPrompter } from "../wizard/prompts.js";
|
||||
import { enablePluginInConfig } from "./enable.js";
|
||||
import {
|
||||
applyProviderAuthConfigPatch,
|
||||
applyDefaultModel,
|
||||
mergeConfigPatch,
|
||||
pickAuthMethod,
|
||||
resolveProviderMatch,
|
||||
} from "./provider-auth-choice-helpers.js";
|
||||
@@ -129,7 +129,7 @@ export async function runProviderPluginAuthMethod(params: {
|
||||
|
||||
let nextConfig = params.config;
|
||||
if (result.configPatch) {
|
||||
nextConfig = mergeConfigPatch(nextConfig, result.configPatch);
|
||||
nextConfig = applyProviderAuthConfigPatch(nextConfig, result.configPatch);
|
||||
}
|
||||
|
||||
for (const profile of result.profiles) {
|
||||
|
||||
Reference in New Issue
Block a user