# 中断与恢复（对话进行控制）

英文版：[English](./interruption-resumption.md)

Dominds 对话（"dlg"）可以运行很长时间（流式生成、多步骤工作、工具使用）。用户也经常从多个浏览器标签页观察同一个对话。本文定义了以下内容的**交互设计**：

- 显示每个对话是**空闲**还是**进行中**
- 允许用户**中断**进行中的工作（"停止"）
- 允许用户（或操作员）**恢复**符合条件的对话（"继续" / "全部恢复"）

本文档仅为设计文档（无实现细节）。

---

## 目标

- **即时控制：** 如果对话正在进行中，用户可以从对话视图快速停止它。
- **操作员安全：** 全局"紧急停止"可以在后端范围内停止所有进行中的对话。
- **崩溃恢复：** 后端崩溃/重启后，进行中的对话显示为可恢复（安全时）。
- **多客户端一致性：** 所有连接的观察者收敛到相同状态（一个标签页停止/恢复时，其他标签页可见）。
- **清晰和信任：** UI 明显显示对话**为什么**停止以及**"继续"**会做什么。

## 非目标（本文档范围）

- 取消或回滚现实世界的副作用（本文档仅定义**控制**和**状态可见性**）。
- 为外部操作设计完整的重试/补偿系统。
- 重新设计对话数据模型或持久化格式。

---

## 术语

- **dlg（对话）：** 单个对话/工作线程。
- **进行中：** 后端正在主动驱动对话（生成输出和/或执行步骤）而不等待用户输入。
- **空闲：** 对话未进行中；它要么正在等待用户输入，要么处于稳定的完成/暂停状态。
- **中断：** 在到达稳定的"等待用户"点之前，进行中停止。
- **恢复：** 重新启动中断对话的后端驱动，使其能够达到稳定结果（通常生成/完成待处理的智能体对话过程）。

## 核心用户体验表面区域

### 1) 每个对话的主要控制：`发送 ↔ 停止`

当当前查看的对话**进行中**时：

- 输入区域的主要操作从**发送**变为**停止**。
- 按下**停止**请求中断该对话的当前进行。
- 请求停止后，UI 应反映**停止中…**（直到后端报告对话不再进行）。

当对话**空闲**时：

- 主要操作是**发送**（正常消息传递）。

设计意图："停止"是最快、最容易发现的控制，必须在不搜索菜单的情况下可用。

### 2) 全局操作员控制：`紧急停止` 和 `全部恢复`

WebUI 提供全局控制（通常在标题/工具栏中），作用于所有对话：

- 放置：**紧急停止**和**全部恢复**放在顶部标题中，紧邻连接状态指示器的左侧，以便无论打开哪个对话都保持可见。
- **紧急停止：** 请求中断后端范围内**所有**进行中的对话。
  - 适用于失控输出、资源保护或操作员干预。
  - 应在视觉上与每个对话的停止区分开来（更多"危险"可发现性）。
- **全部恢复：** 请求恢复**所有符合条件的**对话（详情见下文）。

两个控制都必须一目了然地显示"它们将影响什么"（例如，进行中 / 符合条件的对话计数），并应避免让用户/操作员感到惊讶。

### 3) 历史中继续可发现性：`继续`

在对话历史末尾，当对话符合恢复条件时，显示**继续**按钮。

- 继续是**对话范围的**（仅影响当前对话）。
- 继续应与简短的原因标签配对，例如：
  - "被你停止"
  - "被紧急停止停止"
  - "被服务器重启中断"

如果对话不符合条件，UI 不应显示继续，并且可以显示简短的、非侵入性的解释（例如"等待你的输入"）。

---

## 后端必须传达的内容（设计契约）

为了支持上述 UX，后端必须为每个对话暴露：

- 它是否当前**进行中**
- 如果未进行中，是**空闲-等待用户**还是**中断**还是**阻塞**
- 如果中断，一个适合用户显示的**中断原因**

关键设计要求：客户端不应需要从计时或 UI 启发式推断进行中/空闲。进行中状态是一等公民。

---

## 对话运行状态模型（概念性）

每个对话始终处于以下用户相关运行状态之一：

