Files
karuo-ai/01_卡资(金)/金仓_存储备份/脚本/codex_longxia_api_fix.py
2026-07-19 00:21:46 +08:00

119 lines
4.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""修复龙虾U盘AI (simpleapi.quwanzhi.com) 502禁用 auto 模型,固定 gpt-5.4。"""
from __future__ import annotations
import json
import shutil
import subprocess
import time
from datetime import datetime
from pathlib import Path
CODEX_HOME = Path.home() / ".codex"
COCKPIT = Path.home() / ".antigravity_cockpit"
APIKEY_ID = "codex_apikey_5df7aea89c1abb33b2043a4d3cad9071"
PROVIDER = "codex_local_access"
MODEL = "gpt-5.4" # simpleapi /responsesauto→502gpt-5.4/5.5 可用
PROXY_BASE = "http://127.0.0.1:63849/v1" # 本地代理把 auto 改写为 gpt-5.4
def backup(path: Path) -> None:
if path.exists():
shutil.copy2(path, path.with_name(f"{path.name}.bak.{datetime.now().strftime('%Y%m%d%H%M%S')}"))
def load_api_key() -> tuple[str, str]:
acct = json.loads((COCKPIT / "codex_accounts" / f"{APIKEY_ID}.json").read_text(encoding="utf-8"))
key = acct.get("openai_api_key") or ""
base = (acct.get("api_base_url") or "").rstrip("/")
if not key or not base:
raise SystemExit("Cockpit 龙虾账号缺少 openai_api_key 或 api_base_url")
return key, base
def apply_config(api_key: str, base_url: str) -> None:
cfg = CODEX_HOME / "config.toml"
text = cfg.read_text(encoding="utf-8") if cfg.exists() else ""
lines = text.splitlines()
out, skip = [], False
for line in lines:
s = line.strip()
if s.startswith("model_provider = "):
continue
if s.startswith("model = "):
out.append(f'model = "{MODEL}"')
continue
if s.startswith("[model_providers."):
skip = True
continue
if skip:
if s.startswith("[") and not s.startswith("[model_providers."):
skip = False
out.append(line)
continue
out.append(line)
while out and not out[-1].strip():
out.pop()
provider_blocks = [
"",
f"[model_providers.{PROVIDER}]",
'name = "龙虾U盘AI"',
f'base_url = "{PROXY_BASE}" # lobster proxy: auto->gpt-5.4',
'wire_api = "responses"',
"requires_openai_auth = false",
"supports_websockets = false",
f'experimental_bearer_token = "{api_key}"',
"",
]
# model_provider 必须写在顶层(紧挨 model/notify禁止落在 [features] 等表内
inserted = False
final: list[str] = []
for line in out:
final.append(line)
if not inserted and (
line.startswith("notify = ")
or (line.startswith("sandbox_mode = ") and "model_provider" not in "\n".join(final))
):
final.append(f'model_provider = "{PROVIDER}"')
inserted = True
if not inserted:
# 回退:插在第一个 [section] 之前
idx = next((i for i, l in enumerate(final) if l.startswith("[")), len(final))
final.insert(idx, f'model_provider = "{PROVIDER}"')
final.insert(idx, "")
final.extend(provider_blocks)
backup(cfg)
cfg.write_text("\n".join(final) + "\n", encoding="utf-8")
auth = CODEX_HOME / "auth.json"
backup(auth)
auth.write_text(
json.dumps({"auth_mode": "apikey", "OPENAI_API_KEY": api_key}, ensure_ascii=False, indent=2) + "\n",
encoding="utf-8",
)
def restart_codex(api_key: str) -> None:
cli = Path("/Applications/Codex.app/Contents/Resources/codex")
if cli.exists():
subprocess.run([str(cli), "logout"], check=False, capture_output=True)
subprocess.run([str(cli), "login", "--with-api-key"], input=api_key.encode(), check=False, capture_output=True)
subprocess.run(["killall", "Codex"], check=False)
time.sleep(1.5)
subprocess.run(["/usr/bin/open", "-a", "Codex"], check=True)
def main() -> None:
api_key, base_url = load_api_key()
apply_config(api_key, base_url)
restart_codex(api_key)
print(f"[OK] 龙虾U盘AI 已配置 model={MODEL} provider={PROVIDER} base={base_url}")
print("[WARN] Codex 内勿选 auto 模型,请用 gpt-5.4 或 gpt-5.5")
if __name__ == "__main__":
main()