Skip to content

feat(workbench): let the user start the Bot over - #6569

Open
liugddx wants to merge 1 commit into
rust-previewfrom
feat/bot-restart
Open

liugddx wants to merge 1 commit into
rust-previewfrom
feat/bot-restart

Conversation

@liugddx

@liugddx liugddx commented Nov 2, 2026

Copy link
Copy Markdown
Member

Summary

A Session's tool list is fixed at creation, so a Bot created by an older build never gains tools added later (this came up with #6528 and #6538). The Bot is also kept out of the conversation list, so the usual archive action does not reach it. The only way to get a new Bot was to edit the Host's data.

This adds a restart button to the Bot's own page header (shown only when the open conversation is the Bot). It asks for confirmation, then archives the current Bot, opens a new one with openBot, and switches to it. The Host already supports this (an archived Bot is replaced by openBot); this only adds the entry point.

  • Confirmation text: "This opens a new Bot. The current Bot is archived with its conversation. Its checklist and scheduled tasks are not carried over." Not carrying the checklist over is deliberate for now; migrating it is a separate step.
  • If archiving or opening fails, the error is shown in the dialog and the current Bot stays.
  • Header gets an optional actions slot; the button lives in a new BotRestart component so ui.tsx does not depend on it. Strings are added in English, Simplified and Traditional Chinese.

Notes for reviewers

  • I checked the button placement in a screenshot of the running desktop app (top right of the Bot page, next to the workspace chip). I have not clicked through the dialog or the archive-and-reopen path in the UI; the dialog follows the existing delete-confirmation pattern in SessionActions. A reviewer's manual check of that flow would help.
  • If the archive succeeds but opening the new Bot fails, there is briefly no active Bot; the next press of "Maka Bot" opens one.

Test plan

  • UI type check as CI runs it (ui_types + tsc), biome, workbench tests (77)
  • button visible on the Bot page in the running app
  • confirm dialog, archive and reopen, checked manually

🤖 Generated with Claude Code

A Session's tools are fixed when it is created, so a Bot made by an older build
never gains the tools of a newer one, and the Bot sits outside the conversation
list, so the usual archive action does not reach it. The only way to get a new
Bot was to edit the Host's data.

The Bot's own page now has a restart button in its header. After a
confirmation it archives the current Bot, opens a new one and switches to it.
The confirmation says the checklist and scheduled tasks are not carried over.
A failure is shown in the dialog and leaves the current Bot in place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@M4n5ter M4n5ter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

English

Could we discuss whether replacing the Bot session is necessary to solve the tool-upgrade problem?

The current approach creates a fresh session without transferring conversation context or a handoff summary, and deliberately leaves the checklist and scheduled tasks behind. That makes sense for an intentional reset, but seems costly when the user only needs tools added by a newer build.

I also found two concrete issues in the current flow:

  1. Recovery after partial failure does not work as described. If archiving succeeds but openBot fails, botSession retains the archived ID. Clicking “Maka Bot” then reopens that session instead of calling openBot again.

  2. The archived Bot’s original replies are no longer displayed correctly. Once a new Bot is registered, reopening the old session identifies it as ordinary and does not load its SendUser transcript. botOutbox only reads the currently registered Bot. The records remain in storage, but the archived conversation no longer presents the replies previously shown to the user.

One alternative worth exploring would be to keep the existing Bot session and derive its tools from the current configuration. For example:

  • The Host could select from the existing Bot coordination-tool list and the tools available in the current composition.
  • A new Turn could receive the current tool set, while already prepared or running executions retain their original snapshots.
  • The Bot’s creation-time tool list might then be removable as redundant derived state, while ordinary sessions keep their explicit tool restrictions.

This would preserve context, checklist, scheduled tasks and worker relationships without a migration. It is my current preference, but I may be missing a reason why the Bot’s tool list needs to remain fixed for the lifetime of its session.

Is that lifetime restriction intentional and necessary? If replacing the session is required, could we consider a context handoff instead? Existing fork/history-copy support may provide a starting point, although it does not by itself transfer Bot identity, outbox history or task ownership.

If the goal is also to offer an explicit “start over” feature, that seems worth distinguishing from tool upgrades so users can choose whether to discard continuity.

The two failure paths were checked through source tracing and focused behavior probes; the existing transcript tests passed, but a complete native desktop workflow was not exercised.

简体中文

想先讨论一下:为了解决 Bot 工具升级的问题,是否有必要更换整个 Bot session?

当前方案创建一个空的新会话,没有传递对话上下文或移交摘要,并且明确不迁移待办和定时任务。如果用户就是想清空重来,这可以理解;但如果只是想获得新版新增的工具,这个代价似乎偏大。

另外,当前流程存在两个确定的问题:

  1. 部分失败后的恢复方式与描述不符。 归档成功、openBot 失败时,botSession 仍缓存旧归档会话的 ID。此后点击“Maka Bot”只会重新打开旧会话,不会再次调用 openBot。

  2. 归档后的旧 Bot 回复展示不完整。 新 Bot 注册后,重新打开旧 session 会将它识别为普通会话,不再加载原来的 SendUser 发言;botOutbox 也只读取当前注册的 Bot。记录仍在存储中,但归档会话无法正常呈现用户之前看到的回复。

