Files
goodbuddy/docs/features/assistant-workbar/runtime-interactions.md
T
mesalogo 9836a4cc9d
GoodBuddy Agents / Validate Agent source (push) Canceled after 0s
GoodBuddy Agents / Build darwin arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux arm64 Agent (push) Canceled after 0s
GoodBuddy Agents / Build linux x64 Agent (push) Canceled after 0s
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s
fix: keep question order and streamline contextual help
Keep interactive questions and answered cards at their original position in
conversation history, including remote reception, recovery, and reopening.
Preserve legacy history placement without a database migration.

Move supplementary guidance into shared accessible contextual-help popovers
across pages and settings. Add keyboard, modal, accessibility, and Electron
regressions, plus bounded opt-in live canvas-analysis validation.

Remove unused Agent, Runtime, and in-memory graph-search helpers, obsolete
mocks and browser copy; reuse the existing package-size formatter. Keep
production execution paths, protocol schemas, and released data migrations.

Validation: targeted cleanup tests, typecheck, lint, shared Linux Host
attach/read/re-attach, and added help/Electron checks passed. Final full-suite
verification passed 4,858 tests with 67 skipped and zero failures (412 files
passed, 9 skipped). Focused help checks passed 54 tests, including Electron
style comparisons and Chromium accessibility descriptions. Details and
validation boundaries are recorded in feature docs.

Release note: 修复交互式问答在回答后排到后续输出末尾的问题,重新打开会话仍保留提问位置。页面和设置中的补充说明改为标题或字段旁的按需帮助,支持鼠标与键盘操作。
2026-09-20 01:26:36 +08:00

17 KiB
Raw Blame History

Runtime 交互边界

本文定义当前原生交互的适配范围,不增加工作模式或第二层 Execute 审批。

Runtime 权限确认 业务问答
本机 GoodBuddy 管理的 OpenCode 内部默认配置允许权限;每个 Ask 请求仍使用 deny-all 与显式只读能力。Execute 自动回复属于当前请求的父、子孙会话权限事件,不处理其他并行请求 通过 question.asked 转交父、子孙会话问题,支持原生单选、多选、yes/no、自由文本及跳过;使用公开 ID 回传 question.reply/reject
托管 SSH OpenCode Agent 按已接受 Prompt 的 Ask/Execute 模式处理 ACP 权限,规则见远程主机技术设计 当前 Agent 插件转交原生父、子孙会话 question.asked;前台使用同一问答队列,回答和跳过经认证 Agent 控制通道回传,已知 Task 关联显示子任务归属
Continue Execute 启动传入 --auto,剩余原生权限请求按当前模式自动答复 对接 1.5.47 QuizService 的扁平 pendingQuestion,其中 question 是字符串。选项回答与自定义文本分别回传正确的 isCustomAnswer;跳过发送拒绝回答的文本
DeepSeek Harness 固定 Host 的 Execute 文件与命令工具不询问目录权限;若收到 ACP 权限请求,活跃 Execute 直接选一次性允许,缺少该选项时使用 Runtime 提供的允许选项,Ask 拒绝,不等待额外 authorizer 固定 Host 当前未提供通用原生业务问答服务,不把普通模型正文误识别成待答协议。模型以普通回复提问时,用户通过下一条消息回答

托管 SSH OpenCode 的权限、原生问题事件与回复链路由 远程主机技术设计定义。该远端业务问答基线需要 Desktop 0.13.0、Agent 0.11.24 和新启动的托管 Runtime;请先升级 Desktop,再更新 Host 环境。2026-09-14 的已发布 Desktop 0.13.2 / Agent 0.11.25 已包含此前问答修复, 但不包含本文末尾尚未发布的进程复用改动。任意第三方 ACP 服务及旧 Agent 不因此获得通用问答接口。

