Skip to content

fix(server): surface a failed model call instead of an empty assistant reply - #17

Open
2333sky wants to merge 1 commit into
mainfrom
fix/silent-model-failure
Open

2333sky wants to merge 1 commit into
mainfrom
fix/silent-model-failure

Conversation

@2333sky

@2333sky 2333sky commented Nov 4, 2026

Copy link
Copy Markdown
Owner

问题

模型调用失败时(没配 key、上游 429/5xx、网关超时),pi-agent-core 会把失败写进一条 stopReason: "error" 的 assistant 消息——但它不抛异常。于是:

  • 消息体是空的,界面上就是一条空白回复,用户不知道发生了什么;
  • 服务端也没日志,事后排查只能翻 JSONL 猜。

我在本地真机复现过一次:没有凭据的实例发一条消息,turnStatus: failed、52ms、content: []——用户看到的就是「没反应」。

改法

失败原因只存在于持久化记录里,所以从记录里读:

  1. 新增分类器 apps/server/src/runtime/agent/model-failure.ts
    • modelFailureFrom(message):只认 role: "assistant" 且 stopReason === "error"(或带 errorMessage)的消息,按正则分三类——credential_missing / upstream_error / model_error
    • modelFailureText(failure):生成一行人能看懂的话,带 provider/model/category/reason,不回显任何凭据
  2. 历史投影 agent-session-repository.ts:内容为空且命中失败时,把这句话写回消息体,前端自然就显示了
  3. 日志 node-session-service.ts:每个 message.completed 事件检查一次,命中就 log("error", ...) 并带结构化字段(provider/model/category),不重复刷

验证(先红后绿)

  • 只跑这两个文件:9 passed
  • 证伪:把 agent-session-repository.ts 回退到 292d0ec6 再跑 → 1 failed | 2 passed,失败点正是「空内容应被替换成可读文本」
  • 还原后 blob 43b9608f79b43f15772cd2026b7fc0f95fd5551b 与 HEAD 一致,工作树干净
  • pnpm --filter @pi-science/server typecheck exit 0

风险与已知限制

  1. 分类靠正则,不是结构化错误码——上游要是不按常规文案报错,会落到 model_error 这个兜底类(仍比空白好,但不是精确归因)。
  2. 文案是英文硬编码,没走 i18n。要本地化的话得再加一层 key 映射,本 PR 没做。
  3. 只覆盖「失败但被持久化成消息」这一路;如果运行时在某条路径上直接抛异常、根本没落消息,本 PR 管不到。
  4. 只加了一处日志,没有加指标/告警。

…t reply

A provider failure is persisted by the agent runtime as an assistant message with stopReason
error and no content, so the history projection returned an empty array and the server logged
nothing. Carry the provider, model and failure category into both surfaces.
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.

1 participant