openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
233 lines (232 loc) • 10.2 kB
JavaScript
import { a as normalizeLowercaseStringOrEmpty } from "./string-coerce-mnp54Vah.js";
import { c as isRecord } from "./utils-CCC-BEJH.js";
import "./string-coerce-runtime-CEGJWkQ_.js";
import { n as CLAUDE_CLI_DEFAULT_ALLOWLIST_REFS, t as CLAUDE_CLI_BACKEND_ID } from "./cli-constants-DrUvDt2r.js";
import { n as resolveKnownAnthropicModelRef, t as resolveClaudeCliAnthropicModelRefs } from "./claude-model-refs-DTOvY43e.js";
//#region extensions/anthropic/config-defaults.ts
const ANTHROPIC_PROVIDER_API = "anthropic-messages";
const ANTHROPIC_API_KEY_DEFAULT_ALLOWLIST_REFS = ["anthropic/claude-sonnet-4-6"];
function normalizeProviderId(provider) {
const normalized = normalizeLowercaseStringOrEmpty(provider);
if (normalized === "bedrock" || normalized === "aws-bedrock") return "amazon-bedrock";
return normalized;
}
function resolveAnthropicDefaultAuthMode(config, env) {
const profiles = config.auth?.profiles ?? {};
const anthropicProfiles = Object.entries(profiles).filter(([, profile]) => profile?.provider === "anthropic" || profile?.provider === "claude-cli");
const order = [...config.auth?.order?.anthropic ?? [], ...(config.auth?.order)?.["claude-cli"] ?? []];
for (const profileId of order) {
const entry = profiles[profileId];
if (!entry || entry.provider !== "anthropic" && entry.provider !== "claude-cli") continue;
if (entry.provider === "claude-cli") return "oauth";
if (entry.mode === "api_key") return "api_key";
if (entry.mode === "oauth" || entry.mode === "token") return "oauth";
}
const hasApiKey = anthropicProfiles.some(([, profile]) => profile?.provider === "anthropic" && profile?.mode === "api_key");
const hasOauth = anthropicProfiles.some(([, profile]) => profile?.provider === "claude-cli" || profile?.mode === "oauth" || profile?.mode === "token");
if (hasApiKey && !hasOauth) return "api_key";
if (hasOauth && !hasApiKey) return "oauth";
if (env.ANTHROPIC_OAUTH_TOKEN?.trim()) return "oauth";
if (env.ANTHROPIC_API_KEY?.trim()) return "api_key";
return null;
}
function resolveModelPrimaryValue(value) {
if (typeof value === "string") return value.trim() || void 0;
const primary = value?.primary;
if (typeof primary !== "string") return;
return primary.trim() || void 0;
}
function parseProviderModelRef(raw, defaultProvider) {
const trimmed = raw.trim();
if (!trimmed) return null;
const slashIndex = trimmed.indexOf("/");
if (slashIndex <= 0) return {
provider: defaultProvider,
model: trimmed
};
const provider = trimmed.slice(0, slashIndex).trim();
const model = trimmed.slice(slashIndex + 1).trim();
if (!provider || !model) return null;
return {
provider: normalizeProviderId(provider),
model
};
}
function isAnthropicCacheRetentionTarget(parsed) {
return Boolean(parsed && (parsed.provider === "anthropic" || parsed.provider === "amazon-bedrock" && normalizeLowercaseStringOrEmpty(parsed.model).includes("anthropic.claude")));
}
function usesClaudeCliModelSelection(config) {
const primary = resolveModelPrimaryValue(config.agents?.defaults?.model);
if ((primary ? parseProviderModelRef(primary, "anthropic") : null)?.provider === "claude-cli") return true;
return Object.entries(config.agents?.defaults?.models ?? {}).some(([key, entry]) => {
const parsed = parseProviderModelRef(key, "anthropic");
if (parsed?.provider === "claude-cli") return true;
const runtimeId = isRecord(entry?.agentRuntime) ? entry.agentRuntime.id : void 0;
return parsed?.provider === "anthropic" && normalizeLowercaseStringOrEmpty(runtimeId) === "claude-cli";
});
}
function usesSelectedClaudeCliAuthProfile(config) {
const profiles = config.auth?.profiles ?? {};
const orderedProfileIds = [...config.auth?.order?.anthropic ?? [], ...(config.auth?.order)?.["claude-cli"] ?? []];
for (const profileId of orderedProfileIds) {
const provider = profiles[profileId]?.provider;
if (provider === "claude-cli") return true;
if (provider === "anthropic") return false;
}
let hasClaudeCliProfile = false;
let hasAnthropicProfile = false;
for (const profile of Object.values(profiles)) {
if (profile?.provider === "claude-cli") hasClaudeCliProfile = true;
if (profile?.provider === "anthropic") hasAnthropicProfile = true;
}
return hasClaudeCliProfile && !hasAnthropicProfile;
}
function toCanonicalAnthropicModelRef(ref) {
return ref.startsWith(`claude-cli/`) ? `anthropic/${ref.slice(CLAUDE_CLI_BACKEND_ID.length + 1)}` : ref;
}
function modelEntryWithClaudeCliRuntime(entry) {
const base = isRecord(entry) ? { ...entry } : {};
const currentRuntime = normalizeLowercaseStringOrEmpty(isRecord(base.agentRuntime) ? base.agentRuntime.id : void 0);
if (currentRuntime && currentRuntime !== "auto") return base;
base.agentRuntime = {
...isRecord(base.agentRuntime) ? base.agentRuntime : {},
id: CLAUDE_CLI_BACKEND_ID
};
return base;
}
function collectClaudeCliRuntimeRefs(model) {
const refs = /* @__PURE__ */ new Set();
if (typeof model === "string") {
for (const ref of resolveClaudeCliAnthropicModelRefs(model)?.runtimeRefs ?? []) refs.add(ref);
return [...refs];
}
if (typeof model?.primary === "string") for (const ref of resolveClaudeCliAnthropicModelRefs(model.primary)?.runtimeRefs ?? []) refs.add(ref);
for (const fallback of model?.fallbacks ?? []) for (const ref of resolveClaudeCliAnthropicModelRefs(fallback)?.runtimeRefs ?? []) refs.add(ref);
return [...refs];
}
function collectClaudeCliRuntimeRefsFromModelMap(models) {
const refs = /* @__PURE__ */ new Set();
for (const key of Object.keys(models ?? {})) for (const ref of resolveClaudeCliAnthropicModelRefs(key)?.runtimeRefs ?? []) refs.add(ref);
return [...refs];
}
function collectClaudeCliRuntimeRefsFromConfig(config) {
const refs = new Set(collectClaudeCliRuntimeRefs(config.agents?.defaults?.model));
for (const ref of collectClaudeCliRuntimeRefsFromModelMap(config.agents?.defaults?.models)) refs.add(ref);
for (const agent of config.agents?.list ?? []) {
for (const ref of collectClaudeCliRuntimeRefs(agent.model)) refs.add(ref);
for (const ref of collectClaudeCliRuntimeRefsFromModelMap(agent.models)) refs.add(ref);
}
return [...refs];
}
function normalizeAnthropicProviderConfig(providerConfig) {
if (providerConfig.api || !Array.isArray(providerConfig.models) || providerConfig.models.length === 0) return providerConfig;
return {
...providerConfig,
api: ANTHROPIC_PROVIDER_API
};
}
/** Normalize Anthropic provider config defaults for one provider entry. */
function normalizeAnthropicProviderConfigForProvider(params) {
const provider = normalizeProviderId(params.provider);
if (provider !== "anthropic" && provider !== "claude-cli") return params.providerConfig;
return normalizeAnthropicProviderConfig(params.providerConfig);
}
/** Apply Anthropic and Claude CLI defaults to an OpenClaw config object. */
function applyAnthropicConfigDefaults(params) {
const defaults = params.config.agents?.defaults;
if (!defaults) return params.config;
const authMode = resolveAnthropicDefaultAuthMode(params.config, params.env);
if (!authMode) return params.config;
let mutated = false;
const nextDefaults = { ...defaults };
const contextPruning = defaults.contextPruning ?? {};
const heartbeat = defaults.heartbeat ?? {};
if (defaults.contextPruning?.mode === void 0) {
nextDefaults.contextPruning = {
...contextPruning,
mode: "cache-ttl",
ttl: defaults.contextPruning?.ttl ?? "1h"
};
mutated = true;
}
if (defaults.heartbeat?.every === void 0) {
nextDefaults.heartbeat = {
...heartbeat,
every: authMode === "oauth" ? "1h" : "30m"
};
mutated = true;
}
if (authMode === "api_key") {
const nextModels = defaults.models ? { ...defaults.models } : {};
let modelsMutated = false;
for (const [key, entry] of Object.entries(nextModels)) {
if (!isAnthropicCacheRetentionTarget(parseProviderModelRef(key, "anthropic"))) continue;
const current = entry ?? {};
const paramsValue = current.params ?? {};
if (typeof paramsValue.cacheRetention === "string") continue;
nextModels[key] = {
...current,
params: {
...paramsValue,
cacheRetention: "short"
}
};
modelsMutated = true;
}
const primary = resolveKnownAnthropicModelRef(resolveModelPrimaryValue(defaults.model));
if (primary) {
const parsedPrimary = parseProviderModelRef(primary, "anthropic");
if (parsedPrimary && isAnthropicCacheRetentionTarget(parsedPrimary)) {
const key = `${parsedPrimary.provider}/${parsedPrimary.model}`;
const current = nextModels[key] ?? {};
const paramsValue = current.params ?? {};
if (typeof paramsValue.cacheRetention !== "string") {
nextModels[key] = {
...current,
params: {
...paramsValue,
cacheRetention: "short"
}
};
modelsMutated = true;
}
}
}
if (Object.keys(nextModels).some((key) => isAnthropicCacheRetentionTarget(parseProviderModelRef(key, "anthropic")))) for (const ref of ANTHROPIC_API_KEY_DEFAULT_ALLOWLIST_REFS) {
if (ref in nextModels) continue;
nextModels[ref] = { params: { cacheRetention: "short" } };
modelsMutated = true;
}
if (modelsMutated) {
nextDefaults.models = nextModels;
mutated = true;
}
}
if (authMode === "oauth" && (usesClaudeCliModelSelection(params.config) || usesSelectedClaudeCliAuthProfile(params.config))) {
const nextModels = defaults.models ? { ...defaults.models } : {};
let modelsMutated = false;
const runtimeRefs = new Set(collectClaudeCliRuntimeRefsFromConfig(params.config));
for (const rawRef of CLAUDE_CLI_DEFAULT_ALLOWLIST_REFS) runtimeRefs.add(toCanonicalAnthropicModelRef(rawRef));
for (const ref of runtimeRefs) {
const current = nextModels[ref];
const updated = modelEntryWithClaudeCliRuntime(current);
if (JSON.stringify(updated) === JSON.stringify(current ?? {})) continue;
nextModels[ref] = updated;
modelsMutated = true;
}
if (modelsMutated) {
nextDefaults.models = nextModels;
mutated = true;
}
}
if (!mutated) return params.config;
return {
...params.config,
agents: {
...params.config.agents,
defaults: nextDefaults
}
};
}
//#endregion
export { normalizeAnthropicProviderConfigForProvider as n, applyAnthropicConfigDefaults as t };