mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 08:00:42 +00:00
fix(anthropic): scope api default normalization
This commit is contained in:
@@ -20,6 +20,7 @@ Docs: https://docs.openclaw.ai
|
||||
### Fixes
|
||||
|
||||
- Exec/YOLO: stop rejecting gateway-host exec in `security=full` plus `ask=off` mode via the Python/Node script preflight hardening path, so promptless YOLO exec once again runs direct interpreter stdin and heredoc forms such as `node <<'NODE' ... NODE`.
|
||||
- Anthropic/plugins: scope Anthropic `api: "anthropic-messages"` defaulting to Anthropic-owned providers, so `openai-codex` and other providers without an explicit `api` no longer get rewritten to the wrong transport. Fixes #64534.
|
||||
- fix(qqbot): add SSRF guard to direct-upload URL paths in uploadC2CMedia and uploadGroupMedia [AI-assisted]. (#69595) Thanks @pgondhi987.
|
||||
- fix(gateway): enforce allowRequestSessionKey gate on template-rendered mapping sessionKeys. (#69381) Thanks @pgondhi987.
|
||||
- Webchat/images: treat inline image attachments as media for empty-turn gating while still ignoring metadata-only blank turns. (#69474) Thanks @Jaswir.
|
||||
|
||||
@@ -159,6 +159,16 @@ export function normalizeAnthropicProviderConfig<T extends { api?: string; model
|
||||
return { ...providerConfig, api: ANTHROPIC_PROVIDER_API };
|
||||
}
|
||||
|
||||
export function normalizeAnthropicProviderConfigForProvider<
|
||||
T extends { api?: string; models?: unknown[] },
|
||||
>(params: { provider: string; providerConfig: T }): T {
|
||||
const provider = normalizeProviderId(params.provider);
|
||||
if (provider !== "anthropic" && provider !== CLAUDE_CLI_BACKEND_ID) {
|
||||
return params.providerConfig;
|
||||
}
|
||||
return normalizeAnthropicProviderConfig(params.providerConfig);
|
||||
}
|
||||
|
||||
export function applyAnthropicConfigDefaults(params: {
|
||||
config: OpenClawConfig;
|
||||
env: NodeJS.ProcessEnv;
|
||||
|
||||
@@ -100,6 +100,36 @@ describe("anthropic provider replay hooks", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("defaults Claude CLI provider api through plugin config normalization", async () => {
|
||||
const provider = await registerSingleProviderPlugin(anthropicPlugin);
|
||||
|
||||
expect(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "claude-cli",
|
||||
providerConfig: {
|
||||
models: [{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6" }],
|
||||
},
|
||||
} as never),
|
||||
).toMatchObject({
|
||||
api: "anthropic-messages",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not default non-Anthropic provider api through plugin config normalization", async () => {
|
||||
const provider = await registerSingleProviderPlugin(anthropicPlugin);
|
||||
const providerConfig = {
|
||||
baseUrl: "https://chatgpt.com/backend-api/codex",
|
||||
models: [{ id: "gpt-5.4", name: "GPT-5.4" }],
|
||||
};
|
||||
|
||||
expect(
|
||||
provider.normalizeConfig?.({
|
||||
provider: "openai-codex",
|
||||
providerConfig,
|
||||
} as never),
|
||||
).toBe(providerConfig);
|
||||
});
|
||||
|
||||
it("applies Anthropic pruning defaults through plugin hooks", async () => {
|
||||
const provider = await registerSingleProviderPlugin(anthropicPlugin);
|
||||
|
||||
|
||||
@@ -35,6 +35,34 @@ describe("anthropic provider policy public artifact", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("normalizes Claude CLI provider config", () => {
|
||||
expect(
|
||||
normalizeConfig({
|
||||
provider: "claude-cli",
|
||||
providerConfig: {
|
||||
baseUrl: "https://api.anthropic.com",
|
||||
models: [createModel("claude-sonnet-4-6", "Claude Sonnet 4.6")],
|
||||
},
|
||||
}),
|
||||
).toMatchObject({
|
||||
api: "anthropic-messages",
|
||||
});
|
||||
});
|
||||
|
||||
it("does not normalize non-Anthropic provider config", () => {
|
||||
const providerConfig = {
|
||||
baseUrl: "https://chatgpt.com/backend-api/codex",
|
||||
models: [createModel("gpt-5.4", "GPT-5.4")],
|
||||
};
|
||||
|
||||
expect(
|
||||
normalizeConfig({
|
||||
provider: "openai-codex",
|
||||
providerConfig,
|
||||
}),
|
||||
).toBe(providerConfig);
|
||||
});
|
||||
|
||||
it("applies Anthropic API-key defaults without loading the full provider plugin", () => {
|
||||
const nextConfig = applyConfigDefaults({
|
||||
config: {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-types";
|
||||
import {
|
||||
applyAnthropicConfigDefaults,
|
||||
normalizeAnthropicProviderConfig,
|
||||
normalizeAnthropicProviderConfigForProvider,
|
||||
} from "./config-defaults.js";
|
||||
|
||||
export function normalizeConfig(params: { provider: string; providerConfig: ModelProviderConfig }) {
|
||||
return normalizeAnthropicProviderConfig(params.providerConfig);
|
||||
return normalizeAnthropicProviderConfigForProvider(params);
|
||||
}
|
||||
|
||||
export function applyConfigDefaults(params: Parameters<typeof applyAnthropicConfigDefaults>[0]) {
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
} from "./cli-shared.js";
|
||||
import {
|
||||
applyAnthropicConfigDefaults,
|
||||
normalizeAnthropicProviderConfig,
|
||||
normalizeAnthropicProviderConfigForProvider,
|
||||
} from "./config-defaults.js";
|
||||
import { anthropicMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
||||
import { buildAnthropicReplayPolicy } from "./replay-policy.js";
|
||||
@@ -483,7 +483,8 @@ export function buildAnthropicProvider(): ProviderPlugin {
|
||||
},
|
||||
}),
|
||||
],
|
||||
normalizeConfig: ({ providerConfig }) => normalizeAnthropicProviderConfig(providerConfig),
|
||||
normalizeConfig: ({ provider, providerConfig }) =>
|
||||
normalizeAnthropicProviderConfigForProvider({ provider, providerConfig }),
|
||||
applyConfigDefaults: ({ config, env }) => applyAnthropicConfigDefaults({ config, env }),
|
||||
resolveDynamicModel: (ctx) => resolveAnthropicForwardCompatModel(ctx),
|
||||
resolveSyntheticAuth: ({ provider }) =>
|
||||
|
||||
Reference in New Issue
Block a user