fix: normalize fallback updates for string model defaults

This commit is contained in:
Gustavo Madeira Santana
2026-02-23 02:45:02 -05:00
parent b2956f073c
commit 2ca832a8ea
3 changed files with 25 additions and 7 deletions

View File

@@ -82,6 +82,25 @@ describe("models set + fallbacks", () => {
});
});
it("preserves primary when adding fallbacks to string defaults.model", async () => {
mockConfigSnapshot({ agents: { defaults: { model: "openai/gpt-4.1-mini" } } });
const runtime = makeRuntime();
await modelsFallbacksAddCommand("anthropic/claude-opus-4-6", runtime);
expect(writeConfigFile).toHaveBeenCalledTimes(1);
const written = getWrittenConfig();
expect(written.agents).toEqual({
defaults: {
model: {
primary: "openai/gpt-4.1-mini",
fallbacks: ["anthropic/claude-opus-4-6"],
},
models: { "anthropic/claude-opus-4-6": {} },
},
});
});
it("normalizes provider casing in models set", async () => {
mockConfigSnapshot({});
const runtime = makeRuntime();

View File

@@ -2,12 +2,13 @@ import { buildModelAliasIndex, resolveModelRefFromString } from "../../agents/mo
import type { OpenClawConfig } from "../../config/config.js";
import { loadConfig } from "../../config/config.js";
import { logConfigUpdated } from "../../config/logging.js";
import { resolveAgentModelFallbackValues, toAgentModelListLike } from "../../config/model-input.js";
import type { AgentModelConfig } from "../../config/types.agents-shared.js";
import type { RuntimeEnv } from "../../runtime.js";
import {
DEFAULT_PROVIDER,
ensureFlagCompatibility,
mergePrimaryFallbackConfig,
type PrimaryFallbackConfig,
modelKey,
resolveModelTarget,
resolveModelKeysFromEntries,
@@ -17,17 +18,14 @@ import {
type DefaultsFallbackKey = "model" | "imageModel";
function getFallbacks(cfg: OpenClawConfig, key: DefaultsFallbackKey): string[] {
const entry = cfg.agents?.defaults?.[key] as unknown as PrimaryFallbackConfig | undefined;
return entry?.fallbacks ?? [];
return resolveAgentModelFallbackValues(cfg.agents?.defaults?.[key]);
}
function patchDefaultsFallbacks(
cfg: OpenClawConfig,
params: { key: DefaultsFallbackKey; fallbacks: string[]; models?: Record<string, unknown> },
): OpenClawConfig {
const existing = cfg.agents?.defaults?.[params.key] as unknown as
| PrimaryFallbackConfig
| undefined;
const existing = toAgentModelListLike(cfg.agents?.defaults?.[params.key]);
return {
...cfg,
agents: {

View File

@@ -166,7 +166,8 @@ export function mergePrimaryFallbackConfig(
existing: PrimaryFallbackConfig | undefined,
patch: { primary?: string; fallbacks?: string[] },
): PrimaryFallbackConfig {
const next: PrimaryFallbackConfig = { ...existing };
const base = existing && typeof existing === "object" ? existing : undefined;
const next: PrimaryFallbackConfig = { ...base };
if (patch.primary !== undefined) {
next.primary = patch.primary;
}