fix(agents): honor image tool model overrides

This commit is contained in:
Peter Steinberger
2026-05-10 17:57:59 +01:00
parent 58e953fab1
commit bf2e4bcea5
3 changed files with 59 additions and 0 deletions

View File

@@ -34,6 +34,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Agents/image: honor explicit `image` tool model overrides even when `agents.defaults.imageModel` is unset, restoring one-off vision calls for configured multimodal providers. Fixes #79341. Thanks @haumanto.
- Telegram: pass agent-scoped media roots through gateway message actions so workspace-local media from the active agent is not rejected as cross-agent access. Thanks @frankekn.
- CLI/gateway: keep `gateway status --deep` plugin-aware so configured plugin manifest warnings, including missing channel config metadata, stay visible during install and update smoke checks.
- Feishu: fall back to a top-level group send when normal group quoted replies target a withdrawn or missing message, preventing replies from disappearing silently while preserving native topic safety. Fixes #79349. Thanks @arlen8411.

View File

@@ -660,6 +660,46 @@ describe("image tool implicit imageModel config", () => {
});
});
it("honors a per-call model override when no imageModel is configured", async () => {
await withTempAgentDir(async (agentDir) => {
const describeImage = vi.fn(async (params: ImageDescriptionRequest) => ({
text: `ok ${params.provider}/${params.model}`,
model: params.model,
}));
installImageUnderstandingProviderStubs({
id: "opencode-go",
capabilities: ["image"],
describeImage,
});
const cfg: OpenClawConfig = {
agents: { defaults: { model: { primary: "opencode-go/kimi-k2.6" } } },
};
const tool = createRequiredImageTool({
config: cfg,
agentDir,
deferAutoModelResolution: true,
});
const result = await tool.execute("t1", {
prompt: "Describe this image.",
image: `data:image/png;base64,${ONE_PIXEL_PNG_B64}`,
model: "opencode-go/mimo-v2-omni",
});
expect(describeImage).toHaveBeenCalledWith(
expect.objectContaining({
provider: "opencode-go",
model: "mimo-v2-omni",
}),
);
expect(result.content).toEqual(
expect.arrayContaining([
expect.objectContaining({ type: "text", text: "ok opencode-go/mimo-v2-omni" }),
]),
);
});
});
it("pairs minimax primary with MiniMax-VL-01 (and fallbacks) when auth exists", async () => {
await withTempAgentDir(async (agentDir) => {
vi.stubEnv("MINIMAX_API_KEY", "minimax-test");

View File

@@ -182,6 +182,20 @@ export function resolveImageModelConfigForTool(params: {
});
}
function resolveImageModelConfigForOverride(params: {
cfg?: OpenClawConfig;
modelOverride?: string;
}): ImageModelConfig | null {
const model = params.modelOverride?.trim();
if (!model) {
return null;
}
return resolveConfiguredImageModelRefs({
cfg: params.cfg,
imageModelConfig: { primary: model },
});
}
function pickMaxBytes(cfg?: OpenClawConfig, maxBytesMb?: number): number | undefined {
if (typeof maxBytesMb === "number" && Number.isFinite(maxBytesMb) && maxBytesMb > 0) {
return Math.floor(maxBytesMb * 1024 * 1024);
@@ -622,6 +636,10 @@ export function createImageTool(options?: {
// MARK: - Run image prompt with all loaded images
const imageModelConfig =
resolvedImageModelConfig ??
resolveImageModelConfigForOverride({
cfg: options?.config,
modelOverride,
}) ??
resolveImageModelConfigForTool({
cfg: options?.config,
agentDir,