From 92e864a5215d59beaab2e0591d5cf48868eff9db Mon Sep 17 00:00:00 2001 From: zhulijin1991 <167979819+zhulijin1991@users.noreply.github.com> Date: Sun, 12 Apr 2026 08:16:45 +0800 Subject: [PATCH] fix(image): respect configured provider for bare image overrides --- .../model-fallback.image-provider.test.ts | 28 +++++++++++++++++++ src/agents/model-fallback.ts | 21 +++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 src/agents/model-fallback.image-provider.test.ts diff --git a/src/agents/model-fallback.image-provider.test.ts b/src/agents/model-fallback.image-provider.test.ts new file mode 100644 index 00000000000..4a9c3af9c8c --- /dev/null +++ b/src/agents/model-fallback.image-provider.test.ts @@ -0,0 +1,28 @@ +import { describe, expect, it, vi } from "vitest"; +import { runWithImageModelFallback } from "./model-fallback.js"; +import { makeModelFallbackCfg } from "./test-helpers/model-fallback-config-fixture.js"; + +describe("runWithImageModelFallback provider resolution", () => { + it("inherits the configured image-model provider for bare override ids", async () => { + const cfg = makeModelFallbackCfg({ + agents: { + defaults: { + imageModel: { + primary: "openai-codex/gpt-5.4", + fallbacks: ["openai-codex/gpt-5.4-mini"], + }, + }, + }, + }); + const run = vi.fn().mockResolvedValueOnce("ok"); + + const result = await runWithImageModelFallback({ + cfg, + modelOverride: "gpt-5.4-mini", + run, + }); + + expect(result.result).toBe("ok"); + expect(run.mock.calls).toEqual([["openai-codex", "gpt-5.4-mini"]]); + }); +}); diff --git a/src/agents/model-fallback.ts b/src/agents/model-fallback.ts index 08fc71808a5..1dde7f41e1d 100644 --- a/src/agents/model-fallback.ts +++ b/src/agents/model-fallback.ts @@ -375,6 +375,25 @@ function resolveImageFallbackCandidates(params: { return candidates; } +function resolveImageFallbackDefaultProvider(cfg: OpenClawConfig | undefined): string { + const configuredPrimary = resolveAgentModelPrimaryValue(cfg?.agents?.defaults?.imageModel); + if (configuredPrimary?.trim()) { + const aliasIndex = buildModelAliasIndex({ + cfg: cfg ?? {}, + defaultProvider: DEFAULT_PROVIDER, + }); + const resolved = resolveModelRefFromString({ + raw: configuredPrimary, + defaultProvider: DEFAULT_PROVIDER, + aliasIndex, + }); + if (resolved?.ref.provider) { + return resolved.ref.provider; + } + } + return DEFAULT_PROVIDER; +} + function resolveFallbackCandidates(params: { cfg: OpenClawConfig | undefined; provider: string; @@ -922,7 +941,7 @@ export async function runWithImageModelFallback(params: { }): Promise> { const candidates = resolveImageFallbackCandidates({ cfg: params.cfg, - defaultProvider: DEFAULT_PROVIDER, + defaultProvider: resolveImageFallbackDefaultProvider(params.cfg), modelOverride: params.modelOverride, }); if (candidates.length === 0) {