docs(subagent): land the continuable-subagents note and supersede its predecessors
Moves the RFC to implemented/, restates it as current-state prose under the implemented note format, and records what the Task-backed continuable-subagents note and the two subagent-service simplification notes retain versus what this record replaces.
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-21-continuable-background-subagents.md
|
||||
2026-07-21-continuable-background-subagents.md: 0ea085a3eb9c6e661c1f009f338b264c06f14983
|
||||
2026-07-21-continuable-background-subagents.zh.md: 93f4c5b8ba4a052c5a6bb6eac3802601eb0797a5
|
||||
2026-07-21-continuable-background-subagents.md: 513ee668a9e04c05bb50f946016c460e09d1ddcd
|
||||
2026-07-21-continuable-background-subagents.zh.md: 88cdd00582b18a2092c6993507fe3d4b92f237ae
|
||||
|
||||
@@ -4,7 +4,7 @@ Status: implemented
|
||||
|
||||
English | [中文](2026-07-21-continuable-background-subagents.zh.md)
|
||||
|
||||
The service-placement and provider-capability policy in this record are superseded by [Merge subagent control into the subagent service](../simplification/2026-07-26-merge-subagent-control-service.md) and [Intent-named subagent continuation operations](../simplification/2026-07-27-intent-named-subagent-continuation-operations.md). The continuation, persistence, Task, routing, authorization, and durability semantics remain in force.
|
||||
This record is superseded by [Continuable subagents](2026-07-28-continuable-subagent-conversations.md), which replaces its Task-backed activation model, routing, cancellation, and durability semantics with one durable Session plus at most one process-local Activation. Its service-placement and provider-capability policy were already superseded by [Merge subagent control into the subagent service](../simplification/2026-07-26-merge-subagent-control-service.md) and [Intent-named subagent continuation operations](../simplification/2026-07-27-intent-named-subagent-continuation-operations.md). Only the durable child-session and descriptor rationale remains in force.
|
||||
|
||||
## Problem
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Status: implemented
|
||||
|
||||
[English](2026-07-21-continuable-background-subagents.md) | 中文
|
||||
|
||||
本记录中的服务放置与提供方功能策略已由[将 subagent 控制合并到 subagent 服务](../simplification/2026-07-26-merge-subagent-control-service.md)和[以意图命名的 subagent 继续执行操作](../simplification/2026-07-27-intent-named-subagent-continuation-operations.md)取代。继续执行、持久化、Task、路由、授权和持久性语义仍然有效。
|
||||
本记录已由[可继续的 subagent](2026-07-28-continuable-subagent-conversations.md)取代——后者以一个持久 Session 加至多一个进程内 Activation(驻留期)替换了其基于 Task 的 activation 模型、路由、取消和持久性语义。其服务放置与提供方功能策略此前已由[将 subagent 控制合并到 subagent 服务](../simplification/2026-07-26-merge-subagent-control-service.md)和[以意图命名的 subagent 继续执行操作](../simplification/2026-07-27-intent-named-subagent-continuation-operations.md)取代。仅持久 child 会话与 descriptor 的设计依据仍然有效。
|
||||
|
||||
## 问题
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-07-28-continuable-subagent-conversations.md
|
||||
2026-07-28-continuable-subagent-conversations.md: 5ab17ea13d15d66afab4fee6766b082dd207b8a3
|
||||
2026-07-28-continuable-subagent-conversations.zh.md: eb14ebcec9682432682f6b5b4d8399f35b6882a2
|
||||
@@ -1,6 +1,6 @@
|
||||
# Agent Note: Continuable subagents
|
||||
|
||||
Status: proposed
|
||||
Status: implemented
|
||||
|
||||
English | [中文](2026-07-28-continuable-subagent-conversations.zh.md)
|
||||
|
||||
@@ -16,7 +16,7 @@ The runtime lifetime is also wider than one turn. A subagent can finish its own
|
||||
|
||||
Users and parent Agents also need to send later work to the same live child without changing its current turn. Queueing every continuation message as a follow-up preserves one ordering rule for both senders.
|
||||
|
||||
## Proposal
|
||||
## Decision
|
||||
|
||||
A continuable subagent has one durable Session and at most one process-local Activation:
|
||||
|
||||
@@ -34,7 +34,7 @@ The continuation manager owns activation admission, authority checks, the live o
|
||||
|
||||
### Materialization and public operations
|
||||
|
||||
The named subagent provider participates only in preparing the initial creation spec, where `spawn` and `fork` differ. Its optional `prepareContinuable(request): Promise<ContinuableCreateSpec>` method is the continuable-creation capability. The returned spec contains only detached provider-specific creation inputs such as the optional parent-history seed; it contains no Agent, `AgentHandle`, prompt delivery, result, disposal, or resume operation. The manager reserves the child identity, resolves the durable descriptor and common Agent setup, calls `ctx.agents.create()` through a private activation-owner scope, installs the returned `AgentHandle` into the Activation, establishes any continuable-parent ownership, and then calls `Agent.followup(initialPrompt)`. Inbox acceptance yields an `AgentMessageId`; at that boundary `ctx.subagents.startContinuable()` returns `{ childId, messageId }` without waiting for the turn to start or for the message to enter the Session log.
|
||||
The named subagent provider participates only in preparing the initial creation spec, where `spawn` and `fork` differ. Its optional `prepareContinuable(request): Promise<ContinuableCreateSpec>` method is the continuable-creation capability. The returned spec contains only detached provider-specific creation inputs such as the optional parent-history seed; it contains no Agent, `AgentHandle`, prompt delivery, result, disposal, or resume operation. The manager reserves the child identity, resolves the durable descriptor and common Agent setup, calls `ctx.agents.create()` through a private activation-owner scope, installs the returned `AgentHandle` into the Activation, establishes any continuable-parent ownership, and then calls `Agent.followup(initialPrompt)`. Inbox acceptance yields an `MessageId`; at that boundary `ctx.subagents.startContinuable()` returns `{ childId, messageId }` without waiting for the turn to start or for the message to enter the Session log.
|
||||
|
||||
Any failure before inbox acceptance rejects without returning either id. Agent creation provides rollback before handle transfer; after transfer, the manager disposes the created handle, removes the Activation, and rolls back any parent `ownedChildren` membership before rejecting.
|
||||
|
||||
@@ -44,9 +44,9 @@ Cold resume does not dispatch through a subagent provider. The continuation mana
|
||||
|
||||
`SubagentProvider.start()` and `SubagentRun` remain exclusively on the unchanged one-shot path. A continuable Activation directly owns its `AgentHandle` and never creates, wraps, or retains a `SubagentRun`; `SubagentRun.steer?()` is therefore absent.
|
||||
|
||||
`ctx.subagents.followup(authority, childId, content, { source, signal })` remains the sole continuation-message operation. `authority` is either `{ kind: 'parent', agent }` or `{ kind: 'user' }`; the parent variant is admitted only from an exact live Agent tool context, while only a trusted host adapter can supply user authority. `source` remains durable provenance and grants no authority. The model-facing `send_message` tool keeps only its stable `subagent_id` and `message` fields and always submits a follow-up turn. Both start and follow-up return the accepted `AgentMessageId`, and neither reports how the manager materialized the Activation.
|
||||
`ctx.subagents.followup(authority, childId, content, { source, signal })` remains the sole continuation-message operation. `authority` is either `{ kind: 'parent', agent }` or `{ kind: 'user' }`; the parent variant is admitted only from an exact live Agent tool context, while only a trusted host adapter can supply user authority. `source` remains durable provenance and grants no authority. The model-facing `send_message` tool keeps only its stable `subagent_id` and `message` fields and always submits a follow-up turn. Both start and follow-up return the accepted `MessageId`, and neither reports how the manager materialized the Activation.
|
||||
|
||||
For start and follow-up, the caller signal owns lookup, materialization, and admission only until inbox acceptance. After the operation returns its `AgentMessageId`, the manager owns the Activation independently; later caller cancellation does not cancel the accepted turn or dispose the child.
|
||||
For start and follow-up, the caller signal owns lookup, materialization, and admission only until inbox acceptance. After the operation returns its `MessageId`, the manager owns the Activation independently; later caller cancellation does not cancel the accepted turn or dispose the child.
|
||||
|
||||
### Durable Session and live Activation
|
||||
|
||||
@@ -95,7 +95,7 @@ Routing depends only on Activation residency:
|
||||
| `waiting` | parent or user | wake the same Activation |
|
||||
| no Activation | parent or user | cold-resume a new Activation |
|
||||
|
||||
The continuation layer defines no separate delivery-route result. Successful `ctx.subagents.followup()` and `send_message` delivery returns the accepted `AgentMessageId`, while delivery failure throws. Existing `agent/inbox/enqueue`, `agent/inbox/dequeue`, and `agent/inbox/discard` events remain the message-lifecycle observations; adapters may render a generic acceptance but do not expose `started`, `queued`, `resumed`, or another subagent-specific route vocabulary.
|
||||
The continuation layer defines no separate delivery-route result. Successful `ctx.subagents.followup()` and `send_message` delivery returns the accepted `MessageId`, while delivery failure throws. Existing `agent/inbox/enqueue`, `agent/inbox/dequeue`, and `agent/inbox/discard` events remain the message-lifecycle observations; adapters may render a generic acceptance but do not expose `started`, `queued`, `resumed`, or another subagent-specific route vocabulary.
|
||||
|
||||
### Child ownership
|
||||
|
||||
@@ -171,22 +171,24 @@ The MVP adds no subagent steering operation, report tool, child-to-parent conten
|
||||
|
||||
**Expose subagent steering in the MVP.** User steering can be a strict live-only host action, but parent steering needs current-turn controller state to protect a user-controlled turn. Queueing every first-version continuation avoids that state and its admission race. A later UI can add a distinct user-only action without changing follow-up ordering.
|
||||
|
||||
**Return a subagent-specific delivery route.** Labels such as `started`, `queued`, and `resumed` duplicate Activation and inbox state without giving the caller an independent result. Reusing `AgentMessageId` and the existing inbox events keeps delivery correlation on the Agent contract that owns it.
|
||||
**Return a subagent-specific delivery route.** Labels such as `started`, `queued`, and `resumed` duplicate Activation and inbox state without giving the caller an independent result. Reusing `MessageId` and the existing inbox events keeps delivery correlation on the Agent contract that owns it.
|
||||
|
||||
**Use a child reference count.** A count cannot identify which child still owns teardown work and permits duplicate decrement errors. An identity set retains cancellation and disposal obligations explicitly.
|
||||
|
||||
## Acceptance criteria
|
||||
## Consequences
|
||||
|
||||
The implementation pins these behaviors:
|
||||
|
||||
- A continuable child has at most one live Activation and one Agent inbox; the continuation manager has no Activation FIFO or queued Activation state.
|
||||
- `SubagentProvider.prepareContinuable?()` returns only a detached `ContinuableCreateSpec`; configured continuable mode requires that capability, while `backgroundMode` remains an independent policy choice.
|
||||
- The manager calls `ctx.agents.create()` through its private activation-owner scope, installs the returned `AgentHandle` and parent ownership, calls `Agent.followup(initialPrompt)`, and returns `{ childId, messageId }` when inbox acceptance yields the `AgentMessageId`, without waiting for turn start or a Session-log write.
|
||||
- The manager calls `ctx.agents.create()` through its private activation-owner scope, installs the returned `AgentHandle` and parent ownership, calls `Agent.followup(initialPrompt)`, and returns `{ childId, messageId }` when inbox acceptance yields the `MessageId`, without waiting for turn start or a Session-log write.
|
||||
- Every failure before initial-prompt inbox acceptance rejects without ids and rolls back any created handle, Activation, and parent `ownedChildren` membership.
|
||||
- Cold resume calls `ctx.agents.resume()` from the continuation manager and never dispatches through the initial subagent provider; `SubagentProvider.resume?()` and `SubagentProviderResumeRequest` are absent.
|
||||
- A continuable Activation directly owns `AgentHandle` and never creates, wraps, or retains `SubagentRun`; `SubagentProvider.start()` and `SubagentRun` remain one-shot-only, without `SubagentRun.steer?()`.
|
||||
- A user can cold-resume a persisted child without loading its historical parent.
|
||||
- `followup()` accepts only trusted parent or user authority; durable message provenance cannot authorize delivery.
|
||||
- Parent and user continuation messages always use `Agent.followup()` and share its inbox FIFO, including when one origin queues behind the other or the child already has an open turn.
|
||||
- `ctx.subagents.followup()` and its `send_message` adapter return only the accepted `AgentMessageId`; the continuation layer accepts no delivery target and defines no subagent-specific route result.
|
||||
- `ctx.subagents.followup()` and its `send_message` adapter return only the accepted `MessageId`; the continuation layer accepts no delivery target and defines no subagent-specific route result.
|
||||
- The MVP exposes no public subagent cancellation operation; caller signals stop start and follow-up only before inbox acceptance, while host and manager teardown retains child-first global cleanup.
|
||||
- The MVP exposes no subagent steering operation or current-turn controller state.
|
||||
- An idle Agent with live owned children yields a `waiting` Activation whose `AgentHandle` remains retained.
|
||||
@@ -198,10 +200,10 @@ The MVP adds no subagent steering operation, report tool, child-to-parent conten
|
||||
- Session logs reconstruct only messages that were actually written, with their admitted provenance; inbox-accepted but unlogged messages have no restart guarantee.
|
||||
- No continuable-subagent path creates or depends on a Task, `TaskId`, Task completion notice, Task cancellation, or intermediate result-bearing execution wrapper.
|
||||
- Unit coverage pins the `startContinuable()` inbox-acceptance return boundary, complete rollback for each pre-acceptance failure, caller-signal ownership on both sides of acceptance, and the absence of automatic replay for accepted-but-unlogged messages.
|
||||
- Unit coverage pins the residency-only routing table, single-inbox ordering, `AgentMessageId` correlation through inbox events, follow-up during an open turn, waiting wakeup, cold resume, ownership registration and release, child-first disposal, send-versus-dispose races, both `false` and rejection from the final durability checkpoint without ownership leaks, and the absence of public subagent cancellation, steering, and report tools.
|
||||
- Unit coverage pins the residency-only routing table, single-inbox ordering, `MessageId` correlation through inbox events, follow-up during an open turn, waiting wakeup, cold resume, ownership registration and release, child-first disposal, send-versus-dispose races, both `false` and rejection from the final durability checkpoint without ownership leaks, and the absence of public subagent cancellation, steering, and report tools.
|
||||
- A keyless assembled-app snapshot covers parent delegation, mixed parent/user follow-up queueing, the absence of subagent steering, report delivery, and automatic parent wakeup, retained waiting `AgentHandle`, and child-first disposal.
|
||||
|
||||
## Risks
|
||||
### Accepted costs
|
||||
|
||||
Removing Tasks gives up generic background-work inspection, result collection, and exact Task cancellation. If those product features become requirements, they need a request ticket or inbox capability that does not reintroduce a second execution queue.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Agent Note(agent 决策记录):可继续的 subagent
|
||||
|
||||
Status: proposed
|
||||
Status: implemented
|
||||
|
||||
[English](2026-07-28-continuable-subagent-conversations.md) | 中文
|
||||
|
||||
@@ -16,7 +16,7 @@ Status: proposed
|
||||
|
||||
用户和 parent Agent 还需要在不改变当前轮次的前提下,向同一个在线 child 发送后续工作。将每条继续执行消息作为 follow-up 排队,可以让两类发送方遵循同一项排序规则。
|
||||
|
||||
## 提案
|
||||
## 决策
|
||||
|
||||
一个可继续 subagent 拥有一个持久化会话,并且至多拥有一个进程内激活:
|
||||
|
||||
@@ -34,7 +34,7 @@ persisted Session
|
||||
|
||||
### 物化与公开操作
|
||||
|
||||
具名 subagent 提供方只参与准备初始创建规格,此时 `spawn` 与 `fork` 有所区别。其可选的 `prepareContinuable(request): Promise<ContinuableCreateSpec>` 方法就是可继续创建能力。返回的规格只包含与 Agent 实例分离且由提供方决定的创建输入,例如可选的 parent 历史种子;它不包含 Agent、`AgentHandle`、提示词投递、结果、dispose 或恢复操作。管理器会预留 child 身份,解析持久化描述符和通用 Agent 配置,通过私有 activation-owner 作用域调用 `ctx.agents.create()`,将返回的 `AgentHandle` 安装到激活中,建立适用的可继续 parent 所有权,然后调用 `Agent.followup(initialPrompt)`。inbox 接受消息后会产生一个 `AgentMessageId`;`ctx.subagents.startContinuable()` 在此边界返回 `{ childId, messageId }`,不等待轮次开始,也不等待消息写入会话日志。
|
||||
具名 subagent 提供方只参与准备初始创建规格,此时 `spawn` 与 `fork` 有所区别。其可选的 `prepareContinuable(request): Promise<ContinuableCreateSpec>` 方法就是可继续创建能力。返回的规格只包含与 Agent 实例分离且由提供方决定的创建输入,例如可选的 parent 历史种子;它不包含 Agent、`AgentHandle`、提示词投递、结果、dispose 或恢复操作。管理器会预留 child 身份,解析持久化描述符和通用 Agent 配置,通过私有 activation-owner 作用域调用 `ctx.agents.create()`,将返回的 `AgentHandle` 安装到激活中,建立适用的可继续 parent 所有权,然后调用 `Agent.followup(initialPrompt)`。inbox 接受消息后会产生一个 `MessageId`;`ctx.subagents.startContinuable()` 在此边界返回 `{ childId, messageId }`,不等待轮次开始,也不等待消息写入会话日志。
|
||||
|
||||
inbox 接受消息前发生任何失败,操作都会在不返回任何 id 的情况下被拒绝。Agent 创建流程负责 handle 移交前的回滚;移交后,管理器会先 dispose 已创建的 handle、移除激活并回滚 parent `ownedChildren` 中的任何成员关系,再拒绝操作。
|
||||
|
||||
@@ -44,9 +44,9 @@ inbox 接受消息前发生任何失败,操作都会在不返回任何 id 的
|
||||
|
||||
`SubagentProvider.start()` 和 `SubagentRun` 只保留在不变的 one-shot 路径上。可继续激活直接持有自身的 `AgentHandle`,绝不创建、包装或保留 `SubagentRun`;因此,`SubagentRun.steer?()` 不存在。
|
||||
|
||||
`ctx.subagents.followup(authority, childId, content, { source, signal })` 仍是唯一的继续执行消息操作。`authority` 可以是 `{ kind: 'parent', agent }` 或 `{ kind: 'user' }`;parent 变体仅能从确切的在线 Agent 工具上下文通过准入,只有可信宿主适配器才能提供用户权限。`source` 仍是持久化来源信息,不赋予任何权限。面向模型的 `send_message` 工具只保留稳定的 `subagent_id` 和 `message` 字段,并始终提交一个 follow-up 轮次。start 和 follow-up 都返回已接受的 `AgentMessageId`,两者都不报告管理器如何物化激活。
|
||||
`ctx.subagents.followup(authority, childId, content, { source, signal })` 仍是唯一的继续执行消息操作。`authority` 可以是 `{ kind: 'parent', agent }` 或 `{ kind: 'user' }`;parent 变体仅能从确切的在线 Agent 工具上下文通过准入,只有可信宿主适配器才能提供用户权限。`source` 仍是持久化来源信息,不赋予任何权限。面向模型的 `send_message` 工具只保留稳定的 `subagent_id` 和 `message` 字段,并始终提交一个 follow-up 轮次。start 和 follow-up 都返回已接受的 `MessageId`,两者都不报告管理器如何物化激活。
|
||||
|
||||
对于 start 和 follow-up,调用方 signal 只在 inbox 接受消息前持有查找、物化和准入。操作返回 `AgentMessageId` 后,管理器会独立持有该激活;调用方之后的取消不会取消已接受的轮次,也不会 dispose child。
|
||||
对于 start 和 follow-up,调用方 signal 只在 inbox 接受消息前持有查找、物化和准入。操作返回 `MessageId` 后,管理器会独立持有该激活;调用方之后的取消不会取消已接受的轮次,也不会 dispose child。
|
||||
|
||||
### 持久化会话与在线激活
|
||||
|
||||
@@ -95,7 +95,7 @@ Agent inbox 是唯一队列。每条继续执行消息都使用 `Agent.followup(
|
||||
| `waiting` | parent 或 user | 唤醒同一激活 |
|
||||
| 无激活 | parent 或 user | 冷恢复新激活 |
|
||||
|
||||
继续执行层不定义单独的投递路由结果。成功投递 `ctx.subagents.followup()` 或 `send_message` 时会返回已接受的 `AgentMessageId`,投递失败则会抛出异常。现有的 `agent/inbox/enqueue`、`agent/inbox/dequeue` 和 `agent/inbox/discard` 事件仍用于观测消息生命周期;适配器可以呈现通用的接受确认,但不暴露 `started`、`queued`、`resumed` 或其他 subagent 专属路由词汇。
|
||||
继续执行层不定义单独的投递路由结果。成功投递 `ctx.subagents.followup()` 或 `send_message` 时会返回已接受的 `MessageId`,投递失败则会抛出异常。现有的 `agent/inbox/enqueue`、`agent/inbox/dequeue` 和 `agent/inbox/discard` 事件仍用于观测消息生命周期;适配器可以呈现通用的接受确认,但不暴露 `started`、`queued`、`resumed` 或其他 subagent 专属路由词汇。
|
||||
|
||||
### child 所有权
|
||||
|
||||
@@ -171,22 +171,24 @@ MVP 不新增 subagent steering 操作、报告工具、从 child 到 parent 的
|
||||
|
||||
**在 MVP 中暴露 subagent steering。** 用户 steering 可以是严格且仅限在线使用的宿主操作,但 parent steering 需要当前轮次控制方状态,以保护由用户控制的轮次。首个版本将每条继续执行消息都排队,可以避免引入该状态及其准入竞争。后续 UI 可以新增一项仅限用户的独立操作,而不改变 follow-up 排序。
|
||||
|
||||
**返回 subagent 专属的投递路由。** `started`、`queued` 和 `resumed` 等标签重复了激活与 inbox 状态,却没有给调用方提供独立结果。复用 `AgentMessageId` 和现有 inbox 事件,可以让投递关联继续由其所属的 Agent 契约承载。
|
||||
**返回 subagent 专属的投递路由。** `started`、`queued` 和 `resumed` 等标签重复了激活与 inbox 状态,却没有给调用方提供独立结果。复用 `MessageId` 和现有 inbox 事件,可以让投递关联继续由其所属的 Agent 契约承载。
|
||||
|
||||
**使用 child 引用计数。** 计数无法识别哪个 child 仍持有拆卸工作,也允许重复递减错误。身份集合会显式保留取消和 dispose 义务。
|
||||
|
||||
## 验收标准
|
||||
## 影响
|
||||
|
||||
本实现固定了以下行为:
|
||||
|
||||
- 可继续 child 至多拥有一个在线激活和一个 Agent inbox;继续执行管理器没有激活 FIFO 或 queued 激活状态。
|
||||
- `SubagentProvider.prepareContinuable?()` 只返回分离式 `ContinuableCreateSpec`;配置为 continuable 时要求具备该能力,而 `backgroundMode` 仍是独立的策略选择。
|
||||
- 管理器通过私有 activation-owner 作用域调用 `ctx.agents.create()`,安装返回的 `AgentHandle` 并建立 parent 所有权,调用 `Agent.followup(initialPrompt)`,然后在 inbox 接受消息并产生 `AgentMessageId` 时返回 `{ childId, messageId }`,而不等待轮次开始或消息写入会话日志。
|
||||
- 管理器通过私有 activation-owner 作用域调用 `ctx.agents.create()`,安装返回的 `AgentHandle` 并建立 parent 所有权,调用 `Agent.followup(initialPrompt)`,然后在 inbox 接受消息并产生 `MessageId` 时返回 `{ childId, messageId }`,而不等待轮次开始或消息写入会话日志。
|
||||
- 初始提示词被 inbox 接受前的每条失败路径都会导致操作被拒绝且不返回 id,并回滚已创建的任何 handle、激活和 parent `ownedChildren` 成员关系。
|
||||
- 冷恢复由继续执行管理器调用 `ctx.agents.resume()`,绝不通过初始 subagent 提供方分发;`SubagentProvider.resume?()` 和 `SubagentProviderResumeRequest` 均不存在。
|
||||
- 可继续激活直接持有 `AgentHandle`,绝不创建、包装或保留 `SubagentRun`;`SubagentProvider.start()` 和 `SubagentRun` 只用于 one-shot,且没有 `SubagentRun.steer?()`。
|
||||
- 用户可以在不加载历史 parent 的前提下冷恢复持久化 child。
|
||||
- `followup()` 只接受可信 parent 或用户权限;持久化消息来源信息不能授权投递。
|
||||
- Parent 和用户的继续执行消息始终使用 `Agent.followup()` 并共享其 inbox FIFO,包括一种来源排在另一种来源之后,以及 child 已有开放轮次的情况。
|
||||
- `ctx.subagents.followup()` 及其 `send_message` 适配器只返回已接受的 `AgentMessageId`;继续执行层不接受投递 target,也不定义 subagent 专属路由结果。
|
||||
- `ctx.subagents.followup()` 及其 `send_message` 适配器只返回已接受的 `MessageId`;继续执行层不接受投递 target,也不定义 subagent 专属路由结果。
|
||||
- MVP 不暴露公开 subagent 取消操作;调用方 signal 只能在 inbox 接受消息前停止 start 和 follow-up,宿主和管理器拆卸则保留 child-first 全局清理。
|
||||
- MVP 不暴露 subagent steering 操作或当前轮次控制方状态。
|
||||
- 带有在线所持 child 的空闲 Agent 会产生 `waiting` 激活,其 `AgentHandle` 继续保留。
|
||||
@@ -198,10 +200,10 @@ MVP 不新增 subagent steering 操作、报告工具、从 child 到 parent 的
|
||||
- 会话日志只能根据准入来源重建实际写入的消息;已被 inbox 接受但未写入日志的消息没有重启保证。
|
||||
- 可继续 subagent 路径不创建或依赖 Task、`TaskId`、Task 完成通知、Task 取消或中间的带结果执行包装层。
|
||||
- 单元覆盖固定 `startContinuable()` 在 inbox 接受消息时的返回边界、每条接受前失败路径的完整回滚、接受前后两个阶段的调用方 signal 所有权,以及已接受但未写入日志的消息不会自动回放。
|
||||
- 单元覆盖固定仅由驻留状态决定的路由表、单 inbox 顺序、通过 inbox 事件关联 `AgentMessageId`、在开放轮次期间 follow-up、等待唤醒、冷恢复、所有权注册与释放、child-first dispose、发送与 dispose 的竞争、最终持久性检查点返回 `false` 和 rejection 时都不泄漏所有权,以及不存在公开 subagent 取消、steering 和报告工具这一事实。
|
||||
- 单元覆盖固定仅由驻留状态决定的路由表、单 inbox 顺序、通过 inbox 事件关联 `MessageId`、在开放轮次期间 follow-up、等待唤醒、冷恢复、所有权注册与释放、child-first dispose、发送与 dispose 的竞争、最终持久性检查点返回 `false` 和 rejection 时都不泄漏所有权,以及不存在公开 subagent 取消、steering 和报告工具这一事实。
|
||||
- 一项无密钥整套应用快照覆盖 parent 委派、parent 与用户混合的 follow-up 排队、不存在 subagent steering、报告投递和自动唤醒 parent、保留等待中的 `AgentHandle` 以及 child-first dispose。
|
||||
|
||||
## 风险
|
||||
### 已接受的代价
|
||||
|
||||
移除 Task 会放弃通用后台工作检查、结果收集和精确 Task 取消。如果这些产品功能成为需求,就需要不会重新引入第二条执行队列的请求 ticket 或 inbox 能力。
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-26-merge-subagent-control-service.md
|
||||
2026-07-26-merge-subagent-control-service.md: 84995446939d0f47e008bffb38083b1b6e0706de
|
||||
2026-07-26-merge-subagent-control-service.zh.md: 7f82555159bfea9e00fa4cc2afdcf30382f3f776
|
||||
2026-07-26-merge-subagent-control-service.md: 67a26b6014efeb4f35911ccb90980d85f5e67557
|
||||
2026-07-26-merge-subagent-control-service.zh.md: 532a93e7c027ae18417e7aa4ae41faee21b5575a
|
||||
|
||||
@@ -4,7 +4,7 @@ Status: implemented
|
||||
|
||||
English | [中文](2026-07-26-merge-subagent-control-service.zh.md)
|
||||
|
||||
The public operation set is refined by [Intent-named subagent continuation operations](2026-07-27-intent-named-subagent-continuation-operations.md).
|
||||
The public operation set is refined by [Intent-named subagent continuation operations](2026-07-27-intent-named-subagent-continuation-operations.md) and again by [Continuable subagents](../feature/2026-07-28-continuable-subagent-conversations.md), which keeps the single merged service while removing provider `resume` dispatch and the Task-backed continuation lifecycle.
|
||||
|
||||
## Problem
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ Status: implemented
|
||||
|
||||
[English](2026-07-26-merge-subagent-control-service.md) | 中文
|
||||
|
||||
公开操作集合由[以意图命名的 subagent 继续执行操作](2026-07-27-intent-named-subagent-continuation-operations.md)进一步细化。
|
||||
公开操作集合由[以意图命名的 subagent 继续执行操作](2026-07-27-intent-named-subagent-continuation-operations.md)进一步细化,并由[可继续的 subagent](../feature/2026-07-28-continuable-subagent-conversations.md)再次细化——后者保留这一个合并后的服务,同时移除提供方 `resume` 派发和基于 Task 的继续执行生命周期。
|
||||
|
||||
## 问题
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/simplification/2026-07-27-intent-named-subagent-continuation-operations.md
|
||||
2026-07-27-intent-named-subagent-continuation-operations.md: 1155e6b2fb89661021ebdbd6310902e74a500078
|
||||
2026-07-27-intent-named-subagent-continuation-operations.zh.md: 5f434cd8fbb171ef77a3b1f307029d6ade09f1d6
|
||||
2026-07-27-intent-named-subagent-continuation-operations.md: 9f29074add3517d0baf94516c56fa69085ef75c4
|
||||
2026-07-27-intent-named-subagent-continuation-operations.zh.md: a748af1a6cf44bc552b492d43314bf5a4e95338d
|
||||
|
||||
@@ -4,6 +4,8 @@ Status: implemented
|
||||
|
||||
English | [中文](2026-07-27-intent-named-subagent-continuation-operations.zh.md)
|
||||
|
||||
The `followup` operation this record names is retained by [Continuable subagents](../feature/2026-07-28-continuable-subagent-conversations.md), which replaces its Task-backed return value with the accepted `MessageId`, its bare-`Agent` parameter with an explicit authority union, and provider `resume` dispatch with `prepareContinuable`.
|
||||
|
||||
## Problem
|
||||
|
||||
Merging continuable-child orchestration into `ctx.subagents` left provider dispatch and caller intent on the same public service. `resume(name, request)` accepted a descriptor, authorized parent, durable child id, and activation signal that only the internal continuation manager could resolve correctly. `sendMessage(...)` exposed transport wording rather than the `followup` intent already used by `Agent`, and its separate source and signal parameters widened an operation every caller had to use atomically.
|
||||
|
||||
@@ -4,6 +4,8 @@ Status: implemented
|
||||
|
||||
[English](2026-07-27-intent-named-subagent-continuation-operations.md) | 中文
|
||||
|
||||
本记录命名的 `followup` 操作由[可继续的 subagent](../feature/2026-07-28-continuable-subagent-conversations.md)保留,但后者以已接受的 `MessageId` 替换其基于 Task 的返回值,以显式的 authority(授权)联合类型替换裸 `Agent` 参数,并以 `prepareContinuable` 替换提供方 `resume` 派发。
|
||||
|
||||
## 问题
|
||||
|
||||
将可继续 child 的编排合并到 `ctx.subagents` 后,提供方分发与调用方意图共存于同一个公开服务中。`resume(name, request)` 接受描述符、已鉴权的 parent、持久化 child id 与激活信号,而只有内部继续执行管理器才能正确解析这些数据。`sendMessage(...)` 暴露的是传输层措辞,而不是 `Agent` 已采用的 `followup` 意图;它还将来源与信号拆成独立参数,扩大了操作接口,而每个调用方都必须以原子方式同时使用二者。
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/proposed/feature/2026-07-28-continuable-subagent-conversations.md
|
||||
2026-07-28-continuable-subagent-conversations.md: 3902fbc33004219f98d070d4b898de6b2c19d40d
|
||||
2026-07-28-continuable-subagent-conversations.zh.md: 11f59d8f1a57e2d1bf375a3e1c1cd46043c60a3f
|
||||
Reference in New Issue
Block a user