























@@ -63,11 +63,17 @@ const ANTHROPIC_SONNET_46_DOT_MODEL_ID = "claude-sonnet-4.6";
6363const ANTHROPIC_SONNET_TEMPLATE_MODEL_IDS = ["claude-sonnet-4-5", "claude-sonnet-4.5"] as const;
6464const ANTHROPIC_MODERN_MODEL_PREFIXES = [
6565"claude-opus-4-7",
66+"claude-opus-4.7",
6667"claude-opus-4-6",
68+"claude-opus-4.6",
6769"claude-sonnet-4-6",
70+"claude-sonnet-4.6",
6871"claude-opus-4-5",
72+"claude-opus-4.5",
6973"claude-sonnet-4-5",
74+"claude-sonnet-4.5",
7075"claude-haiku-4-5",
76+"claude-haiku-4.5",
7177] as const;
7278const ANTHROPIC_SETUP_TOKEN_NOTE_LINES = [
7379"Anthropic setup-token auth is supported in OpenClaw.",
@@ -370,6 +376,46 @@ function matchesAnthropicModernModel(modelId: string): boolean {
370376return ANTHROPIC_MODERN_MODEL_PREFIXES.some((prefix) => lower.startsWith(prefix));
371377}
372378379+function hasImageInput(input: unknown): boolean {
380+return Array.isArray(input) && input.includes("image");
381+}
382+383+function supportsAnthropicImageInput(modelId: string, modelName?: string): boolean {
384+return [modelId, modelName]
385+.filter((value): value is string => typeof value === "string")
386+.some((candidate) => matchesAnthropicModernModel(candidate));
387+}
388+389+function applyAnthropicImageInputCapability(params: {
390+modelId: string;
391+model: ProviderRuntimeModel;
392+}): ProviderRuntimeModel | undefined {
393+if (hasImageInput(params.model.input)) {
394+return undefined;
395+}
396+if (!supportsAnthropicImageInput(params.modelId, params.model.name)) {
397+return undefined;
398+}
399+return {
400+ ...params.model,
401+input: ["text", "image"],
402+};
403+}
404+405+function normalizeAnthropicResolvedModel(
406+ctx: ProviderNormalizeResolvedModelContext,
407+): ProviderRuntimeModel | undefined {
408+const imageCapableModel = applyAnthropicImageInputCapability(ctx) ?? ctx.model;
409+const contextWindowModel =
410+applyAnthropicOpus47ContextWindow({
411+config: ctx.config,
412+provider: ctx.provider,
413+modelId: ctx.modelId,
414+model: imageCapableModel,
415+}) ?? imageCapableModel;
416+return contextWindowModel === ctx.model ? undefined : contextWindowModel;
417+}
418+373419function buildAnthropicAuthDoctorHint(params: {
374420config?: ProviderAuthContext["config"];
375421store: AuthProfileStore;
@@ -576,16 +622,21 @@ export function buildAnthropicProvider(): ProviderPlugin {
576622if (!model) {
577623return undefined;
578624}
625+const imageCapableModel =
626+applyAnthropicImageInputCapability({
627+modelId: ctx.modelId,
628+ model,
629+}) ?? model;
579630return (
580631applyAnthropicOpus47ContextWindow({
581632config: ctx.config,
582633provider: ctx.provider,
583634modelId: ctx.modelId,
584- model,
585-}) ?? model
635+model: imageCapableModel,
636+}) ?? imageCapableModel
586637);
587638},
588-normalizeResolvedModel: (ctx) => applyAnthropicOpus47ContextWindow(ctx),
639+normalizeResolvedModel: (ctx) => normalizeAnthropicResolvedModel(ctx),
589640resolveSyntheticAuth: ({ provider }) =>
590641normalizeLowercaseStringOrEmpty(provider) === CLAUDE_CLI_BACKEND_ID
591642 ? resolveClaudeCliSyntheticAuth()
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。