Skip to content

Commit b83b2e3

Browse files
authored
fix(openai-codex): honor providerConfig.baseUrl in dynamic-model synthesis fallback (#76428)
* fix(openai-codex): honor providerConfig.baseUrl in dynamic-model synthesis fallback The synthesis fallback in resolveCodexForwardCompatModel hardcoded OPENAI_CODEX_BASE_URL when the model registry had no template row to clone, which meant openai-codex providers configured with a custom baseUrl (e.g. a local proxy that forwards Codex traffic) silently fell back to api.openai.com / chatgpt.com - bypassing the proxy and typically failing the auth contract. Synthesis now reads ctx.providerConfig.baseUrl when present, with the existing OPENAI_CODEX_BASE_URL constant as the fallback. No effect on template-clone or registry-find paths, which already inherit the configured baseUrl through the cloned template. * docs(changelog): add Unreleased Fixes entry for #76428 codex synthesis baseUrl honor
1 parent 73a95d3 commit b83b2e3

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ Docs: https://docs.openclaw.ai
6868
- Plugins/externalization: keep official external install docs, update examples, and live Codex npm checks on default npm tags instead of `@beta`. Thanks @vincentkoc.
6969
- Plugins/externalization: keep ACPX, Google Chat, and LINE publishable plugin dist trees out of the core npm package file list.
7070
- Plugins/ClawHub: fall back to version metadata when the artifact resolver route is missing and keep the Docker ClawHub fixture aligned with npm-pack artifact resolution, avoiding false version-not-found failures during plugin install validation. Thanks @vincentkoc.
71+
- Providers/openai-codex: honor `providerConfig.baseUrl` in the dynamic-model synthesis fallback so codex providers configured with a custom upstream (for example a forwarding proxy) no longer silently bypass the configured URL when the registry has no template row to clone for the requested model id. (#76428) Thanks @arniesaha.
7172
- Status/channels: show configured channels in `openclaw status` and config-only `openclaw channels status` output even when the Gateway is unreachable, avoiding empty Channels tables on WSL and other no-Gateway paths. Thanks @vincentkoc.
7273
- Plugins/ClawHub: explain unavailable explicit ClawHub ClawPack artifact downloads with a temporary npm install hint while ClawHub artifact routing rolls out. Thanks @vincentkoc.
7374
- Media: accept home-relative `MEDIA:~/...` attachment paths while preserving existing file-read policy, traversal checks, and media type validation. Fixes #73796. Thanks @fabkury.

extensions/openai/openai-codex-provider.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,43 @@ describe("openai codex provider", () => {
405405
});
406406
});
407407

408+
it("honors providerConfig.baseUrl in the gpt-5.5 synthesis fallback", () => {
409+
const provider = buildOpenAICodexProviderPlugin();
410+
411+
const model = provider.resolveDynamicModel?.({
412+
provider: "openai-codex",
413+
modelId: "gpt-5.5",
414+
modelRegistry: createSingleModelRegistry(createCodexTemplate({}), null) as never,
415+
providerConfig: { baseUrl: "http://proxy.local:30400" },
416+
});
417+
418+
expect(model).toMatchObject({
419+
id: "gpt-5.5",
420+
api: "openai-codex-responses",
421+
baseUrl: "http://proxy.local:30400",
422+
});
423+
});
424+
425+
it("honors providerConfig.baseUrl in the gpt-5.4 synthesis fallback", () => {
426+
const provider = buildOpenAICodexProviderPlugin();
427+
const emptyRegistry = { find: () => null };
428+
429+
const model = provider.resolveDynamicModel?.({
430+
provider: "openai-codex",
431+
modelId: "gpt-5.4",
432+
modelRegistry: emptyRegistry as never,
433+
providerConfig: { baseUrl: "http://proxy.local:30400" },
434+
});
435+
436+
expect(model).toMatchObject({
437+
id: "gpt-5.4",
438+
api: "openai-codex-responses",
439+
baseUrl: "http://proxy.local:30400",
440+
contextWindow: 1_050_000,
441+
maxTokens: 128_000,
442+
});
443+
});
444+
408445
it("resolves gpt-5.4-pro from a gpt-5.4 runtime template when legacy codex rows are absent", () => {
409446
const provider = buildOpenAICodexProviderPlugin();
410447

extensions/openai/openai-codex-provider.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ function normalizeCodexTransport(model: ProviderRuntimeModel): ProviderRuntimeMo
172172
function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext) {
173173
const trimmedModelId = ctx.modelId.trim();
174174
const lower = normalizeLowercaseStringOrEmpty(trimmedModelId);
175+
const synthBaseUrl = ctx.providerConfig?.baseUrl ?? OPENAI_CODEX_BASE_URL;
175176

176177
if (lower === OPENAI_CODEX_GPT_55_MODEL_ID) {
177178
const model = ctx.modelRegistry.find(PROVIDER_ID, trimmedModelId) as
@@ -188,7 +189,7 @@ function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext)
188189
name: trimmedModelId,
189190
api: "openai-codex-responses",
190191
provider: PROVIDER_ID,
191-
baseUrl: OPENAI_CODEX_BASE_URL,
192+
baseUrl: synthBaseUrl,
192193
reasoning: true,
193194
input: ["text", "image"],
194195
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -264,7 +265,7 @@ function resolveCodexForwardCompatModel(ctx: ProviderResolveDynamicModelContext)
264265
: trimmedModelId,
265266
api: "openai-codex-responses",
266267
provider: PROVIDER_ID,
267-
baseUrl: OPENAI_CODEX_BASE_URL,
268+
baseUrl: synthBaseUrl,
268269
reasoning: true,
269270
input: ["text", "image"],
270271
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

0 commit comments

Comments
 (0)