运行与失败

  • 结构化 yes/no 是普通选项,不从日志、自然语言或 Shell 输出猜测用户意图。
  • 前台同一请求的待答问题按公开 questionId 去重,按到达顺序保存在消息的 pendingQuestions 中。每次显示队首表单;有多个待答请求时显示数量。后续提问和重复 事件不替换当前表单或清空输入,回答或跳过成功后只移除对应 ID,再显示下一张表单。 提交失败保留队列、输入和重试入口,队列未清空时继续显示“等待你的回答”。
  • 本机与托管 SSH OpenCode 在提问到达前已收到原生 Task 的 metadata.sessionId 时,将精确匹配的 子会话关联为可选 childTaskId。问答卡片显示该任务名称;对应 Task 卡片显示 “等待你的回答”,展开后可点击“前往问答表单”滚动并聚焦当前队首表单,仍按顺序回答。 没有已知关联的子孙会话问题照常排队,不猜测子任务归属,也不从工具名或进度文本构造表单。
  • 回答或跳过成功后,会话保留只读的“问题与回答”,显示原问题及对应的选项答案、 自定义文本或“已跳过”。同一任务的多轮问答逐次保留,随本地会话保存,重新打开后仍可查看。 提交失败时保留输入与重试入口,不生成已回答记录;取消未回答的问题不记为主动跳过。
  • 新消息在提问到达时,将只含 questionId 的问题位置块插入当时的消息块序列; 待答和回答后的卡片使用同一位置,后续正文、工具输出不再排到问题前面。重复问题不追加 或移动位置块。位置块不保存待答表单;旧会话没有位置块时保留原有问答展示,不推测或 回填历史顺序。该变更复用既有消息元数据,不升级数据库 schema。
  • 提交响应晚于任务结束时仍保存已提交的问答,但不覆盖完成或失败状态;晚于下一轮提问时 不清除新的待答卡片。旧版会话未保存的问题与答案无法从“已提交”状态文案恢复。
  • 待答队列仅保存在当前桌面会话内存中,不写入持久会话快照。刷新仍在运行的消息时保留整个 本地队列;完成、失败、取消事件或持久化终态快照清除整个队列。迟到的提交结果可以保存 已回答记录,但不会恢复表单或覆盖终态。本机 Runtime 不恢复重启前未提交的问题;托管 SSH 重新附加同一存活 Agent Prompt 时,由 Agent 当前待答列表补发问题,已回答的历史事件不补发。
  • 未发布的进程复用源码在 Desktop 重启后由 Main 并行附加同项目的存活任务,将待答 列表和 Stop 所需的请求 ID 投影到实时 activeRequest,不保存该字段或重新发送任务。 回答/跳过成功由 Main 写回原远程助理消息的既有问答历史,Renderer 不覆盖远程正文或终态。 Main 在前台与恢复请求收到实时问题时立即保存位置块;实时待答快照没有语义事件来源, 不伪造来源或追加 transcript。带来源的提问事件仍通过既有事务投影并按问题 ID 去重。 Runtime 设置、定制和能力更新让旧请求在原配置上结束,已有问题仍可回答;新请求使用 新配置。专家团队例外:既有专家调度器在设置替换时取消子任务,团队父请求也随之停止, 不使用替换后的模型汇总旧结果。详细实现见 恢复与终态投影。
  • 后台任务收到结构化提问时,通过现有 Main 路径明确失败并提示改为前台对话,不永久等待。
  • 请求结束或取消后清除对应待答映射;过期回答明确报错,不转交给后来的请求。
  • 任意终端程序的密码、OAuth 登录、许可证确认或 stdin 提示不自动回复 yes。这类程序应 使用其非交互参数,或由用户在终端完成;不能把权限确认和业务决策混为一谈。Shell 工具保留其现有取消与超时,不新增日志解析或通用交互代理。

托管 Runtime 的并行与输出

子任务完整过程的显示与数据库差量存储相互独立,本机和托管 SSH 共用桌面存储层; 旧库升级与空间回收规则见执行记录存储与升级回收。

  • 本机和 Agent 管理的 OpenCode 启动配置都显式设置 snapshot: false。GoodBuddy 不消费 原生自动 Git 快照、快照差异摘要或快照撤销;关闭这条内部路径,避免大行级差异的同步 计算阻塞同一原生进程中的其他会话。
  • 文件工具、Shell、原生子代理、工作区 Git 状态和单文件差异保持可用;不新增全局会话 队列、请求重放或总执行截止时间。外部 OpenCode Server 的配置不由 GoodBuddy 改写, 已运行的旧原生进程也不会热更新配置。
  • Continue 使用 HTTP 传递响应和状态;Electron UtilityProcess 启动后持续排空不用展示的 stdout,避免控制台输出填满管道后阻塞宿主。stderr 的有界错误处理、请求取消与进程 回收保持不变,不把诊断输出复制进聊天或持久日志。
  • 远端最终启动配置由远程主机技术设计定义, 模型桥生成最终配置时同样保留上述快照策略。

