问题
bot 通过 ask_user 抛出带按钮的问题后,如果用户不点按钮、直接在输入框手打一条自由文本(非常自然的反应,比如问题是「以哪个时刻为终点?」,用户直接回「0点」),这条消息目前的归属是未定义的:
期望行为(候选,需要产品决策)
- 自由文本视为对当前 pending 问题的作答:单选匹配选项/编号,
allow_custom 时作为自定义答案,文本题直接作答——与 plain-text 回退(AdvanceText)同一语义,只是扩展到 native 渠道。最符合用户直觉。
- 新消息打断挂起的 run(取消 pending 问题、supersede 旧 turn,以新消息开新 turn)。
- 至少:busy 时给用户一条可读提示(「还有一个待回答的问题」+ 重新展示卡片),而不是静默或 RPC error。
背景
问题
bot 通过
ask_user抛出带按钮的问题后,如果用户不点按钮、直接在输入框手打一条自由文本(非常自然的反应,比如问题是「以哪个时刻为终点?」,用户直接回「0点」),这条消息目前的归属是未定义的:internal/channel/inbound/user_input_plain_text.go:26对 NativeUserInput 直接跳过);StartTurn,但挂起的 run 以 waiting_decision 占着 session 唯一活跃槽,admission 拒绝(ErrSessionBusy;split 模式下还会因 [Bug]: split 模式 gRPC turn 边界丢失 ErrSessionBusy 哨兵,session 占槽被报成 Internal RPC error 发给用户 #1153 变成 Internal RPC error 糊脸);期望行为(候选,需要产品决策)
allow_custom时作为自定义答案,文本题直接作答——与 plain-text 回退(AdvanceText)同一语义,只是扩展到 native 渠道。最符合用户直觉。背景
internal/agent/decision/input/plain_text.go的AdvanceText)已经实现了完整的文本作答状态机(编号匹配/自定义答案/skip/back),目前只对非 native 渠道开放;native 渠道把这个能力让渡给了按钮——但按钮覆盖不了「用户直接打字」这个真实行为。askUserTextPrompts)只绑定「点了 Other…/Fill answer 之后的回复」,不覆盖主动打字。