# @deepseek-ai/dsh-client-ui-question

[English](README.md) | 中文

Web `ask_user_question` 功能插件。只有选择 Web 功能时，其主机侧才会挂载 `dsh-tool-ask-user`；浏览器侧会把 `question` 配置项注册到会话拥有的 `conversation.composer` 键控 slot 中。

组件每次渲染一个问题，提供进度导航、单选和多选选项、由标签后缀派生的推荐徽标，以及自定义答案。用户打开或编辑自定义答案时，多选题草稿会保留已选中的标签，因此提交项可以同时携带 `selected` 与 `custom`；单选题的自定义答案仍保持互斥。问题详情复用助手输出的 `MarkdownText` 原语，包括其 GFM 渲染与不受信任内容策略。限高卡片保持标题、导航与提交动作固定，超长的详情与选项共享内部滚动区。单选选项会立即前进；所有问题均已回答或跳过后，Enter 会提交；IME 输入法组合期间按 Enter 只会确认输入候选，不会前进。组件为整个请求提交一批结构化答案：「跳过此问题」会保留其他草稿，并为该项发出既有的空 `{ selected: [] }` 形状；关闭则以 `ASK_CANCELLED` 拒绝整个等待。

若某个请求的唯一问题声明了呈现意图，则改为渲染该意图自己的界面。`plan-review`——由 `dsh-plan-mode` 在 `exit_plan_mode` 审阅上设置——采用等待审批卡片的形状：一条 `Plan review` 条带、计划作为可滚动的 markdown 主体、问题文本作为卡片的无障碍名称，以及一行 `Chat about it` / `Refuse` / `Approve` 的决定操作。Approve 与 Refuse 用提问方自己的选项标签回答（意图指名哪个标签表示批准，因此裁决绝不依赖选项顺序），并把提问方的描述保留为 tooltip；`Chat about it` 以 `ASK_CANCELLED` 拒绝该等待，让编辑器归位，用户可以直接说出他想说的话。卡片只在能够发出该请求允许的每一个答案时才接管：只有一个问题、声明了意图、计划以 `detail` 存在、提供了被指名的批准标签，且是二元单选（除批准外最多一个选项，且非多选）。其他任何情形——没有意图、一批含多个问题、缺少计划、批准标签未命中任何选项、出现第三个选项、多选决定——都留在能够表达它的通用流程上。意图改变的只是布局，从不改变可达的答案。

选择状态只存在于以请求 rpcId 为 key 的组件本地。使用相同 id 回放时，只要组件仍挂载，就会保留草稿；主机发出的 `question/resolved` 则会移除编辑器。主机仍具有最终决定权：HTTP 交付成功不会在本地移除待处理状态。

编辑器外框文案（翻页器、按钮、占位符、校验提示）是双语的：插件在 `dsh-client-locale` 的 `question` 命名空间下注册 zh/en 词典，并通过 inject face 把绑定的翻译函数和 locale 快照源交给该配置项，因此切换语言会重新渲染已挂载的编辑器。问题与选项文本来自模型并原样渲染；载体失败消息也不经翻译直接显示。

## 模型体验

通过 `dsh-tool-ask-user` 间接影响；该包拥有模型可见的工具 schema 和结构化结果。

#### KV Cache 影响

不会直接失效；模型可见的工具调用与结果由 `dsh-tool-ask-user` 拥有。

## 已知限制与暂缓事项

- **未提交的草稿不持久**：重新连接再同步或完整刷新页面时，会恢复主机拥有且 rpcId 相同的待处理请求，但编辑器卸载会重置本地选项和自定义文本草稿。
- **每次只有一个请求拥有编辑器**：后续待处理请求仍留在会话快照中，并在较早请求解决后显示。