一个值得讨论的替代方向是:保留现有 Bot session,根据当前配置确定工具集合。例如:

  • Host 可以从现有 Bot 协调工具清单和当前 composition 实际提供的工具中选择。
  • 新 Turn 使用当前工具集合,已准备或正在执行的任务继续保留原快照。
  • 这样或许就不需要永久保存 Bot 创建时的那份工具名单;普通会话显式设置的工具限制仍保留原有语义。

这个方向可以保留上下文、待办、定时任务和 worker 关系,避免迁移。目前我更倾向于它,但也可能遗漏了“Bot 工具名单必须在整个 session 生命周期内保持固定”的理由。

这个限制是否有意为之,又是否确实必要?如果必须更换 session,是否可以考虑移交上下文?已有 fork/历史复制机制可能提供基础,但它本身并不处理 Bot 身份、独立发言记录或任务归属的转移。

如果还希望提供用户主动“清空重来”的功能,我觉得可以与工具升级区分开,让用户决定是否放弃连续性。

上述两条失败路径已通过源码追踪和定向行为检查核对;既有 transcript 测试已通过,但尚未实际运行完整原生桌面流程。

@github-actions github-actions Bot added the effort/M Under 500 readable lines label Nov 3, 2026
@liugddx

liugddx commented Nov 3, 2026

Copy link
Copy Markdown
Member Author

Thanks for tracing this, and sorry for the late reply. Both failure paths are real, and I agree the PR mixes two different things.

  • Tool upgrade. Replacing the Bot is the wrong tool for this. The fixed tool list is not something the Bot needs for its whole life. I froze it because ordinary Sessions do, and queue.rs rejects a prepared execution whose Session tools no longer match its snapshot. That check is also what keeps in-flight work on its original snapshot, so a refresh has to happen only while the Bot is idle. I'll try your direction: when the Bot is opened, and also before a new Turn is prepared, derive its tools from COORDINATION_TOOLS and the current composition, and write the result back only when it differs and nothing is queued or running. That keeps context, checklist, schedule and workers.
  • Start over. I'll keep it as its own, explicit action and drop the "upgrade" framing. For the two bugs: a failed openBot after archiving should clear the cached ID so the next click calls openBot again, and an archived Bot should keep showing its SendUser transcript.

I haven't confirmed that the refresh is safe against the admission checks yet. I'll first write it as a test against queue.rs, then update this PR, or split it into two if the first turns out cleaner. Tell me if you would rather have the start-over button removed from this PR entirely.

简体中文

感谢追查,也抱歉回复晚了。两条失败路径都成立,而且我同意这个 PR 把两件事混在了一起。

  • 工具升级:用换 Bot 来解决是不对的。Bot 并不需要在整个生命周期里固定工具名单;我固定它只是因为普通会话都这样,而且 queue.rs 会拒绝“会话工具与快照不一致”的已准备执行。这条检查同时也保证了进行中的任务保留原快照,所以刷新只能在 Bot 空闲时进行。我会按你的方向试:打开 Bot 时、以及准备新一轮之前,根据 COORDINATION_TOOLS 和当前 composition 重新推导工具;仅当结果不同且没有排队或运行中的任务时才写回。这样上下文、待办、定时任务和 worker 都保留。
  • 重新开始:保留为独立、明确的操作,去掉“升级”的说法。两个问题:归档后 openBot 失败时要清掉缓存的 ID,下次点击才会重新调用 openBot;归档的 Bot 要继续显示它的 SendUser 记录。

刷新在准入检查下是否安全,我还没有确认。我会先对着 queue.rs 写测试,再更新这个 PR;如果第一部分更干净,就拆成两个 PR。如果你更希望这个 PR 里完全不要“重新开始”按钮,请告诉我。

@M4n5ter

M4n5ter commented Nov 3, 2026

Copy link
Copy Markdown
Member
English

Thanks @liugddx, this sounds closer to the distinction I had in mind in your reply. I'd prefer splitting tool upgrades and “start over” into separate changes, with the upgrade work first. Starting a new conversation is a valid explicit choice, but it shouldn't be necessary to gain newly available tools.

For tool upgrades, could we derive the effective tools at admission and freeze that result for the accepted work, rather than maintain a Session-level mirror that is written back while idle?

The existing MessageBasis already captures accepted prerequisites. The queue.rs comparison is a real constraint in today's implementation, but I don't think it establishes a product requirement to freeze the Bot's tools for its whole lifetime or wait for its entire queue to empty. I'd distinguish ordinary Sessions' explicit tool restrictions from the Bot's policy-derived tool set, and adjust the validation around that distinction—not simply remove the checks or set tools to unrestricted.

