Skip to content

feat(desktop): define one channel for each kind of error feedback #5797

Open

Description

@Colafornia
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 an aria-hidden ticking countdown. Whatever replaces it must keep announcing the wait state.
  • A turn can fail with no answer bubble to hang ChatMessageMetadata on; the channel for turn failure must work without a rendered assistant message.

Acceptance criteria

  • DESIGN.md contains 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 流程产出的浅色和深色模式前后对比截图。

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions