Repository navigation
fix(codex): allow direct API login on launch - #8014
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
…8014-20261104 Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; GPT-6 (Codex); OpenAI; self_reported
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
已在 Codex 使用直接 API key 的用户,在打开 GPT 路由时遇到错误。 直接 API 登录已存在时,原预检拒绝打开;现在允许继续打开并保留外部认证原样,切回受管槽位仍要求先处理外部账号变化。 合法直接 API 登录通过预检,账号状态诚实显示未匹配;损坏、混合及未完成事务仍拒绝,凭据、配置和 vault 均不改写。 本 PR 不实现自动付费切换、调用方 API 优先、模型推理或实际 AppKit 重开验收。 本 PR 只恢复合法直接 API 登录的启动预检,并保持损坏缓存诊断;订阅/API 调用方主力与兜底策略属于后续同一 account 工作。
改动思路 / Approach
在既有原生账号 IO owner 内区分外部 API 登录与受管 relay,不复制 Key、不增加账号存储、刷新器或切换策略。 原生 identity() 继续只识别受管槽位;打开一个已由 Codex 认证的外部 API 路由,与覆盖其凭据,是两种不同操作。判别放在原 IO owner,启动入口只在原身份检查失败后使用它。pending.json 的恢复门先于此分支,switch() 继续沿原锁与事务运行。没有新增配置字段、账号副本、重试器或决策 owner。当前交付边界是直接 API 启动预检及损坏缓存诊断,独立调用方额度策略继续保留。
具体改动 / Changes
规格基准:spec_ref = packages/loopx-codex-provider-routing/NATIVE.md,spec_revision = a0130633723210a5406dca61ee27aa33fe48b3f3。按改前规格映射:native-single-writer 保持唯一凭据 writer;native-recovery-preserved 保持原锁、事务、回滚和显式选择保护;native-paid-opt-in 保持添加 Key 与启用自动付费的区别,均由上述实际入口与相关 suite 验证。
关键代码讲解
external_api_auth()检查对象、API 模式、非空无空白 Key、无混合 token,排除受管 relay。复审发现原实现遇到[]、null会抛出AttributeError;已增加对象检查,并在原测试集中覆盖五种非对象值。account_preflight()先拒绝未完成事务,再运行原生身份检查;只有有效外部 API 缓存能从该身份拒绝中继续,原 auth、配置、active 及 vault 内容均不写入。Accounts.status()对无法解析成受管身份的缓存投影current_login_matches=false;不会宣称已加入受管账号,也不会放宽后续switch()。
改动位于两个生产文件与一个既有测试文件;没有生成或私有文件。正常合入当前 main 后重新检查了完整 PR 差异,后续修复为两行生产检查与一个五分支负例。
对主干的风险 / Risks
主要风险是把“可以打开”错误扩大成“可以覆盖账号”,或吞掉真正的损坏/恢复错误。使用同一组合成文件,通过真实 native_app.account_preflight() 做了 base a0130633723210a5406dca61ee27aa33fe48b3f3 与 head 770c032a5d4bbb435b3cbb438da40d12b637cd25 对照:旧版只在合法直接 API 一例应当改变,七个负例保持拒绝,八例 auth/config/active/vault 均无变化。原 PR 的数组与 null 诊断回归也已在原 head 复现,并由当前 head 的相同入口验证修复。
验证:PASS,53 tests/25 subtests;八例真实文件预检;native-policy、native-host、native-host-clients、provider-routing 四组 smoke;Ruff、RFC 双语检查与预合并五项直接检查。预合并 catalog 选择为零项,未把它写成额外 canary 覆盖。实际三个公开候选文件扫描通过;全局 check 同时保留两个其他旧 Goal 的 canonical-authority 诊断,没有为此扩大或迁移它们。
语义与 CI 对齐
本改动是原外部认证输入边界的有意修正,复用既有 vocabulary,保留共享原生事务。API 自动切换开关及调度未变。按本 Goal 的 wait_for_ci=false,没有查询、轮询或等待 CI;当前结论来自上述本地受影响不变量验证。
我的整体评价 / Verdict
没有剩余阻塞发现,当前 exact head 可以合并。long_horizon 与 user_experience 均改善:反复启动无需重新处理已有的合法外部登录;原错误和恢复路径仍可见,零新增确认轮次。范围和维护成本相称;已在现有判别器内完成有证据的边界收紧,无需另建框架。没有渲染变更,visual review 不适用;实际桌面 AppKit 重开与模型推理没有重跑,也未据此宣称通过。完整 account 调用方策略仍由本轮后续工作交付。
English verdict: APPROVE 770c032; valid direct API launch is restored, malformed-cache diagnostics repaired, managed switching remains fenced; local boundary and native suites pass.
Problem
The native account preflight treated every API-key auth cache outside the managed relay vault as corruption. A valid direct
sk-proj-…login therefore madepersonal-apps statusreportconfig_ready: falseand could block launch even though the App route was valid.The native vault intentionally does not own or migrate direct API keys, so opening the route must not require identity equality with a managed slot.
Behavior
current_login_matches: falseinstead of failing status readback.Verification
pytest -q tests/presentation/test_native_app.py tests/presentation/test_native_account_store.py: 51 passed, 20 subtests passed.git diff --checkpassed.config_ready: truewhile retaining the direct API key unchanged.No credential value is included in the diff or PR.