1. **空闲（等待用户）**
   - 用户可以发送。
   - 不符合恢复条件（没有进行中的内容可以继续）。

2. **进行中**
   - 主要控制变为停止。
   - 不符合恢复条件（因为它已经在运行）。

3. **中断（可恢复）**
   - 进行中在运行中途停止。
   - 可以提供继续（如果符合条件）。

4. **阻塞（需要用户操作）**
   - 对话未进行中，但无法在没有特定用户操作的情况下继续（例如回答待处理的问题）。
   - 不提供继续；相反，UI 应引导所需操作。

5. **终止（完成或不可恢复）**
   - 对话达到稳定的结束状态，其中"继续"没有意义（例如完成）或需要手动干预超出恢复机制。

此模型故意极简：它匹配用户需要决定"发送 / 停止 / 继续 / 行动"的内容。

---

## 中断语义（用户期望）

### "停止"的含义

- 停止是**尽力而为的中断请求**：对话应尽快停止进行。
- 停止后，对话必须转换到非进行中状态，并清楚地记录**为什么**停止。
- UI 应将停止视为**暂停**，而不是破坏性取消（预期恢复，除非不符合条件）。

### "紧急停止"的含义

- 与停止语义相同，但应用于所有进行中的对话。
- 紧急停止不应静默影响空闲对话超出 UI 状态标签。

### "继续 / 恢复"的含义

- 恢复意味着"尝试完成被中断的进行中的工作"并使对话返回稳定状态。
- 恢复从用户角度应该是**幂等的**：重复点击不应创建令人困惑的并行运行。
- 如果恢复可能重复外部副作用，UI 不得假装它是无风险的；它应显示不确定性并倾向于要求明确的用户确认。

---

## 恢复资格（扩展）

当以下**所有**条件为真时，对话**符合恢复条件**：

1. **当前未进行中**
   - 如果它正在运行，停止是相关操作。

2. **有中断的进行中的运行**
   - 最近的运行因中断而结束，而不是干净地到达"等待用户"。
   - 可能符合条件的典型中断原因：
     - 手动停止（每个对话）
     - 紧急停止（全局）
     - 进行中时后端崩溃/重启
     - 资源保护停止（操作员/系统）

3. **没有待处理的用户输入**
   - 如果对话被阻塞等待用户回答问题，则**不符合**条件。
   - 适当的操作是所需的用户输入，而不是继续。

4. **恢复目标定义明确**
   - 系统可以识别它正在尝试完成什么（例如，完成待处理的助手程或完成中断的步骤）。
   - 如果系统无法定义安全/清晰的恢复目标，对话不符合条件（或继续必须成为引导的"先解决"流程）。

5. **在不惊吓用户的情况下尝试是安全的**
   - 如果有合理的风险恢复将重复外部可见副作用，UI 必须要求明确的确认步骤（或将对话标记为不符合条件，直到用户解决歧义）。

### 常见不符合条件的情况

- 对话**空闲等待用户**（正常状态）。
- 对话**阻塞**（需要用户操作，如回答待处理的问题）。
- 对话处于**终止**状态（完成或不可恢复，无需手动干预）。
- 对话状态**未知/过时**（例如，断开的客户端尚无权威后端状态）；在状态已知之前不应出现继续。

---

## 多客户端行为（多个标签页 / 观察者）

- 进行中/空闲/中断状态必须被视为**对话全局**，而非"每个标签页"。
- 如果任何客户端停止或恢复对话，所有其他观察客户端应及时更新：
  - 发送 ↔ 停止一致切换
  - 继续一致出现/消失
  - 原因标签保持一致

设计意图：用户永远不应看到两个标签页不同意对话是否正在运行。

---

## UI 反馈和透明度

为减少混淆并建立信任：

- 对话历史应在有意义的状态转换时包含轻量级"系统标记"：
  - "被你停止" / "被紧急停止停止" / "被服务器重启中断"
  - "已恢复"
- 对话列表/侧边栏可以选择显示紧凑徽章：
  - "进行中"
  - "已中断"
  - "需要输入"

这些提示使全局控制（"全部恢复"）更安全，因为用户可以在不打开每个对话的情况下看到正在发生什么。
