From 416720ae514cae3bc5fc6e3a4318ab5002e2b0d6 Mon Sep 17 00:00:00 2001 From: delta-cloud-208e Date: Sun, 8 Mar 2026 08:43:25 +0000 Subject: [PATCH] fix(codex): add env_key to custom provider + model_catalog_json for picker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add env_key = "OPENAI_API_KEY" to [model_providers.custom] in PS1 fallback templates (fixes 401 Unauthorized on machines without Python 3.11+) - Add model_catalog_json config + model_catalog.json file generation (fixes empty model picker — all 4 models now visible in interactive mode) - Both fixes applied in: codex_patcher.py, ucodex_install.ps1, ucodex_update.ps1 Co-Authored-By: Claude Opus 4.6 --- codex/codex_patcher.py | 31 +++++++++++++++++++++++++++++++ codex/ucodex_install.ps1 | 16 ++++++++++++++++ codex/ucodex_update.ps1 | 16 ++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/codex/codex_patcher.py b/codex/codex_patcher.py index 57a65bb..8843efb 100755 --- a/codex/codex_patcher.py +++ b/codex/codex_patcher.py @@ -44,6 +44,7 @@ RESET = "\033[0m" # Managed config keys (we update these, preserve everything else) MANAGED_TOP_KEYS = { "model", "model_reasoning_effort", "model_provider", + "model_catalog_json", "approval_policy", "sandbox_mode", "check_for_update_on_startup", "forced_login_method", } @@ -163,6 +164,14 @@ def generate_config_toml(existing, config): lines.append(f'model = "{config["model"]}"') lines.append(f'model_reasoning_effort = "{config.get("model_reasoning_effort", "high")}"') lines.append('model_provider = "custom"') + + # Model catalog path (for model picker) + codex_dir = os.path.join(os.path.expanduser("~"), ".codex") + catalog_path = os.path.join(codex_dir, "model_catalog.json") + # Use forward slashes for cross-platform TOML compatibility + catalog_path_toml = catalog_path.replace("\\", "/") + lines.append(f'model_catalog_json = "{catalog_path_toml}"') + lines.append(f'approval_policy = "{config.get("approval_policy", "never")}"') lines.append(f'sandbox_mode = "{config.get("sandbox_mode", "danger-full-access")}"') lines.append(f'check_for_update_on_startup = {toml_value(config.get("check_for_update", False))}') @@ -464,6 +473,21 @@ def apply_all_patches(config, home_dir=None): # Backup before any changes backup_file(config_path) + # Generate model catalog JSON for model picker + catalog_path = os.path.join(codex_dir, "model_catalog.json") + models = config.get("models", [config["model"]]) + catalog_entries = [] + for m in models: + catalog_entries.append({ + "id": m, + "object": "model", + "created": 1700000000, + "owned_by": "system" + }) + with open(catalog_path, "w", encoding="utf-8") as f: + json.dump(catalog_entries, f, indent=2) + print(f" {'[OK]':>8} Catalog: {catalog_path} ({len(models)} models)") + # Generate new config.toml (merge) new_content = generate_config_toml(existing, config) @@ -574,6 +598,13 @@ def patch_user(user_home, config): existing = read_toml(config_path) backup_file(config_path) + # Generate model catalog + catalog_path = os.path.join(codex_dir, "model_catalog.json") + models = config.get("models", [config["model"]]) + catalog_entries = [{"id": m, "object": "model", "created": 1700000000, "owned_by": "system"} for m in models] + with open(catalog_path, "w", encoding="utf-8") as f: + json.dump(catalog_entries, f, indent=2) + new_content = generate_config_toml(existing, config) with open(config_path, "w", encoding="utf-8") as f: f.write(new_content) diff --git a/codex/ucodex_install.ps1 b/codex/ucodex_install.ps1 index 8a4b82b..60343c7 100644 --- a/codex/ucodex_install.ps1 +++ b/codex/ucodex_install.ps1 @@ -215,10 +215,12 @@ if (-not $pyCmd) { Remove-Item $configToml -Force -ErrorAction SilentlyContinue } + $catalogPath = "$configDir\model_catalog.json" -replace '\\', '/' $tomlContent = @" model = "gpt-5.4" model_reasoning_effort = "high" model_provider = "custom" +model_catalog_json = "$catalogPath" approval_policy = "never" sandbox_mode = "danger-full-access" check_for_update_on_startup = false @@ -230,6 +232,7 @@ enabled = false [model_providers.custom] name = "custom" base_url = "https://ai.37-187-136-86.sslip.io/v1" +env_key = "OPENAI_API_KEY" wire_api = "responses" [notice] @@ -243,6 +246,19 @@ wire_api = "responses" [System.IO.File]::WriteAllText($configToml, $tomlContent) Write-Host " config.toml created: $configToml" -ForegroundColor Green + # Create model catalog for model picker + $catalogFile = Join-Path $configDir "model_catalog.json" + $catalogJson = @" +[ + {"id": "gpt-5.4", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.3-codex-spark", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.3-codex", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.2-codex", "object": "model", "created": 1700000000, "owned_by": "system"} +] +"@ + [System.IO.File]::WriteAllText($catalogFile, $catalogJson) + Write-Host " model_catalog.json created: $catalogFile" -ForegroundColor Green + # Set env vars via setx & setx OPENAI_API_KEY "ClauderAPI" 2>$null | Out-Null & setx OPENAI_BASE_URL "https://ai.37-187-136-86.sslip.io/v1" 2>$null | Out-Null diff --git a/codex/ucodex_update.ps1 b/codex/ucodex_update.ps1 index 23ceb51..e18a560 100644 --- a/codex/ucodex_update.ps1 +++ b/codex/ucodex_update.ps1 @@ -138,10 +138,12 @@ if (-not $pyCmd) { $configToml = Join-Path $configDir "config.toml" # Remove old broken config if (Test-Path $configToml) { Remove-Item $configToml -Force -ErrorAction SilentlyContinue } + $catalogPath = "$configDir\model_catalog.json" -replace '\\', '/' $tomlContent = @" model = "gpt-5.4" model_reasoning_effort = "high" model_provider = "custom" +model_catalog_json = "$catalogPath" approval_policy = "never" sandbox_mode = "danger-full-access" check_for_update_on_startup = false @@ -153,6 +155,7 @@ enabled = false [model_providers.custom] name = "custom" base_url = "https://ai.37-187-136-86.sslip.io/v1" +env_key = "OPENAI_API_KEY" wire_api = "responses" [notice] @@ -163,6 +166,19 @@ wire_api = "responses" "gpt-5.2-codex" = "done" "@ [System.IO.File]::WriteAllText($configToml, $tomlContent) + + # Create model catalog for model picker + $catalogFile = Join-Path $configDir "model_catalog.json" + $catalogJson = @" +[ + {"id": "gpt-5.4", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.3-codex-spark", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.3-codex", "object": "model", "created": 1700000000, "owned_by": "system"}, + {"id": "gpt-5.2-codex", "object": "model", "created": 1700000000, "owned_by": "system"} +] +"@ + [System.IO.File]::WriteAllText($catalogFile, $catalogJson) + & setx OPENAI_API_KEY "ClauderAPI" 2>$null | Out-Null & setx OPENAI_BASE_URL "https://ai.37-187-136-86.sslip.io/v1" 2>$null | Out-Null $env:OPENAI_API_KEY = "ClauderAPI"