DSH / Atlas
2026-08-30implementedsimplificationarchived 2026-09-04

Team messaging uses one Steer send_message operation

Team 消息使用单一 Steer send_message 操作

Agent Teams exposed two model operations for one durable mailbox: quiet `send_message` injected into a live target without waking it, while `followup_task` queued a distinct waking turn and cold-resumed an inactive teammate. Models had to choose a scheduling policy instead of stating whom to message, and quiet messages could accumulate for an inactive teammate until unrelated work resumed it. The ordinary continuable

English

Problem

Agent Teams exposed two model operations for one durable mailbox: quiet send_message injected into a live target without waking it, while followup_task queued a distinct waking turn and cold-resumed an inactive teammate. Models had to choose a scheduling policy instead of stating whom to message, and quiet messages could accumulate for an inactive teammate until unrelated work resumed it.

The ordinary continuable-Agent controls already use one direction-neutral send_message with fixed Steer scheduling. Retaining separate Team names and delivery modes made equivalent model communication depend on whether the target happened to be a direct child or a Team peer.

Decision

Every Team member receives one send_message({ target, message }) tool. The Team tool set contains nine operations; followup_task and model-selectable quiet delivery are absent. The durable TeamMessageSnapshot stores sender, target, content, and message identity without a scheduling field.

Every accepted Team message uses Steer. A running target receives it at the nearest step boundary, an idle target starts a turn, and an inactive teammate cold-resumes through the continuation lifecycle. A successful Team send remains durable before delivery starts. accepted means the target inbox accepted the message; queued means a temporary inspection, resume, or inbox-admission failure left it in the Team mailbox for recovery. Neither result means the target completed the requested work.

The Lead receives the Team-attributed user message through Agent.steer(). A teammate receives it through a symbol-keyed host-only continuation adapter that authorizes the exact Lead-to-direct-child edge, preserves the original TeamMessageSource, and performs resident or cold-resume Steer admission. Sibling and teammate-to-Lead messages therefore retain the real sender; the Team runtime never calls public adjacent-Agent sendMessage() while impersonating the Lead.

The Lead Session remains the mailbox transaction owner. It flushes team/message/queued before dispatch, serializes immediate admissions per target in Lead-log order, and records team/message/delivered only after the target Session durably contains the same Team message id. Recovery retries queued-minus-delivered records in order, and target-side source folding prevents duplicate acceptance across the crash window between inbox insertion and acknowledgement.

Alternatives considered

Keep quiet send_message and waking followup_task. This preserves caller control over turn scheduling but makes the model choose an implementation policy, permits unread durable mail on inactive targets, and diverges from adjacent-Agent messaging.

Keep followup_task as an alias for Steer. Two names for identical behavior would preserve the tool-selection failure without adding an observable capability.

Route siblings through public adjacent-Agent sendMessage(). That operation authorizes only exact direct-parent or direct-child model senders and derives its own AgentMessageSource. Calling it with the Lead would misattribute sibling mail; widening it to Team membership would weaken its adjacency rule.

Drop the Team mailbox and deliver directly. Direct delivery loses durable enqueue-before-admission, recovery after temporary failure, stable message ids, and target-side de-duplication.

Testing

Package tests pin running, idle, inactive, Lead, sibling, and recovery delivery; target-local ordering; sender attribution; inbox/history de-duplication; temporary failure returning queued; and the nine-tool schema. The keyless Agent Teams profile snapshot drives a running implementer, steers a researcher message into its next step, and verifies that both teammates still complete their assigned tasks before the Lead aggregates the result.

Consequences

Models have one Team communication choice and cannot park quiet information intentionally. A message may extend the target's current turn, so prompts and tests require teammates to integrate new messages without abandoning work already in progress.

The host-only Steer adapter becomes part of the internal continuation integration used by Team delivery. Human browser prompts keep the separate Queue adapter and remain distinct turns. The broader Agent Teams decision retains mailbox, roster, task, and shared-checkout ownership; the adjacent-Agent messaging decision retains the public direct-edge authorization and model-message source.

