Repository navigation
fix(importers): discover Pi auth-only model providers - #1761
Conversation
The explicit model-config scan only read ~/.pi/agent/models.json, so providers connected through `pi /login` (for example DeepSeek or a Z.AI coding plan) never appeared in the Pi group. Their keys live in auth.json and their endpoint/model metadata lives in Pi's cached models-store.json. Read both files and pair each API-key provider with its largest coherent endpoint group. OAuth/subscription grants stay in Pi, `!command` keys are never executed or stored, and models.json remains authoritative when both files describe a provider. A key in auth.json also fills a models.json provider whose `env:`/`$VAR` reference cannot resolve in Desktop. Tests cover the cached-catalog pairing, OAuth/command exclusion, endpoint selection, and the scanner merge.
|
Reviewed the split in an isolated worktree. This is the right shape for the batch condition, and the core logic is the same code I reviewed in #1750. Split is clean. Tests: 30/30. The safety properties I checked on #1750 still hold here:
One note for the description: this PR is the model-import half only — the MCP scan half ( |
|
Thanks. Added a Related section: the MCP half is #1750, closed for this round with the branch retained for the next round when UI changes are in scope. This PR is explicitly model-import only. |
|
Heads-up on why this shows no checks: all three workflows for Since the code is unchanged from what I reviewed, I re-ran the affected suites locally on @vastsa — flagging in case the approval request is sitting in a queue; this one needs only the standard approval, not a re-push. |
vastsa
left a comment
There was a problem hiding this comment.
目前不建议合入:模型配置回退读取有一个会让 Pi 旧路径失效的实际问题,见行内说明。修复并补上回退路径用例后,我会继续复核。感谢把模型导入拆成无界面改动。
| (await readJson(path.join(home, ".pi", "models.json"))); | ||
| return parsePiModelConfig(models, env); | ||
| const agentDir = path.join(home, ".pi", "agent"); | ||
| const fallbackDir = path.join(home, ".pi"); |
There was a problem hiding this comment.
这里的 readJson(...) 返回 Promise,?? 在 Promise 被 await 之前就求值,因此左侧 Promise 永远非 null,~/.pi/models.json / auth.json / models-store.json 的回退路径实际上不会读取。旧实现先 await 再判断;当前新增测试只写了 ~/.pi/agent/,没覆盖 fallback。请把每个读取改成“await 主路径,再在结果为空时 await fallback”(可抽一个小 helper),并增加仅有 ~/.pi/ 文件的回归用例。
`readJson(...) ?? readJson(...)` compared the Promise itself, so the left
side was always truthy and ~/.pi/{models,auth,models-store}.json were
never read. Use a sequential helper that awaits each candidate before
moving on, preserving the ~/.pi/agent primary path.
Add a fallback-only regression test covering all three Pi files.
|
确认,这确实是一个真 bug: |
|
已在当前 head 暂不合入的唯一阻塞是远端 CI、Docs check、PR-base 三个 workflow 在这个 head 上都处于 |
|
Independently verified
On the blocker: I confirmed the same thing independently — all three workflows for @vastsa — the approval is the only step left on this one, and the local evidence above covers what the blocked workflows would have told you. |
vastsa
left a comment
There was a problem hiding this comment.
确认 #1750 拆分后的本 PR 只包含 model importer/shared parser/tests/docs,没有 apps/desktop/src 或 i18n 界面改动。
#1732 相关导入缺失是真问题:原扫描只读取 models.json,pi /login 写入 auth.json 的 provider 会被漏掉。现在通过 Pi 的缓存模型目录补齐 auth-only provider,models.json 仍优先;未解析的 env key 会回退到同 provider 的 auth key。OAuth 凭据和 !command 都不会被导入,secret 也不会进入 renderer candidate。
我在包含最新 main 的隔离候选上验证无冲突,并运行 importer 7/7、shared parser 24/24,以及 shared TypeScript build,全部通过。此前发现的 Promise fallback 问题已由顺序 await 修复,且 ~/.pi/ 三个旧路径均有回归覆盖。
按 @vastsa 在 #1750 的意见拆分:本 PR 只包含模型导入修复,不修改任何
apps/desktop/src或packages/i18n文件,符合“本轮只合入无界面改动 fix”。修复
模型导入扫描过去只读
~/.pi/agent/models.json,因此通过pi /login连接的 provider(例如 DeepSeek、Z.AI Coding CN)不会出现在已有的 Pi 分组里。parsePiAuthModelConfig():读取~/.pi/agent/auth.json的 API key,并与 Pi 缓存的~/.pi/agent/models-store.json目录配对。models.json仍然是权威来源;只有它没有描述的 provider 才使用 auth+catalog 草稿。models.json的env:/$VAR在 Desktop 进程里解析不到时,用同一 provider 的auth.jsonkey 补齐。!command不执行、不作为字面量密钥保存。MCP 扫描的修改不在本 PR 内:那部分需要新增可见的导入来源/标签、导入面板和 9 个语言包,按照本轮范围留到允许界面改动的轮次。
验证(base
589e580,headf0d4216)pnpm --filter @pi-desktop/shared exec vitest run src/model-config-import.test.ts→ 24 passednode --test apps/desktop/test/model-config-import.test.mjs→ 7 passedpnpm --filter @pi-desktop/desktop typecheck→ passedpnpm lint:biome→ 125 files checked, no fixespnpm test:e2e:settings-inline-import→ passedpnpm check:pr-base→ passed(origin/main589e580是 HEAD 的祖先)兼容性与安全
Related