工具操作摘要

工具记录沿用 UI 设计系统的折叠布局。Continue、DeepSeek Harness 和直连模型共用 toolOperationSummary:优先使用有效原生标题,否则从参数提取命令、 文件路径、搜索条件或 URL,合并空白后最多显示 240 字符。无法识别时保留原有工具名 回退规则;文件正文、整份参数 JSON 不进入标题,参数详情仍可展开查看。

Continue 在宿主截断输入前提取摘要,流式完成与失败事件使用合并后的输入和摘要。 DeepSeek Harness 按调用 ID 保留名称、输入和摘要,结束事件省略输入时仍能显示操作内容。 直连模型从原始参数生成一次摘要,在待执行、执行中和完成时复用;审批失败、拒绝和 执行失败、刷新重试仍保留已有提示。

本机 OpenCode 沿用原生操作标题。远端 ACP 独立使用原生标题作为记录名称,不经过上述 本地转换,本次没有修改 Agent、远程桥或协议。

消息底部请求状态

  • 状态属于当前请求,不与顶部 Runtime 的连接中、就绪、不可用混为一谈。提交后先显示 “正在准备请求”;没有更具体的活动事件时显示“等待后续进展”,不声称模型正在思考。
  • 本机 OpenCode 只把当前父会话的 session.status.retry 映射为等待重试,显示原生 attempt、计划重试时间和有界脱敏原因;后续 busy 才显示已开始重试。其他会话的 状态不串入当前消息,不猜测总重试次数,不把 SDK 事件流重连当作模型重试。
  • 显示优先级为待回答、待确认、进行中的上下文压缩、明确的请求状态、待执行或执行中的 工具、未完成的子任务、等待后续进展。压缩沿用已有活动块,不重复增加底部提示。 正文、推理或工具进展会清除旧状态;子任务更新不覆盖父请求的重试提示。
  • 完成、失败、取消后保留真实终态,迟到的状态事件不能把请求恢复成处理中。底部状态点 为静态,不凭请求尚未结束暗示仍有进展;会话列表闪点和发送、停止按钮保持原有行为。 持久化快照中的同一条消息仍为生成中时,也不能覆盖本地已收到的终态,即使快照的 会话更新时间更晚;否则连续发送或刷新会让已结束的请求重新显示停止按钮。
  • Continue、DeepSeek Harness 和远端 ACP 保留其已接入的处理与工具事件,不伪造未接入 的原生重试状态。直连模型的重试等待与请求开始文案见 直连模型 UI 设计;本次不改变任何 Runtime 的重试上限、请求重放或取消策略。

实现与真实 Runtime 验证证据见进度记录。

Runtime 执行清单

本节为未实现的状态设计,对应 FR-CL1–FR-CL4、US-CL1–US-CL5。 原始格式和传递边界由技术设计维护。

清单属于一次请求及其助手消息。沿用项目、执行空间、Conversation、Runtime 选择和 原生 Session 到请求的既有映射;远端还需核对 binding/operation。不能仅以原生 Session 或 Conversation 为键更新顶部,因为同一会话会连续执行多轮请求。

输入或操作 清单与顶部行为
本轮尚无有效清单 隐藏顶部清单,不复制上一轮内容
收到本轮有效完整清单 按原生顺序整体替换,包括修改、删除、重排和重复文本;不按条目文本合并
收到有效空数组 记录明确清空并隐藏;空数组与缺少清单字段不同
CN 调用进行中 候选只按该请求的调用 ID 暂存;成功后才提交完整替换
CN 调用失败、取消或格式无效 丢弃该候选,保留上次有效清单,工具记录保留实际结果
请求完成、失败、取消或中断 冻结最新已提交清单,并显示请求真实结果;不推断条目完成,迟到输入不改写已结算清单
同一会话开始下一轮 顶部转向新请求,上一轮清单留在原消息;旧轮事件不得归入新轮
切换会话、项目、执行空间或 Runtime 只读取目标归属的数据;原请求在原归属结算,不把原清单标为新 Runtime 的进度
查看历史或重连 从原消息及既有事件恢复;按原请求和远程来源顺序去重,不能用最新原生 Session 快照覆盖历史轮次