中文

问题

Agent Teams 为一个持久 mailbox 公开了两个模型操作:quiet send_message 注入 live target 而不唤醒它,followup_task 则排入一个独立 waking turn 并冷恢复 inactive teammate。模型必须选择调度策略,而不是只说明消息目标;quiet 消息可能为 inactive teammate 持续累积,直到无关工作恢复它。

普通 continuable-Agent 控件已经使用一个方向无关、固定 Steer 调度的 send_message。保留独立的 Team 名称与投递模式,会让等价的模型通信因为 target 恰好是 direct child 还是 Team peer 而采用不同语义。

决策

每个 Team member 都会获得一个 send_message({ target, message }) 工具。Team 工具集包含九个操作;不存在 followup_task 与模型可选的 quiet 投递。持久 TeamMessageSnapshot 存储 sender、target、content 与 message identity,不存储调度字段。

每条已接受的 Team 消息都使用 Steer。running target 在最近的步骤边界收到消息,idle target 启动一个轮次,inactive teammate 则通过 continuation lifecycle 冷恢复。每次成功的 Team send 都会在开始投递前完成持久化。accepted 表示 target inbox 已接受消息;queued 表示临时 inspection、resume 或 inbox 准入失败让消息留在 Team mailbox 等待恢复。两种结果都不表示 target 已完成所请求的工作。

Lead 通过 Agent.steer() 接收携带 Team 归因的用户消息。teammate 通过 symbol-keyed host-only continuation adapter 接收消息;该 adapter 会授权精确的 Lead-to-direct-child edge、保留原始 TeamMessageSource,并执行 resident 或 cold-resume Steer 准入。因此 sibling 与 teammate-to-Lead 消息保留真实 sender;Team 运行时绝不会伪装成 Lead 调用公开的相邻 Agent sendMessage()。

Lead Session 继续作为 mailbox transaction owner。它在 dispatch 前 flush team/message/queued,按 Lead 日志顺序为每个 target 串行化即时准入,并且只有 target Session 持久包含相同 Team message id 后才记录 team/message/delivered。恢复按顺序重试 queued-minus-delivered 记录;target 侧 source 折叠会防止 inbox insertion 与 acknowledgement 之间的 crash window 导致重复准入。

考虑过的替代方案

保留 quiet send_message 与 waking followup_task。 这会保留调用方对 turn 调度的控制,但要求模型选择实现策略、允许 inactive target 存在未读持久 mail,并与相邻 Agent 消息语义分叉。

保留 followup_task 作为 Steer 别名。 两个名字表达同一行为只会保留工具选择错误,不会增加可观察能力。

通过公开的相邻 Agent sendMessage() 路由 sibling。 该操作只授权精确的 direct-parent 或 direct-child 模型 sender,并派生自己的 AgentMessageSource。以 Lead 身份调用会错误归因 sibling mail;把它扩展到 Team membership 则会削弱相邻关系规则。

删除 Team mailbox 并直接投递。 直接投递会失去准入前持久入队、临时失败后的恢复、稳定 message id 与 target 侧去重。

测试

包测试固定 running、idle、inactive、Lead、sibling 与 recovery 投递,target-local ordering、sender attribution、inbox/history 去重、临时失败返回 queued,以及九工具 schema。无密钥 Agent Teams profile snapshot 驱动 running implementer,把 researcher 消息 Steer 到其下一步骤,并验证两个 teammate 都继续完成各自任务,之后 Lead 才汇总结果。

后果

模型只有一种 Team 通信选择,不能有意停放 quiet information。一条消息可能扩展 target 的当前 turn,因此提示词与测试要求 teammate 整合新消息,同时不放弃已经进行的工作。

host-only Steer adapter 成为 Team 投递使用的内部 continuation 集成。人类浏览器 prompt 保留独立 Queue adapter,并继续形成不同 turn。更广泛的 Agent Teams 决策继续负责 mailbox、roster、task 与共享 checkout;相邻 Agent 消息决策继续负责公开 direct-edge authorization 与 model-message source。