AI_PROJECT / src /scripts /configure-codex-local-proxy.mjs
chenchenaoyang's picture
Deploy from Codex on 2026-04-08
4b8c220 verified
#!/usr/bin/env node
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
const DEFAULT_CODEX_HOME = path.join(os.homedir(), ".codex");
const DEFAULT_AUTH_PATH = path.join(DEFAULT_CODEX_HOME, "auth.json");
const DEFAULT_CONFIG_PATH = path.join(DEFAULT_CODEX_HOME, "config.toml");
const DEFAULT_BACKUP_DIR = path.join(DEFAULT_CODEX_HOME, "backups", "configure-codex-local-proxy");
const DEFAULT_PROXY_BASE_URL = "http://127.0.0.1:8787";
const DEFAULT_PROXY_API_KEY = "local-acc-pool-proxy-key";
const DEFAULT_MODEL = "gpt-5.4";
function parseArgs(argv) {
const args = {};
for (const part of argv) {
if (!part.startsWith("--")) continue;
const raw = part.slice(2);
const idx = raw.indexOf("=");
if (idx < 0) {
args[raw] = "true";
continue;
}
args[raw.slice(0, idx)] = raw.slice(idx + 1);
}
return args;
}
function printUsage() {
console.log(`Usage:
node src/scripts/configure-codex-local-proxy.mjs
Options:
--base-url=http://127.0.0.1:8787
--api-key=local-acc-pool-proxy-key
--model=gpt-5.4
--auth-path=~/.codex/auth.json
--config-path=~/.codex/config.toml
--backup-dir=~/.codex/backups/configure-codex-local-proxy
--help
`);
}
function nowStamp() {
const date = new Date();
const pad = (value) => String(value).padStart(2, "0");
return [
date.getFullYear(),
pad(date.getMonth() + 1),
pad(date.getDate()),
"-",
pad(date.getHours()),
pad(date.getMinutes()),
pad(date.getSeconds()),
].join("");
}
function buildConfigToml({ model, baseUrl }) {
return [
'model_provider = "OpenAI"',
`model = "${model}"`,
`review_model = "${model}"`,
"disable_response_storage = true",
'network_access = "enabled"',
"windows_wsl_setup_acknowledged = true",
"model_context_window = 1000000",
"model_auto_compact_token_limit = 900000",
'model_reasoning_effort = "medium"',
"",
"[model_providers]",
"[model_providers.OpenAI]",
'name = "OpenAI"',
`base_url = "${baseUrl}"`,
'wire_api = "responses"',
"requires_openai_auth = true",
"",
].join("\n");
}
async function ensureDir(dirPath) {
await fs.mkdir(dirPath, { recursive: true });
}
async function backupIfExists(sourcePath, backupDir) {
try {
await fs.access(sourcePath);
} catch {
return null;
}
await ensureDir(backupDir);
const targetPath = path.join(
backupDir,
`${path.basename(sourcePath)}.${nowStamp()}.bak`,
);
await fs.copyFile(sourcePath, targetPath);
return targetPath;
}
async function main() {
const args = parseArgs(process.argv.slice(2));
if (args.help === "true") {
printUsage();
return;
}
const baseUrl = args["base-url"] || process.env.CODEX_PROXY_BASE_URL || DEFAULT_PROXY_BASE_URL;
const apiKey = args["api-key"] || process.env.CODEX_PROXY_API_KEY || DEFAULT_PROXY_API_KEY;
const model = args.model || DEFAULT_MODEL;
const authPath = path.resolve(args["auth-path"] || DEFAULT_AUTH_PATH);
const configPath = path.resolve(args["config-path"] || DEFAULT_CONFIG_PATH);
const backupDir = path.resolve(args["backup-dir"] || DEFAULT_BACKUP_DIR);
const authBackup = await backupIfExists(authPath, backupDir);
const configBackup = await backupIfExists(configPath, backupDir);
await ensureDir(path.dirname(authPath));
await ensureDir(path.dirname(configPath));
const authJson = { OPENAI_API_KEY: apiKey };
const configToml = buildConfigToml({ model, baseUrl });
await fs.writeFile(authPath, `${JSON.stringify(authJson, null, 2)}\n`, "utf8");
await fs.writeFile(configPath, configToml, "utf8");
console.log("Codex configured to local proxy.");
console.log(`Auth file: ${authPath}`);
console.log(`Config file: ${configPath}`);
console.log(`Proxy base URL: ${baseUrl}`);
console.log(`Model: ${model}`);
console.log(`Auth backup: ${authBackup || "(none)"}`);
console.log(`Config backup: ${configBackup || "(none)"}`);
}
main().catch((error) => {
console.error(error?.message || error);
process.exitCode = 1;
});