条目状态支持 pending、in_progress、completed、cancelled。OC 原生提供的 priority 保留; CN 未勾选项映射为 pending,已勾选项为 completed,不推断 in_progress 或 priority。 OC 无稳定 item ID,视图索引仅服务本次完整列表渲染,不生成跨更新的条目身份。

清单内容不创建、调度或完成产品 Task,也不改变底部请求状态。清单更新与工具活动可以 同时保留,但顶部计数只来自已确认的结构化清单,不能反向解析普通状态文本、任意 Markdown 或名称含 list 的工具。子会话清单不覆盖父请求顶部。

以上产品状态规则已明确;远程 CN 接入、原生格式确认及历史字段选择仍属技术待办,见 进度记录。

Runtime 资源生命周期

本节对应 FR-RR1–FR-RR6、US-RR1–US-RR4, 定义进程复用的行为规则。当前源码已接入本机共享 owner 和 Agent 共享 ACP; 完整验收状态以进度记录为准,不表示已发布。 具体 owner、兼容键和协议实现见技术设计。

资源有三个独立维度:进程是否启动/退役,会话是否仍持有原生上下文,请求是否在途。 “任务完成”“当前没有选中该项目”“工作栏关闭”均不能直接推导进程可以销毁。

触发 请求与会话行为 进程行为 对应需求/场景
被动状态读取 不取得新执行会话,已有状态可读取 不冷启动,不延长无会话 owner 的空闲期限;不为探测替换服务中的进程 RR2 / US-RR1
显式测试/原生清单 取得临时检查引用;清单带明确工作区 与执行共用启动 Promise 和 owner;结束只释放检查引用 RR1、RR2 / US-RR1
首次或并行 Prompt 取得对应 execution space + conversation 的绑定 同兼容组复用,非兼容组分别启动 RR1、RR3 / US-RR1、RR2
普通请求完成 释放请求订阅、临时 token、问题和 callback,保留可续聊 Session 不因为一个请求完成关闭整个进程 RR3、RR4 / US-RR3
取消一个请求 取消其模型/工具调用并结算,其他会话继续 不以 kill 共享进程代替正常会话取消 RR3、RR4 / US-RR2
关闭面板/切换项目 停止非必要 UI 推送;不取消后台任务或抹掉会话所有权 不触发隐式关闭 RR4 / US-RR3
显式释放/删除会话 释放该 Session 与会话工具资源;删除历史仍只由原有明确删除操作决定 其他引用仍在则保留 RR4 / US-RR3
无会话、无请求、无检查引用 不存在需要保留的原生上下文 进入短空闲等待,再关闭;新使用者到来取消等待 RR4 / US-RR1、RR3
配置替换 已接受请求使用旧配置结算,新请求使用新配置 旧 owner 排空后退役;不积累只被历史 ID 持有的旧配置进程 RR1、RR4 / US-RR4
进程故障/不可响应 只给该 owner 下受影响请求明确中断;未知结果不自动重放 有界终止失效 owner,不伪造逐会话故障隔离 RR3、RR4 / US-RR2、RR4
SSH detach 保留 Agent 已接受 Prompt 及既有恢复归属 关闭传输不关闭 Agent 或活动 Runtime RR5 / US-RR4

表中 RRn 是 PRD 稳定需求 ID FR-RRn 的简写。

不变量:

  1. 一条请求始终使用接受时的 execution space、工作模式、配置和归属;不能读取后来 切换的 UI 选择,也不以进程 cwd 表示所有会话的 cwd。
  2. 同一会话串行,跨会话不增加全局 Prompt 队列。权限、子代理、问题、用量和最终清理 必须沿同一 Session/请求归属,不因共享进程放宽 Ask 或限制 Execute。
  3. owner 的退出条件依据所有使用者,不依据某个 adapter 的空闲状态。 未启动对象的 dispose 不产生冷启动;一个等待者取消不取消其他等待者的初始化。
  4. 正常会话仍持有原生上下文时,不用任意 TTL 清掉它来声称“空闲内存已回收”。 无会话 owner 的短空闲等待为 60 秒; 不增加用户配置项。它是进程引用回收,不是聊天历史保留期限。
  5. 持久历史不因请求结束、进程 idle、配置变化或测试 cleanup 被删除。 原生进程确实重启后的续聊沿现有历史重建规则,不新增第二套持久会话快照。

已明确普通并行、取消、释放、配置替换及断线行为。各项实际通过的场景及尚未完成的 组合/性能验证以进度记录为准。