Skip to content

Commit 91c94e9

Browse files
committed
fix(agents): cover legacy Codex provider config hint
1 parent 7b9ec53 commit 91c94e9

2 files changed

Lines changed: 40 additions & 22 deletions

File tree

src/agents/embedded-agent-runner/model.test.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,24 +2832,45 @@ describe("resolveModel", () => {
28322832
);
28332833
});
28342834

2835-
it("suggests running doctor for legacy openai-codex provider", async () => {
2836-
const cfg = {
2837-
agents: {
2838-
defaults: {
2839-
models: {
2840-
"openai-codex/gpt-5.4": {},
2835+
it.each([
2836+
{
2837+
name: "agent model entry",
2838+
cfg: {
2839+
agents: {
2840+
defaults: {
2841+
models: {
2842+
"openai-codex/gpt-5.4": {},
2843+
},
28412844
},
28422845
},
28432846
},
2844-
} as unknown as OpenClawConfig;
2845-
2846-
const result = await resolveModelAsync("openai-codex", "gpt-5.4", "/tmp/agent", cfg, {
2847-
runtimeHooks: createRuntimeHooks(),
2848-
skipAgentDiscovery: true,
2849-
});
2847+
},
2848+
{
2849+
name: "legacy provider config",
2850+
cfg: {
2851+
models: {
2852+
providers: {
2853+
"openai-codex": {
2854+
models: [{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex" }],
2855+
},
2856+
},
2857+
},
2858+
},
2859+
},
2860+
])("suggests running doctor for openai-codex from $name", async ({ cfg }) => {
2861+
const result = await resolveModelAsync(
2862+
"openai-codex",
2863+
"gpt-5.4",
2864+
"/tmp/agent",
2865+
cfg as unknown as OpenClawConfig,
2866+
{
2867+
runtimeHooks: createRuntimeHooks(),
2868+
skipAgentDiscovery: true,
2869+
},
2870+
);
28502871

28512872
expect(result.error).toBe(
2852-
'Unknown model: openai-codex/gpt-5.4. Found agents.defaults.models["openai-codex/gpt-5.4"], but "openai-codex" is a legacy provider ID. Run `openclaw doctor --fix` to migrate to the current OpenAI provider format. If the provider has no authenticated profile, run `openclaw models status` to check provider auth and re-authenticate if needed. See https://docs.openclaw.ai/concepts/model-providers.',
2873+
'Unknown model: openai-codex/gpt-5.4. "openai-codex" is a legacy provider ID. Run `openclaw doctor --fix` to migrate legacy model and provider config to the current OpenAI format. If the provider has no authenticated profile, run `openclaw models status` to check provider auth and re-authenticate if needed. See https://docs.openclaw.ai/concepts/model-providers.',
28532874
);
28542875
});
28552876

src/agents/embedded-agent-runner/model.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,6 +1908,12 @@ function buildMissingProviderModelRegistrationHint(params: {
19081908
modelId: string;
19091909
cfg?: OpenClawConfig;
19101910
}): string | undefined {
1911+
// Legacy openai-codex refs can come from model selections, provider config,
1912+
// or persisted routes. All of them should be repaired by doctor rather than
1913+
// turned into a new models.providers[] registration.
1914+
if (normalizeProviderId(params.provider) === "openai-codex") {
1915+
return `"openai-codex" is a legacy provider ID. Run \`openclaw doctor --fix\` to migrate legacy model and provider config to the current OpenAI format. If the provider has no authenticated profile, run \`openclaw models status\` to check provider auth and re-authenticate if needed. See https://docs.openclaw.ai/concepts/model-providers.`;
1916+
}
19111917
const configuredModels = params.cfg?.agents?.defaults?.models;
19121918
if (!configuredModels) {
19131919
return undefined;
@@ -1929,15 +1935,6 @@ function buildMissingProviderModelRegistrationHint(params: {
19291935
if (agentRuntimeId) {
19301936
return `Found agents.defaults.models["${agentModelKey}"] bound to the "${agentRuntimeId}" agent runtime. Models served by an agent runtime come from that runtime and its linked account, not from models.providers["${params.provider}"].models[] — registering it there will not make it usable. Confirm "${params.modelId}" is still offered by the "${agentRuntimeId}" runtime and switch agents.defaults.model.primary to a currently available model (run \`openclaw models list --provider ${params.provider}\` to list them). See https://docs.openclaw.ai/concepts/model-providers.`;
19311937
}
1932-
// Legacy openai-codex is folded into the "openai" provider. Its models
1933-
// register through the OpenAI provider at startup, so a missing-model
1934-
// error here is almost always a legacy config reference or a missing
1935-
// auth profile. The correct fix is to migrate the config via doctor
1936-
// or re-authenticate the provider, not to add a models.providers[]
1937-
// overlay (which the validator rejects without baseUrl).
1938-
if (normalizeProviderId(params.provider) === "openai-codex") {
1939-
return `Found agents.defaults.models["${agentModelKey}"], but "openai-codex" is a legacy provider ID. Run \`openclaw doctor --fix\` to migrate to the current OpenAI provider format. If the provider has no authenticated profile, run \`openclaw models status\` to check provider auth and re-authenticate if needed. See https://docs.openclaw.ai/concepts/model-providers.`;
1940-
}
19411938
const providerConfig = findNormalizedProviderValue(
19421939
params.cfg?.models?.providers,
19431940
params.provider,

0 commit comments

Comments
 (0)