diff --git a/src/harness/codex-harness.ts b/src/harness/codex-harness.ts index e40eaf8f..cf174f05 100644 --- a/src/harness/codex-harness.ts +++ b/src/harness/codex-harness.ts @@ -199,6 +199,11 @@ export function codexChildEnv(source: NodeJS.ProcessEnv, jail: string): NodeJS.P export function prepareCodexHome(source: NodeJS.ProcessEnv, jail: string): string { const target = join(jail, "codex-home"); mkdirSync(target, { recursive: true }); + if (source.OPENAI_BASE_URL) { + writeFileSync(join(target, "config.toml"), `openai_base_url = ${JSON.stringify(source.OPENAI_BASE_URL)}\n`, { + mode: 0o600, + }); + } if (source.OPENAI_API_KEY) { writeFileSync( join(target, "auth.json"), diff --git a/test/codex-harness.test.ts b/test/codex-harness.test.ts index 168d858c..e47b975c 100644 --- a/test/codex-harness.test.ts +++ b/test/codex-harness.test.ts @@ -304,6 +304,13 @@ test("Codex materializes API-key auth into its isolated home, and never an ambie assert.equal(existsSync(join(prepareCodexHome({ HOME: homedir() }, bare), "auth.json")), false); }); +test("Codex materializes an OpenAI-compatible endpoint into its isolated home", (t) => { + const jail = mkdtempSync(join(tmpdir(), "qm-codex-endpoint-test-")); + t.after(() => rmSync(jail, { recursive: true, force: true })); + const home = prepareCodexHome({ OPENAI_BASE_URL: "https://proxy.example.com/v1" }, jail); + assert.equal(readFileSync(join(home, "config.toml"), "utf8"), 'openai_base_url = "https://proxy.example.com/v1"\n'); +}); + test("Codex children cannot use parent surface, control, or terminal tools", () => { assert.equal(codexChildToolAllowed("history"), true); assert.equal(codexChildToolAllowed("execute"), true);