Concretely, new admissions would derive the Bot's tools from COORDINATION_TOOLS and the captured current composition. The model's tool catalog and standing instructions should use that same result. This needs to cover ordinary submissions, scheduled wakes and notification-driven work, not just opening the Bot page. Already prepared, queued, running or parked work should retain its accepted basis, subject to the existing permission and capability/revision checks; draining a queue or resuming parked work should not silently adopt newer grants. That seems simpler than adding another synchronization mechanism for a redundant persisted list. Is there an admission invariant that would prevent this arrangement?

For “start over,” clearing the cached ID alone doesn't complete the recovery path. In commandBot, a cleared value falls back to refreshBotSession(). If archiving succeeded but openBot failed before replacing the registration, botOutbox can still return the archived ID. The focused replay after clearing the cache still reopened the old session without calling openBot. Would it be simpler for the Bot entry point to let the Host's existing openBot resolve the current-versus-archived state, leaving the cache for presentation rather than that decision?

The old transcript also needs a read path independent of the current registration. Right now transcript identity treats the old session as ordinary once another Bot is registered, and botOutbox only addresses the current Bot. Historical SendUser records should be readable by the viewed Session's stable identity. That must remain separate from granting current Bot authority: reading an archived Bot's replies must not give it SendUser/sleep privileges again.

We're not at the stage where I'd recommend adding backward-compatibility branches for old Bot records. I'd rather update the internal model directly. If existing development data needs a one-off adjustment, a small verified migration gist, linked from an appropriate place such as the PR body, would be fine; it doesn't need to become a second runtime path.

For verification, I'd focus on the tools actually offered to the model, preservation of already accepted snapshots and ordinary Session restrictions, and—if the reset feature is kept—the next click after partial failure and the archived conversation's visible replies. The Maka-assisted checks at 3003bda9 passed all 14 existing transcript tests and reproduced the cache/history paths above, but those tests do not cover these reset requirements, and no complete native desktop flow was exercised.

简体中文

感谢回复,这样区分更接近我之前的意思。我倾向于把工具升级和“重新开始”拆成两个改动,先解决工具升级。用户主动开始一段新对话是合理的独立选择,但不应该为了获得新增工具而被迫这样做。

工具升级这部分,能否在准入时推导有效工具集合,并为已接受的工作冻结这次结果,而不是再维护一份需要等空闲时写回的 Session 镜像?

现有的 MessageBasis 已经捕获了被接受工作的前提条件。queue.rs 的比较 确实是当前实现的约束,但我不认为它能证明“Bot 整个生命周期必须固定工具”或“必须等整个队列清空才能升级”是产品需求。我更倾向于区分普通 Session 的显式工具限制和 Bot 根据策略推导出的工具集合,再围绕这个区别调整校验,而不是直接删检查,或把 tools 改成不受限制。

具体来说,新准入的工作根据 COORDINATION_TOOLS 和本次捕获的当前 composition 推导工具,模型实际拿到的工具目录和 standing instructions 使用同一份结果。这里需要覆盖普通发送、定时唤醒和通知触发,不只是打开 Bot 页面。已经准备、排队、运行或挂起的工作保留其已接受的 basis,同时继续遵守现有权限和 capability/revision 校验;消费队列、恢复挂起工作时,不应悄悄采用新授予的工具。这样似乎比给一份冗余的持久化名单再加同步机制更简单。准入契约里有没有哪条不变量会妨碍这种组织方式?

“重新开始”的恢复路径,只清掉缓存 ID 还不够。 commandBot 遇到清空的值后,仍会通过 refreshBotSession() 查询。如果归档成功,而 openBot 在替换注册记录之前失败,botOutbox 仍可能返回旧归档 ID。定向回放里,清缓存之后还是打开了旧会话,没有调用 openBot。能否让 Bot 入口统一由 Host 现有的 openBot 判断当前会话是否仍可用、是否需要替换,缓存只服务展示,不再承担这个决定?

旧对话也需要独立于当前注册记录的历史读取路径。目前一旦注册了新 Bot,transcript 的身份判断 就会把旧会话视为普通会话,而 botOutbox 又只读取当前 Bot。历史 SendUser 记录应该能按被查看 Session 的稳定身份读取。这个能力应与当前 Bot 的权限分开:能查看归档 Bot 的旧回复,不意味着重新赋予它 SendUser/sleep 权限。

现阶段还不建议为旧 Bot 记录增加向后兼容分支,我更倾向于直接更新内部模型。如果现有开发数据需要一次性调整,可以提供一个实际验证过的迁移 gist,在 PR body 等合适位置放链接,不必因此在运行时永久保留第二条路径。

验证上,我会重点看模型实际获得的工具、已经接受的快照和普通 Session 限制是否保持,以及——如果保留重置功能——部分失败后的下一次点击能否真正恢复、归档对话能否显示原回复。这次由 Maka 辅助核对的 3003bda9 上,现有 14 个 transcript 测试全部通过,也复核了上面的缓存和历史路径;但这些测试没有覆盖上述重置要求,完整原生桌面流程也还没有实际验收。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/M Under 500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants