Repository navigation
feat(desktop): define one channel for each kind of error feedback #5797
Description
English
Part of #TBD-tracker.
Problem
When something fails, the user can get feedback through four different channels, and nothing decides which one a failure should use:
| Channel | Current use |
|---|---|
toast.error |
154 call sites (plus 50 toast.success) |
Banner |
138 uses in 51 files: 45 error, 48 warning, 23 info, 6 success |
Hand-written role="alert" |
29 uses in 21 files |
| In-transcript notices | failed-turn banner and provider retry notice (both container="section"), recovery notice, sandbox and bypass banners inside tool detail, stream truncation as ChatSystemMessage |
The same kind of failure therefore looks different on different surfaces, and a surface can show the same failure twice. DESIGN.md defines status colors and tints, but not which channel carries which failure. Open issues such as #4854 (a compaction toast that never settles) and #5762 (a generic failure message) are partly symptoms of this.
Astryx already provides the parts: field status messages, card Banner, ChatMessageMetadata with status="error" and a retry action (the pattern its failed-message examples use), Toast, and AlertDialog.
Desired outcome
DESIGN.md has one rule table that maps each kind of failure to one channel. A starting proposal:
| Failure | Channel |
|---|---|
| Invalid input in a field | Field status message, next to the field |
| A panel or page cannot load or save | Card Banner at the top of that panel |
| A turn fails or is interrupted | In the turn: metadata row with error status and retry, plus a short cause line |
| A background or asynchronous action fails away from where the user is | Toast with a diagnostic action |
| The user must decide before continuing | AlertDialog |
The transcript then moves onto the table: failed-turn banner, provider retry notice, recovery notice, stream truncation note, and sandbox and bypass banners.
Constraints
- The provider retry notice is a
role="status"live region with anaria-hiddenticking countdown. Whatever replaces it must keep announcing the wait state. - A turn can fail with no answer bubble to hang
ChatMessageMetadataon; the channel for turn failure must work without a rendered assistant message.
Acceptance criteria
-
DESIGN.mdcontains the rule table, including when not to toast (for example, a failure the user is already looking at). - Every transcript failure notice uses the channel the table names. The PR lists each notice with its old and new channel.
- A failure is shown once per surface. No transcript failure also raises a toast.
- Retry and safe-resume actions keep working, with their existing tests.
- Screen readers still announce each failure once, through the channel's own live region.
- Before and after captures in light and dark, produced by the A0 loop, are attached to the PR.
中文
属于 #TBD-tracker。
问题
出错时,用户可能通过四种不同渠道收到提示,而没有任何规则决定某类失败该走哪一种:
| 渠道 | 当前使用 |
|---|---|
toast.error |
154 处调用(另有 50 处 toast.success) |
Banner |
51 个文件共 138 处:错误 45、警告 48、信息 23、成功 6 |
手写 role="alert" |
21 个文件共 29 处 |
| 对话流内的提示 | 失败轮次横幅和服务商重试提示(都是 container="section")、恢复提示、工具详情里的沙箱和绕过权限横幅、用 ChatSystemMessage 显示的流截断提示 |
结果是,同一类失败在不同界面上看起来不一样,同一个界面也可能把同一个失败显示两次。DESIGN.md 规定了状态色和浅色底,但没有规定哪种渠道承载哪类失败。#4854(压缩任务的提示一直不结束)和 #5762(通用失败文案)等未关闭的 issue,部分就是这个问题的表现。
Astryx 已经提供了所需的组件:字段状态信息、卡片形态的 Banner、带 status="error" 和重试操作的 ChatMessageMetadata(它的失败消息示例就是这样做的)、Toast 和 AlertDialog。
期望结果
DESIGN.md 中有一张规则表,把每类失败对应到唯一的渠道。初步提案:
| 失败类型 | 渠道 |
|---|---|
| 字段输入无效 | 字段状态信息,显示在字段旁边 |
| 面板或页面无法加载或保存 | 该面板顶部的卡片 Banner |
| 一轮对话失败或中断 | 在该轮内:元数据行显示错误状态和重试,外加一行简短原因 |
| 用户当前不在的地方,后台或异步操作失败 | 带诊断操作的 Toast |
| 用户必须先做决定才能继续 | AlertDialog |
然后把对话流迁移到这张表上:失败轮次横幅、服务商重试提示、恢复提示、流截断提示,以及沙箱和绕过权限横幅。
约束
- 服务商重试提示是一个
role="status"实时区域,跳动的倒计时被aria-hidden。替换它的任何形式都必须继续播报等待状态。 - 一轮对话可能在没有助手气泡的情况下失败;轮次失败的渠道必须在不渲染助手消息时也能工作。
验收标准
-
DESIGN.md包含这张规则表,并说明什么情况下不应弹出提示(例如用户正在看着的失败)。 - 对话流中的每个失败提示都使用表中规定的渠道。PR 逐条列出每个提示的原渠道和新渠道。
- 同一个失败在同一界面只显示一次。对话流中的失败不再额外弹出提示。
- 重试和安全恢复操作继续可用,现有测试保持通过。
- 屏幕阅读器对每个失败仍只播报一次,通过所用渠道自带的实时区域。
- PR 附上 A0 流程产出的浅色和深色模式前后对比截图。
Activity