Parent: #577
背景
这是父 RFC 的子任务 A,目标是先完成 ask_user 的后端闭环(工具 + Runtime + Gateway),不依赖 UI 先跑通。
当前系统缺少“结构化询问用户”能力,模型只能用文本提问,导致分支不可控、回合冗余、状态不可观测。
目标
实现 ask_user 的运行时协议闭环:
- Runtime 触发 ask_user 工具调用;
- Gateway 发出
user_question_requested;
- 客户端提交
user_question_answer;
- Runtime 收到回答后注入 tool_result 并继续执行。
范围(做什么)
1) 新增 ask_user 工具定义(internal tool)
- 工具名:
ask_user
- 类型:internal tool(仅 Runtime 可发起)
- schema(v1 最小集合):
question_id (string, required)
title (string, required)
description (string, optional)
kind (single_choice | multi_choice | text, required)
options[](choice 类 required)
required (bool)
allow_skip (bool)
max_choices (int, multi_choice)
timeout_sec (int, optional)
2) Runtime 等待态与恢复
- 新增 run 状态:
waiting_user_input
- 进入条件:ask_user 发起且等待回答
- 恢复条件:收到合法 answer 或超时策略触发
- 收敛条件:cancel/timeout/run end 自动清理 pending question
3) Gateway 协议动作
新增:
- 事件:
gateway.event(runtime_event_type=user_question_requested)
- 动作:
user_question_answer
user_question_answer 参数:
question_id
answer_type (single_choice | multi_choice | text | skip)
selected_option_ids[]
text
client_meta(可选)
4) 幂等与一致性
- 同
question_id 只接受一次有效提交(幂等)
- 重复提交返回幂等结果,不重复推进 run
- 超时策略可配置(默认
skip)
5) 可观测事件
新增或复用事件:
user_question_requested
user_question_answered
user_question_timeout
user_question_skipped
非目标(本 issue 不做)
- 不做 TUI/Web/Desktop 具体卡片 UI(放到子 B)
- 不做复杂表单引擎
- 不新增 provider 协议改造
- 不做跨会话长期问题队列
关键约束
- 不跨层直连:前端不得直接改 Runtime 内存状态。
- question_id 唯一:run 内唯一;非法重复必须拒绝。
- 结构化回灌:必须走 tool_result,不以自然语言代替。
- 无配置回归:未触发 ask_user 时行为不变。
实施建议(文件级)
按现有仓库结构微调文件名即可
internal/tools/askuser/:schema/validate/execute 协议定义
internal/runtime/...:run state、pause/resume、pending question 管理
internal/gateway/protocol/...:user_question_answer 参数与事件定义
internal/gateway/...:dispatch + 校验 + 转发
测试计划
- ask_user 请求发出后 run 进入 waiting 状态
- 提交合法 answer 后 run 恢复
- 重复 answer 不重复推进(幂等)
- 超时触发 skip/失败策略
- run cancel 时 pending question 被清理
- invalid question_id / invalid answer_type 正确报错
- 无 ask_user 场景全量回归不变
验收标准(DoD)
- 通过
go test 覆盖 Runtime/Gateway 新增路径
- ask_user 后端闭环可脚本化验证
- 协议文档字段齐全且与实现一致
- 不引入 provider/runtime 边界破坏
与父 RFC 关联
- Parent: ask_user 交互式能力 RFC(将在 parent issue 中回链)
Parent: #577
背景
这是父 RFC 的子任务 A,目标是先完成 ask_user 的后端闭环(工具 + Runtime + Gateway),不依赖 UI 先跑通。
当前系统缺少“结构化询问用户”能力,模型只能用文本提问,导致分支不可控、回合冗余、状态不可观测。
目标
实现 ask_user 的运行时协议闭环:
user_question_requested;user_question_answer;范围(做什么)
1) 新增 ask_user 工具定义(internal tool)
ask_userquestion_id(string, required)title(string, required)description(string, optional)kind(single_choice|multi_choice|text, required)options[](choice 类 required)required(bool)allow_skip(bool)max_choices(int, multi_choice)timeout_sec(int, optional)2) Runtime 等待态与恢复
waiting_user_input3) Gateway 协议动作
新增:
gateway.event(runtime_event_type=user_question_requested)user_question_answeruser_question_answer参数:question_idanswer_type(single_choice|multi_choice|text|skip)selected_option_ids[]textclient_meta(可选)4) 幂等与一致性
question_id只接受一次有效提交(幂等)skip)5) 可观测事件
新增或复用事件:
user_question_requesteduser_question_answereduser_question_timeoutuser_question_skipped非目标(本 issue 不做)
关键约束
实施建议(文件级)
internal/tools/askuser/:schema/validate/execute 协议定义internal/runtime/...:run state、pause/resume、pending question 管理internal/gateway/protocol/...:user_question_answer参数与事件定义internal/gateway/...:dispatch + 校验 + 转发测试计划
验收标准(DoD)
go test覆盖 Runtime/Gateway 新增路径与父 RFC 关联