fix(agents): let forward-compat resolve api when inline model omits it

When a user configures `models.providers.openai-codex` with a models
array but omits the `api` field, `buildInlineProviderModels` produces
an entry with `api: undefined`.  The inline-match early return then
hands this incomplete model straight to the caller, skipping the
forward-compat resolver that would supply the correct
`openai-codex-responses` api — causing a crash loop.

Let the inline match fall through to forward-compat when `api` is
absent so the resolver chain can fill it in.

Fixes #39682
This commit is contained in:
justinhuangcode
2026-03-08 11:08:37 +00:00
committed by Peter Steinberger
parent e9d51d874b
commit c9f2d6b761
2 changed files with 32 additions and 1 deletions

View File

@@ -638,6 +638,32 @@ describe("resolveModel", () => {
});
});
it("uses codex fallback when inline model omits api (#39682)", () => {
mockOpenAICodexTemplateModel();
// When a user lists gpt-5.4 under openai-codex models without specifying
// an api, the inline match must not shadow the forward-compat resolver
// that supplies "openai-codex-responses".
const cfg: OpenClawConfig = {
models: {
providers: {
"openai-codex": {
baseUrl: "https://custom.example.com",
models: [{ id: "gpt-5.4" }],
},
},
},
} as unknown as OpenClawConfig;
const result = resolveModel("openai-codex", "gpt-5.4", "/tmp/agent", cfg);
expect(result.error).toBeUndefined();
expect(result.model).toMatchObject({
api: "openai-codex-responses",
id: "gpt-5.4",
provider: "openai-codex",
});
});
it("includes auth hint for unknown ollama models (#17328)", () => {
// resetMockDiscoverModels() in beforeEach already sets find → null
const result = resolveModel("ollama", "gemma3:4b", "/tmp/agent");

View File

@@ -161,7 +161,12 @@ export function resolveModelWithRegistry(params: {
(entry) => normalizeProviderId(entry.provider) === normalizedProvider && entry.id === modelId,
);
if (inlineMatch) {
return normalizeModelCompat(inlineMatch as Model<Api>);
// When the inline model already carries a concrete api, use it as-is.
// Otherwise fall through so forward-compat resolvers can supply the
// correct api (e.g. "openai-codex-responses" for gpt-5.4). #39682
if (inlineMatch.api) {
return normalizeModelCompat(inlineMatch as Model<Api>);
}
}
// Forward-compat fallbacks must be checked BEFORE the generic providerCfg fallback.