mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 22:44:31 +00:00
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:
committed by
Peter Steinberger
parent
e9d51d874b
commit
c9f2d6b761
@@ -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)", () => {
|
it("includes auth hint for unknown ollama models (#17328)", () => {
|
||||||
// resetMockDiscoverModels() in beforeEach already sets find → null
|
// resetMockDiscoverModels() in beforeEach already sets find → null
|
||||||
const result = resolveModel("ollama", "gemma3:4b", "/tmp/agent");
|
const result = resolveModel("ollama", "gemma3:4b", "/tmp/agent");
|
||||||
|
|||||||
@@ -161,7 +161,12 @@ export function resolveModelWithRegistry(params: {
|
|||||||
(entry) => normalizeProviderId(entry.provider) === normalizedProvider && entry.id === modelId,
|
(entry) => normalizeProviderId(entry.provider) === normalizedProvider && entry.id === modelId,
|
||||||
);
|
);
|
||||||
if (inlineMatch) {
|
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.
|
// Forward-compat fallbacks must be checked BEFORE the generic providerCfg fallback.
|
||||||
|
|||||||
Reference in New Issue
Block a user