Nexus 的 Room 与 Runtime 怎样接在一起
Room 保存协作事实,Runtime 保存执行过程。Nexus 如何用 Host、Bridge 和独立 session 把两边接起来。
聊到 Nexus 的 Room,常会碰到两个问题。
同一个 Room 里的 Agent,能不能分别跑在不同机器上?Room 里 @ 一个 Agent,系统里又发生了什么?
这两个问题可以放在一起看。Nexus 把 Agent 在哪里运行、什么时候运行,与 Room 保存的协作事实分开了。

Web、桌面端或外部 IM 发来的消息,最终都会进入 Nexus Host。Client 只负责交互,不决定哪个 Agent 该执行,也不管理 Agent 进程。Room、成员关系和协作状态都由 Host 持有。
Room 不等于 Agent session
一个 Room 里可以有真人,也可以有多个 Agent。Room 本身不属于其中任何一个 Agent。

Planner 可能正在运行,Coder 还没有启动,Reviewer 的 Runtime 也可能已经退出。它们仍然是 Room 成员。成员关系、公共消息和交接状态留在 Host,不会寄存在某个 Agent 的模型上下文里。
假设 Planner 把一件事交给 Coder。
Planner
这个方案基本没问题。
@Coder 看一下缓存这一块有没有并发问题。
如果 Room 只是 Planner session 里的一段上下文,Planner 结束以后,接下来该谁继续便没有可靠的系统状态。
Nexus 会先把 Planner 的最终回复写成 Room 的公共记录,再从有效的 @Coder 提及里建立一次 handoff。Agent 没有直接启动另一个 Agent。它向 Room 留下一条带有明确目标的消息,Host 再处理目标 Agent 的在线状态、Runtime 和 session。

一次 @ 包含消息和唤醒
@Coder 看一下这个实现 至少留下两件事。
第一件是通信事实。Planner 向 Coder 提出了请求。
第二件是调度动作。Coder 应当获得一次运行机会。Nexus 把这个动作叫作 wake。
message ≠ wake
Wake 自己不构成消息,也不会修改已经存在的公开或私域上下文。消息可以已经写入,但 Agent 暂时不运行。Agent 也可能因为延迟唤醒、任务分派或定时任务获得运行机会。
把两件事分开以后,谁说了什么与谁此刻应该执行就不会绑死在一起。
Room 保存协作事实
多 Agent 系统若把每个 Runtime 的完整记录都拼进公共历史,上下文会迅速膨胀,权限边界也会变得含糊。
Nexus 的 Room 因此分出 public feed 和 private context。用户公开消息、Agent 已完成的最终回复,以及明确发到当前 Room 的公开消息会进入 public feed。下面这些运行中间态不会自动变成其他成员的公共历史。
thinking
tool_use
stream 中间状态
runtime result
未完成输出

Coder 可能为了确认一个锁的问题读了几十个文件,执行了十几个工具,产生很长的 Runtime transcript。Reviewer 下一次被唤醒时,不必继承这段完整过程。它需要看到 Coder 已经带回 Room 的结论,以及继续工作所需的公共上下文。
Room 保存协作结果,Runtime 保存执行过程。两类状态的用途和增长速度不同,放在一起反而会让两边都难以维护。
一个 session 可以运行多个 round
Host 和 Runtime 之间也不只是一次 prompt 对应一个临时进程。
Session 是 Agent 持续存在的执行上下文。Round 是这个 session 里的一次具体执行。Runtime manager 单独登记正在执行的 round,并维护取消、完成和中断状态。一个 round 结束,session 仍可留下来。

Coder 第二次收到消息时,可以恢复原来的 session。Host 会先准备这一轮需要的历史、权限和 Room 上下文,再创建 Runtime client,把 round 登记进 manager,随后开始执行。

Host 管的是完整的执行生命周期。模型调用只是其中一步。
Bridge 留住可替换的边界
Nexus Host 与 Runtime 之间还有一层开源的 nexus-agent-sdk-bridge。
当前 Nexus 默认使用 nxs,也可以接入 Claude Code。Host 通过同一套 Go API 使用它们。Bridge 负责 session、流式消息、运行控制、权限和 Hook 等协议能力,不实现 Agent loop,也不包含模型 Runtime。
Runtime 会声明自己支持的 Capability,Host 按协商结果启用对应能力。它不会看到 Runtime 名称以后猜测行为。一个 Runtime 可以支持 session fork,另一个可以不支持;差异留在公开契约里,不需要一路渗进 Room 代码。
这条边界也让开源 Product 与闭源 nxs 保持清楚的依赖方向。Product 只依赖 Bridge,不导入 nxs 内部的 Go SDK。
Room round 与 Runtime round 各管一层
代码里有两个容易混淆的 round。
Room 这一层关心消息触发了哪些 Agent、多个目标怎样排队、回复回到哪里。Runtime 这一层关心某个 session 有没有执行中的 round、怎样取消、何时结束。
Room 会为不同 Agent 建立各自的 slot。每个 slot 再绑定自己的 Runtime session 和 Agent round。

Room 可以让多个 Agent 同时推进。同一个 Agent 收到多个 handoff 时,目标 slot 仍按顺序运行。否则两个 Room 同时叫到同一个 Agent,两段执行一起修改它的 Workspace,很快就会撞上文件和上下文竞争。
Room 的并发与 Runtime 的并发因此可以分开处理。
Handoff 必须留下来
一次 @ 不能只存在于内存队列里。Host 如果刚收到 @Coder 就重启,这次交接也得继续。

Nexus 为 handoff 保存持久记录,并把目标终态与后续 handback 分成独立阶段。某一步刚完成、下一步还没有开始时,即使 Host 退出,恢复流程也能知道该从哪里接上。
从这里看,Nexus Host 更像一套协作 Runtime。前端看到的是消息,Host 维护的是消息、handoff、wake、queue、slot、Runtime session 和 reply route 之间的关系。
Agent 能不能跑在另一台机器上
从架构边界看,可以。
Host 依赖的是一条满足 Bridge 契约的 Runtime connection。Bridge 已经支持本地 Runtime,也提供 direct connect 和宿主管理 transport 的入口。

真正把 Runtime 放到另一台机器上,还要处理注册、身份绑定、session 恢复、断线终态、Workspace 位置、取消投递和凭据注入。这些工作远比把标准输入输出换成网络连接更具体。
Room 不需要跟着推倒重来。它从一开始就没有假设 Agent 必须和 Host 待在同一个进程,也没有假设 Agent 此刻一定在线。
最后把三层放回一起

Room 保存团队已经形成的协作事实。Runtime 保存一个 Agent 自己工作到了哪里。Bridge 负责把两个边界接起来。
Agent 可以退出,Runtime 可以替换,以后也可以迁移到另一台机器。Room 里的成员、消息和交接不会因此消失。
相关代码可以在 Nexus 和 Agent SDK Bridge 仓库里查看。