Skip to content

fix(pi): 裸模型 id 自动补 settings.defaultProvider - #1003

Open
Barrierml wants to merge 1 commit into
deepcoldy:masterfrom
Barrierml:fix/pi-default-provider
Open

fix(pi): 裸模型 id 自动补 settings.defaultProvider#1003
Barrierml wants to merge 1 commit into
deepcoldy:masterfrom
Barrierml:fix/pi-default-provider

Conversation

@Barrierml

Copy link
Copy Markdown
Contributor

改了什么

Pi 适配器启动时如果 BotConfig.model 是裸 slug(例如 grok-4.6),会读 ~/.pi/agent/settings.jsondefaultProvider,把 --model 写成 provider/id。已带 / 的配置原样透传;没有 defaultProvider 时保持裸 id。

为什么

pi --model grok-4.6 会绕过 settings 的 defaultProvider。同名 id 同时出现在 team-gateway / tako-tiny32k / github-copilot / opencode / xai 时,Pi 直接报 ambiguous 并 exit 1。BotMux 大志只配了 model=grok-4.6,所以新会话起不来。

影响面

  • 只动 adapters/cli/pi.ts + 新 helper pi-model.ts
  • 其它 CLI / 公共 worker 路径未改
  • 已写 provider/id 的 bot 行为不变
  • 未配 defaultProvider 时行为与原来一致

测试

pnpm exec vitest run --project unit test/pi-model.test.ts test/cli-adapters.test.ts test/pi-initial-prompt.test.ts

412 passed。

Pi 收到 `--model grok-4.6` 时会绕过 settings.json 的 defaultProvider,
在多个已认证 provider 上撞同名 id 直接退出。启动前把裸 slug 写成
`provider/id`;已带斜杠的配置保持原样。
@Barrierml
Barrierml requested a review from deepcoldy as a code owner August 25, 2026 10:09
@deepcoldy

Copy link
Copy Markdown
Owner

感谢这个 PR!先说结论:方向和定位的 bug 都是对的——pi --model <裸id> 在多个已认证 provider 下确实会 ambiguous across providers 直接 exit 1,导致会话起不来。这点我用 pi 0.84.2 二进制复现确认了,settings.json 写了 defaultProvider 也照样歧义(因为 --model 完全绕过 defaultProvider,后者只在完全不传 --modelfindInitialModel 路径参与)。

不过目前"只要是裸 id 就补 defaultProvider 前缀"这一刀切得偏宽,实测会引入几处回归。核心原因是 pi 的 --model 解析(resolveCliModel)本身已经能处理一部分歧义:

  1. 裸 id 只有一个 provider 命中 → pi 直接解析,零报错;
  2. 裸 id 多个 provider 命中、但只有一个已认证 → pi 也会自动选那个已认证的,零报错;
  3. 只有 ≥2 个已认证 provider 同时命中同一裸 id 时,才会 ambiguous exit 1。

所以无条件补前缀会带来两类问题:

  • 踩掉本来能跑的 case(上面 1、2 两条):比如某 bot 配 model=grok-4.6 而只有一个 provider 认证,pi 本可干净解析成 <该provider>/grok-4.6,PR 却强改成 <defaultProvider>/grok-4.6,把能跑的会话弄挂。
  • 把干净报错变成静默错路由:当 defaultProvider 的 catalog 里并没有这个 id 时,pi 不报错,而是走 buildFallbackModel 造一个"自定义模型",只打一条 warning 就照常起会话 → 最终拿一个伪造的 model id 去打网关,运行期 400 或串模型。(buildFallbackModel 对 gateway 型 provider 是合理特性,但"无条件触发"就不对了——它是静默的。)

建议的收窄改法(保留你修复的赢面、同时灭掉回归):

  1. 已带 / → 原样透传(不变);
  2. 裸 id defaultProvider~/.pi/agent/models.jsonproviders[defaultProvider].models 里确实含这个 id → 才补前缀(catalog 命中必解析成功,不触发 fallback);
  3. 否则保持裸 id(交给 pi 自解析或让它自己干净 exit 1,都不比现状差);
  4. 可选加固:补前再确认 defaultProvider 已认证。

另有一个次要点供参考:resolvePiModelFlag 读的是 worker 进程的 HOME / PI_CODING_AGENT_DIR,而这两个环境变量目前不在 per-bot env 的保留名单里、可被 bot 配置覆盖 → 极端情况下 worker 侧读到的 settings.json 可能与 pi 子进程实际读的不同源。

以上是自动评审的初步意见,可能有疏漏,最终以维护者审阅为准。再次感谢贡献 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants