@hydraharness/harness-subagent 0.1.1-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +155 -0
  3. package/lib/index.js +2743 -0
  4. package/lib/invariant.js +76 -0
  5. package/lib/types/activation-setup-registry.d.ts +57 -0
  6. package/lib/types/activation-setup-registry.js +148 -0
  7. package/lib/types/assistant-output.d.ts +48 -0
  8. package/lib/types/assistant-output.js +72 -0
  9. package/lib/types/budget.d.ts +34 -0
  10. package/lib/types/budget.js +54 -0
  11. package/lib/types/child-agent.d.ts +139 -0
  12. package/lib/types/child-agent.js +169 -0
  13. package/lib/types/client.d.ts +7 -0
  14. package/lib/types/client.js +7 -0
  15. package/lib/types/continuation.d.ts +457 -0
  16. package/lib/types/continuation.js +1157 -0
  17. package/lib/types/depth.d.ts +31 -0
  18. package/lib/types/depth.js +39 -0
  19. package/lib/types/descriptor-seed.d.ts +21 -0
  20. package/lib/types/descriptor-seed.js +24 -0
  21. package/lib/types/descriptor.d.ts +139 -0
  22. package/lib/types/descriptor.js +189 -0
  23. package/lib/types/error.d.ts +11 -0
  24. package/lib/types/error.js +14 -0
  25. package/lib/types/index.d.ts +296 -0
  26. package/lib/types/index.js +374 -0
  27. package/lib/types/invariant.d.ts +13 -0
  28. package/lib/types/invariant.js +91 -0
  29. package/lib/types/lifecycle.d.ts +113 -0
  30. package/lib/types/lifecycle.js +177 -0
  31. package/lib/types/list-children.d.ts +112 -0
  32. package/lib/types/list-children.js +316 -0
  33. package/lib/types/out-of-process.d.ts +117 -0
  34. package/lib/types/out-of-process.js +211 -0
  35. package/lib/types/projection-types.d.ts +60 -0
  36. package/lib/types/projection-types.js +7 -0
  37. package/lib/types/projection.d.ts +95 -0
  38. package/lib/types/projection.js +150 -0
  39. package/lib/types/run-settlement.d.ts +17 -0
  40. package/lib/types/run-settlement.js +66 -0
  41. package/lib/types/types.d.ts +315 -0
  42. package/lib/types/types.js +19 -0
  43. package/package.json +112 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Shared in-process child composition: the delegation-depth budget, the
3
+ * durable session metadata, the resolved child `AgentOptions`, the delegated
4
+ * policy seed, and the scoped setup a child agent needs. Both the one-shot
5
+ * provider driver and the continuation manager compose children this way, so
6
+ * depth accounting, lineage stamping, and delegation policy have one home.
7
+ *
8
+ * @module @hydraharness/harness-subagent/child-agent
9
+ */
10
+ import { delegationDepthOf } from "./depth.js";
11
+ /** Thrown when starting a child would exceed the requested depth cap. */
12
+ export class SubagentDepthError extends Error {
13
+ attemptedDepth;
14
+ maxDepth;
15
+ constructor(attemptedDepth, maxDepth) {
16
+ super(`subagent depth ${attemptedDepth} exceeds maxDepth ${maxDepth}`);
17
+ this.attemptedDepth = attemptedDepth;
18
+ this.maxDepth = maxDepth;
19
+ this.name = 'SubagentDepthError';
20
+ }
21
+ }
22
+ /**
23
+ * Resolve the child's delegation depth from its parent and enforce an optional
24
+ * cap. The persisted parent header is the monotone floor, so a resumed parent
25
+ * cannot delegate as if it were top-level.
26
+ * @param parent - the delegating parent agent.
27
+ * @param maxDepth - optional absolute cap the resolved depth must not exceed.
28
+ * @returns the child's non-negative safe-integer depth.
29
+ * @throws {SubagentDepthError} when the resolved depth exceeds `maxDepth`.
30
+ * @throws {RangeError} when the resolved depth leaves the safe-integer range.
31
+ */
32
+ export function resolveChildDepth(parent, maxDepth) {
33
+ const childDepth = delegationDepthOf(parent) + 1;
34
+ if (!Number.isSafeInteger(childDepth)) {
35
+ throw new RangeError('subagent child depth exceeds the safe-integer range');
36
+ }
37
+ if (maxDepth !== undefined && childDepth > maxDepth) {
38
+ throw new SubagentDepthError(childDepth, maxDepth);
39
+ }
40
+ return childDepth;
41
+ }
42
+ /**
43
+ * Resolve the child's `AgentOptions`: the parent's provider/model/maxTokens
44
+ * route unless the request overrides it, stamped with the child's own
45
+ * delegation depth.
46
+ * @param parent - the delegating parent whose route the child inherits.
47
+ * @param requested - per-child overrides, if any.
48
+ * @param childDepth - the resolved delegation depth to stamp.
49
+ * @returns the resolved options for `ctx.agents.create()`.
50
+ */
51
+ export function resolveChildAgentOptions(parent, requested, childDepth) {
52
+ const parentProvider = parent.options.provider;
53
+ const parentModel = parent.options.model;
54
+ const parentMaxTokens = parent.options.maxTokens;
55
+ return {
56
+ ...parentProvider !== undefined ? { provider: parentProvider } : {},
57
+ ...parentModel !== undefined ? { model: parentModel } : {},
58
+ ...parentMaxTokens !== undefined ? { maxTokens: parentMaxTokens } : {},
59
+ ...requested,
60
+ subagentDepth: childDepth,
61
+ };
62
+ }
63
+ /**
64
+ * Build the child session's durable creation metadata: the parent's workspace,
65
+ * its direct lineage, coarse product origin, the recursion budget that must
66
+ * survive persistence, the seed boundary that separates inherited parent
67
+ * history from child work, and the composition the child runs under.
68
+ *
69
+ * The preset is read from the parent's LIVE scope chain rather than from its
70
+ * header, because a parent that switched preset while blank runs on the newer
71
+ * composition and its header still names the older one. Recording it is what
72
+ * makes a child's history reconstructable: without it a cold read of the child
73
+ * resolves the deployment default and rebuilds turns under a tool set the
74
+ * child never had.
75
+ * @param parent - the delegating parent agent.
76
+ * @param childDepth - the resolved delegation depth to persist.
77
+ * @param lineageSeedLength - how many leading events came from the parent's log.
78
+ * @returns the `meta` for `ctx.agents.create()`.
79
+ */
80
+ export function childSessionMeta(parent, childDepth, lineageSeedLength) {
81
+ const parentHeader = parent.session.header;
82
+ const agentPreset = parent.ctx.get('agentPresets')?.composedPreset(parent.ctx);
83
+ return {
84
+ ...parentHeader.cwd !== undefined ? { cwd: parentHeader.cwd } : {},
85
+ ...agentPreset === undefined ? {} : { agentPreset },
86
+ parentSession: parentHeader.id,
87
+ // Navigation classification only; the descriptor remains the authority
88
+ // for mode and continuation capability.
89
+ origin: 'subagent',
90
+ // Durable: the recursion budget must survive persistence and resume.
91
+ delegationDepth: childDepth,
92
+ ...lineageSeedLength > 0 ? { seedLength: lineageSeedLength } : {},
93
+ };
94
+ }
95
+ /**
96
+ * Model-facing delegation-scope statement for every in-process child. A
97
+ * runtime-context contribution rather than a system-prompt section, so the
98
+ * deployment's system prompt stays uniform across parents and children.
99
+ */
100
+ export const SUBAGENT_DELEGATION_CONTEXT = 'You are a delegated subagent: your permission scope was fixed when you were started and cannot be '
101
+ + 'widened from inside this session — operations that require approval are rejected automatically. '
102
+ + 'When the task needs access beyond that scope, do not retry the denied operation; state the '
103
+ + 'limitation in your reply so the delegating agent can handle it.';
104
+ /**
105
+ * Compose one child inside its creation window: join its parent's preset,
106
+ * register the fixed delegation-scope statement, then apply the child's own
107
+ * shadowing persona section and tool restriction, all owned by the child's
108
+ * scope and therefore invisible to its parent and siblings. Creation and cold
109
+ * resume both pass through here.
110
+ *
111
+ * The join comes first and the child's own registrations second, which is the
112
+ * order the layering already implies — the nearest scope wins a name, and a
113
+ * per-child restriction intersects with everything its chain admits — but
114
+ * stating it here keeps the two steps from being read as independent.
115
+ *
116
+ * The join and the per-child registrations live in ONE call because a child
117
+ * composed without the join is exactly the defect this function exists to
118
+ * prevent: with every model-facing row on the agent plane, a child that joins
119
+ * no preset sees an empty tool registry and none of its parent's prompt
120
+ * sections. Taking the parent as a parameter is what makes that omission
121
+ * unrepresentable at the call sites.
122
+ * @param childCtx - the child agent's scoped creation context.
123
+ * @param parent - the delegating parent whose composition the child joins.
124
+ * @param composition - the per-child persona and tool filter to install.
125
+ */
126
+ export function applyChildComposition(childCtx, parent, composition) {
127
+ childCtx.get('agentPresets')?.composeFrom(childCtx, parent.ctx);
128
+ // Order 120: after the sandbox:policy (110) and approval:policy (115) sentences.
129
+ childCtx.systemPrompt.context({ name: 'subagent:delegation', order: 120, text: SUBAGENT_DELEGATION_CONTEXT });
130
+ if (composition.persona !== undefined) {
131
+ childCtx.systemPrompt.section({ name: 'deployment:persona', order: 0, text: composition.persona });
132
+ }
133
+ if (composition.toolFilter !== undefined)
134
+ childCtx.tools.restrict(composition.toolFilter);
135
+ }
136
+ /**
137
+ * Capture the policy to seed into one delegation. Call synchronously before
138
+ * the child start's first await: a later parent switch belongs to the
139
+ * parent's future, not to this child. Only the parent session's explicit
140
+ * sandbox override is captured — never deployment defaults or one-shot
141
+ * grants — and the approval policy is pinned to `'never'` regardless of the
142
+ * parent's own policy.
143
+ * @param parent - the delegating parent agent.
144
+ * @returns the sandbox override (or `undefined` without one) and the approval pin.
145
+ */
146
+ export function captureDelegatedPolicyOverrides(parent) {
147
+ return {
148
+ sandboxMode: parent.ctx.get('sandboxPolicy')?.overrideOf(parent.session),
149
+ approvalPolicy: parent.ctx.get('approval') === undefined ? undefined : 'never',
150
+ };
151
+ }
152
+ /**
153
+ * Append the captured delegation policy onto the child's own log as
154
+ * `source: 'delegation'` events inside the unpublished creation window, so the
155
+ * child's effective policy is reconstructable from its log alone. Appends land
156
+ * after any fork seed, so fresh policy wins stale seed state; later child
157
+ * switches still win over these events.
158
+ * @param childSession - the unpublished child's session.
159
+ * @param overrides - the policy captured at delegation.
160
+ */
161
+ export function appendDelegatedPolicyOverrides(childSession, overrides) {
162
+ if (overrides.sandboxMode !== undefined) {
163
+ childSession.append('sandbox/mode', { mode: overrides.sandboxMode, source: 'delegation' });
164
+ }
165
+ if (overrides.approvalPolicy !== undefined) {
166
+ childSession.append('approval/policy', { policy: overrides.approvalPolicy, source: 'delegation' });
167
+ }
168
+ }
169
+ //# sourceMappingURL=child-agent.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Browser-safe subagent projection vocabulary.
3
+ *
4
+ * @module @hydraharness/harness-subagent/client
5
+ */
6
+ export type { SubagentIdentityProjection, SubagentTimingProjection } from './projection-types.ts';
7
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Browser-safe subagent projection vocabulary.
3
+ *
4
+ * @module @hydraharness/harness-subagent/client
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1,457 @@
1
+ /**
2
+ * Internal continuable-subagent manager: stable child ids, descriptor
3
+ * persistence, activation admission, the live ownership graph, cold resume,
4
+ * child-first disposal, and settlement delivery to the parent, behind
5
+ * `ctx.subagents`.
6
+ *
7
+ * A continuable child has one durable Session and at most one process-local
8
+ * {@link Activation} — one residency epoch for a reconstructed child Agent. An
9
+ * Activation is not a request, result, cancellation, or Task boundary: it may
10
+ * execute many FIFO turns and stays resident while descendants it created are
11
+ * still running. The Agent inbox is the only turn queue, so this manager owns
12
+ * residency while the Agent loop owns all turn ordering and execution. No
13
+ * continuable path creates a Task or an intermediate result-bearing wrapper.
14
+ *
15
+ * Because residency is this manager's alone to end, telling the parent that a
16
+ * child settled is its job too. An external `subagent/end` listener cannot do
17
+ * it correctly: that payload names no parent, the child handle is already
18
+ * disposed by then, and the release that wakes the parent's own settlement
19
+ * watcher has already run. See {@link SubagentContinuationManager.notifySettlement}.
20
+ *
21
+ * @module @hydraharness/harness-subagent
22
+ */
23
+ import type { Context } from '@hydraharness/cordis';
24
+ import type { Agent } from '@hydraharness/harness-agent';
25
+ import type { ContentBlock, MessageId, MessageSource } from '@hydraharness/harness-llm';
26
+ import { SessionId } from '@hydraharness/harness-session';
27
+ import type { SubagentDescriptorData } from './descriptor.ts';
28
+ import type { ContinuableCreateRequest, ContinuableCreateSpec, SubagentStartRequest } from './types.ts';
29
+ import type { ActivationObserver } from './lifecycle.ts';
30
+ import type SubagentActivationSetupRegistry from './activation-setup-registry.ts';
31
+ /** Attribution for a model coordinator's follow-up to one of its children. */
32
+ export interface CoordinatorMessageSource {
33
+ readonly kind: 'coordinator';
34
+ /** A message another agent addressed to this one (`relay` context form). */
35
+ readonly form: 'relay';
36
+ /** Session id of the agent whose tool call produced the follow-up. */
37
+ readonly senderSessionId: SessionId;
38
+ }
39
+ /** Durable attribution for a continuable child's explicit parent report. */
40
+ export interface SubagentReportMessageSource {
41
+ readonly kind: 'subagent-report';
42
+ /** A message another agent addressed to this one (`relay` context form). */
43
+ readonly form: 'relay';
44
+ /** Session id of the reporting child. */
45
+ readonly senderSessionId: SessionId;
46
+ }
47
+ /**
48
+ * Durable attribution for the runtime's own account of a continuable child
49
+ * settling. Deliberately a different kind from
50
+ * {@link SubagentReportMessageSource}: a report is content the child chose,
51
+ * while this message is the manager stating what became of the child, and a
52
+ * transcript that merged them would credit the child with words it never wrote.
53
+ */
54
+ export interface SubagentSettledMessageSource {
55
+ readonly kind: 'subagent-settled';
56
+ /** A runtime account shown without expanding the row (`notice` context form). */
57
+ readonly form: 'notice';
58
+ /** One-line account of how the child ended. */
59
+ readonly summary: string;
60
+ /** Session id of the child that settled. */
61
+ readonly senderSessionId: SessionId;
62
+ }
63
+ declare module '@hydraharness/harness-llm' {
64
+ interface MessageSourceMap {
65
+ coordinator: CoordinatorMessageSource;
66
+ 'subagent-report': SubagentReportMessageSource;
67
+ 'subagent-settled': SubagentSettledMessageSource;
68
+ }
69
+ }
70
+ /** Deployment scheduling policy for accepted child reports. */
71
+ export type SubagentReportDelivery = 'quiet' | 'next-step';
72
+ /** Options for one continuable child's report to its direct parent. */
73
+ export interface SubagentReportOptions {
74
+ /** Already-resolved parent scheduling policy. */
75
+ readonly delivery: SubagentReportDelivery;
76
+ /** Caller cancellation, owning authorization and admission until acceptance. */
77
+ readonly signal: AbortSignal;
78
+ }
79
+ /** What a caller asks for when starting a continuable background child. */
80
+ export interface ContinuableStartSpec {
81
+ /** The `ctx.subagents` provider whose continuable-creation capability establishes the child. */
82
+ readonly provider: string;
83
+ /** The initial delegation's short `description`, persisted as the child's creation label. */
84
+ readonly label: string;
85
+ /**
86
+ * Optional caller-reserved child identity. Omission preserves the manager's
87
+ * UUID allocation; supplying one lets a durable parent record provisioning
88
+ * before child materialization without a second identity handshake.
89
+ */
90
+ readonly childId?: SessionId;
91
+ /**
92
+ * The delegation request. The manager reserves the stable child id, resolves
93
+ * the durable descriptor, and composes the child itself.
94
+ */
95
+ readonly request: Omit<SubagentStartRequest, 'label' | 'signal' | 'outputSchema'>;
96
+ /** Caller cancellation, owning the operation only until inbox acceptance. */
97
+ readonly signal: AbortSignal;
98
+ }
99
+ /** Identities returned once a continuable child accepted its initial prompt. */
100
+ export interface ContinuableStart {
101
+ /** The durable child session id, stable across activations. */
102
+ readonly childId: SessionId;
103
+ /** The accepted initial prompt's inbox message id. */
104
+ readonly messageId: MessageId;
105
+ }
106
+ /**
107
+ * Authority under which one interrupt request is admitted. `user` carries the
108
+ * durable direct-parent address a human client presented; `ancestor` carries
109
+ * the exact live Agent object whose recorded lineage must contain the caller.
110
+ */
111
+ export type SubagentInterruptAuthority = {
112
+ readonly kind: 'user';
113
+ readonly parentSessionId: SessionId;
114
+ } | {
115
+ readonly kind: 'ancestor';
116
+ readonly agent: Agent;
117
+ };
118
+ /** Options for following up with one continuable child. */
119
+ export interface SubagentFollowupOptions {
120
+ /** Durable attribution retained on the delivered message; it grants no authority. */
121
+ readonly source: MessageSource;
122
+ /** Caller cancellation, owning the operation only until inbox acceptance. */
123
+ readonly signal: AbortSignal;
124
+ }
125
+ /**
126
+ * Hooks the manager needs from the owning service. Declared here, by the
127
+ * dependent, so the manager states exactly what it requires instead of
128
+ * depending back on the whole {@link SubagentRuntime}. Package-private: no
129
+ * consumer outside this package supplies a host.
130
+ */
131
+ interface ContinuationHost {
132
+ /** Reserve one tree slot before setup; release after rollback or residency disposal. */
133
+ admit(parent: Agent, creating: boolean): () => void;
134
+ /**
135
+ * Resolve one provider's continuable-creation contribution, or reject when
136
+ * the provider is unknown or lacks the capability.
137
+ * @param name - the configured provider name.
138
+ * @param request - the reserved identity, delegating parent, and cancellation.
139
+ * @returns the provider's detached creation spec.
140
+ */
141
+ prepareContinuable(name: string, request: ContinuableCreateRequest): Promise<ContinuableCreateSpec>;
142
+ /**
143
+ * Build the lifecycle observer for one Activation's residency epoch.
144
+ * @param provider - the provider name recorded in the durable descriptor.
145
+ * @param childId - the durable child session id.
146
+ * @param parent - the exact live direct parent for scoped dispatch.
147
+ * @returns the observer whose edges this epoch publishes.
148
+ */
149
+ observeActivation(provider: string, childId: SessionId, parent: Agent): ActivationObserver;
150
+ }
151
+ /**
152
+ * The continuable-subagent orchestration service behind `ctx.subagents`. Tool
153
+ * schema and host adapters are consumers of this one contract; foreground
154
+ * one-shot delegation keeps calling `ctx.subagents.start()` and never enters
155
+ * this lifecycle.
156
+ */
157
+ export declare class SubagentContinuationManager {
158
+ private readonly ctx;
159
+ private readonly host;
160
+ private readonly setupRegistry;
161
+ /** Child session id → its live Activation. Process-local, never durable. */
162
+ private activations;
163
+ /** Materializations admitted before drain, tracked through publication or rollback. */
164
+ private readonly materializations;
165
+ private readonly locks;
166
+ /** Structural Cordis owner of every Activation handle. */
167
+ private readonly ownerCtx;
168
+ /**
169
+ * Exact roots whose host teardown has begun, with the live lineage members
170
+ * observed under each root. Entries remain until that exact root leaves the
171
+ * Agent registry, closing admission throughout its host's teardown without
172
+ * poisoning a later same-id replacement.
173
+ */
174
+ private readonly closingScopes;
175
+ private draining;
176
+ constructor(ctx: Context, host: ContinuationHost, setupRegistry: SubagentActivationSetupRegistry);
177
+ /**
178
+ * Start one continuable background child: reserve its durable identity,
179
+ * resolve the provider's detached creation spec, create the child Agent
180
+ * through the private activation-owner scope, establish any continuable-parent
181
+ * ownership, and submit the initial prompt. Resolves when inbox acceptance
182
+ * yields the message id — without waiting for the turn to start or for the
183
+ * message to reach the Session log.
184
+ *
185
+ * Every failure before that acceptance rejects without either id, disposing
186
+ * any created handle and rolling back the Activation and parent ownership.
187
+ * The caller signal owns lookup, materialization, and admission only until
188
+ * acceptance; afterwards the manager owns the Activation independently.
189
+ * @param spec - provider, delegation request, and caller cancellation.
190
+ * @returns the durable child id and the accepted initial prompt's message id.
191
+ */
192
+ startContinuable(spec: ContinuableStartSpec): Promise<ContinuableStart>;
193
+ /** Reject one child identity already owned by a live Agent or Session. */
194
+ private assertChildIdAvailable;
195
+ /**
196
+ * Deliver one later message to a known continuable child as its next FIFO
197
+ * turn. Routing depends only on Activation residency: a `running` Activation
198
+ * enqueues, a `waiting` one wakes the same Agent, and an absent one
199
+ * cold-resumes a new Activation from the persisted Session. The Agent inbox
200
+ * is the only queue, so every accepted message has one observable order.
201
+ *
202
+ * The caller signal owns lookup, materialization, and admission only until
203
+ * inbox acceptance; afterwards the accepted turn cannot be cancelled through
204
+ * this service.
205
+ * @param parent - the exact live direct parent authorizing this delivery.
206
+ * @param childId - the durable child session id.
207
+ * @param content - the user-role content to deliver.
208
+ * @param options - the message source fields and caller cancellation.
209
+ * @returns the accepted message's inbox id.
210
+ * @throws when parent authority, availability, or admission rejects the delivery.
211
+ */
212
+ followup(parent: Agent, childId: SessionId, content: ContentBlock[], options: SubagentFollowupOptions): Promise<MessageId>;
213
+ /**
214
+ * Interrupt one live continuable child's current turn. Admission is
215
+ * synchronous and the effect is asynchronous: this authorizes the caller,
216
+ * requests `Agent.cancel(cause, { keepInbox: true })` on the target, and
217
+ * returns without waiting for the target to observe the signal or reach
218
+ * quiescence. The Activation, its handle, accepted unclaimed inbox work, and
219
+ * already-published descendants are untouched; work already claimed into the
220
+ * interrupted turn is not requeued. Once the interrupted driver is idle, a
221
+ * waking send resumes the parked queue.
222
+ *
223
+ * An absent target is an accepted no-op, which uniformly covers natural
224
+ * completion races, repeated requests, one-shot ids, and unknown ids without
225
+ * consulting the durable catalog. A target whose disposal transaction is
226
+ * already open is likewise an accepted no-op after authorization.
227
+ * @param targetSessionId - the durable child session id to interrupt.
228
+ * @param authority - the human parent address or exact live ancestor Agent.
229
+ * @throws {SubagentError} `UNAUTHORIZED` when the presented authority does
230
+ * not own the live target: a stale or self-targeting ancestor caller, a
231
+ * parent address that is not the live target's durable direct parent, or
232
+ * an ancestor outside the target's recorded live lineage.
233
+ */
234
+ interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;
235
+ /**
236
+ * Deliver explicitly selected content from one resident continuable child to
237
+ * its durable direct parent. Sender authorization, parent resolution, and
238
+ * send acceptance share one no-await span. Reporting neither concludes the
239
+ * child's turn nor changes its Activation lifetime.
240
+ * @param child - exact live reporting child; this is the authority credential.
241
+ * @param content - selected model-facing content.
242
+ * @param options - scheduling policy and pre-acceptance cancellation.
243
+ * @returns the stable identity of the message accepted by the parent.
244
+ * @throws {SubagentError} when the sender is unauthorized, the parent is not
245
+ * live, or continuation admission is closing.
246
+ */
247
+ reportFrom(child: Agent, content: ContentBlock[], options: SubagentReportOptions): Promise<MessageId>;
248
+ /** Authorize only the exact Agent of one resident Activation. */
249
+ private authorizeReporter;
250
+ /** Resolve the reporting child's live direct parent from durable lineage. */
251
+ private resolveReportParent;
252
+ /** Deliver one framed report through the selected parent scheduling preset. */
253
+ private deliverReport;
254
+ /**
255
+ * Perform one waking send to a parent, accounted against that parent's own
256
+ * Activation when it has one. Registering the id before the send is what
257
+ * keeps a continuation-managed parent from being judged quiescent in the
258
+ * window between a waking send and the microtask that admits it.
259
+ * @param parent - the exact live parent receiving the waking message.
260
+ * @param message - the message whose id is accounted.
261
+ * @param send - the synchronous waking send to perform.
262
+ */
263
+ private sendWaking;
264
+ /** Send one report while translating only the parent's own rejection. */
265
+ private sendReport;
266
+ /**
267
+ * Close admission, await every already-admitted materialization through
268
+ * publication or rollback, then dispose the stable live Activation forest
269
+ * child-first. Sibling branches drain independently: one failure is recorded
270
+ * but never prevents the remaining handles from being attempted, and the
271
+ * aggregate rejects only after every branch settles.
272
+ * @returns once materialization is quiescent and every live Activation released its handle.
273
+ * @throws an aggregate error when any branch failed to release.
274
+ */
275
+ drain(): Promise<void>;
276
+ /**
277
+ * Stop only the continuable descendants of exact live host-owned parents.
278
+ * Admission stays closed for those parent trees until each exact parent
279
+ * leaves the Agent registry; unrelated trees and manager-wide admission stay
280
+ * live.
281
+ * @param parents - exact live roots whose continuable descendants must stop.
282
+ * @returns once every retained descendant Activation released its handle.
283
+ * @throws an aggregate error after all scoped branches settle when any failed.
284
+ */
285
+ drainDescendants(parents: readonly Agent[]): Promise<void>;
286
+ /**
287
+ * Release selected resident direct children of one exact live parent without
288
+ * closing admission for the parent's other continuable children. Owned
289
+ * descendants are released recursively through the same lifecycle.
290
+ * @param parent - exact live direct parent authorizing the selected release.
291
+ * @param childIds - durable direct-child ids to release when resident.
292
+ * @returns once every selected Activation released its handle.
293
+ * @throws {SubagentError} `UNAUTHORIZED` when a resident target is not the
294
+ * parent's direct continuable child or the parent identity is stale.
295
+ */
296
+ drainChildren(parent: Agent, childIds: readonly SessionId[]): Promise<void>;
297
+ /** Dispose independent roots and report every branch failure after all settle. */
298
+ private disposeRoots;
299
+ /** Return the retained member set for one exact scoped-teardown root. */
300
+ private closingMembers;
301
+ /**
302
+ * Return the exact currently resolvable ancestry from `agent` upward. The
303
+ * first element is always the supplied identity, even when it is already
304
+ * stale; each ancestor after it must be the registry's current exact entry.
305
+ */
306
+ private liveLineage;
307
+ /**
308
+ * The teardown that closed continuable admission for this agent's lineage.
309
+ * `'manager'` is the whole manager draining; an Agent is the exact scoped root
310
+ * whose forest is closing.
311
+ * @param agent - the agent whose lineage is tested.
312
+ * @returns the closing teardown, or `undefined` while admission is open.
313
+ */
314
+ private closingTeardownFor;
315
+ /** Reject new admission once the manager or this exact parent tree began draining. */
316
+ private assertAdmitting;
317
+ /**
318
+ * Derive residency from Agent quiescence and the owned-child set. `running`
319
+ * covers an active admission, an open turn, or accepted waking inbox work.
320
+ *
321
+ * `Agent.status` alone is insufficient: it stays `idle` between an accepted
322
+ * waking send and the microtask that admits it, so a synchronous inbox
323
+ * observer would see `settled` while a turn is already queued. `accepted`
324
+ * holds the ids this manager admitted but has not yet seen drained.
325
+ */
326
+ private stateOf;
327
+ /**
328
+ * Cold-resume a persisted child: inspect and authorize its Session, fold the
329
+ * generic descriptor, create the Activation through `ctx.agents.resume()`,
330
+ * and submit the waiting turn. This never dispatches through a subagent
331
+ * provider — the persisted Session already holds the initial prefix and the
332
+ * descriptor is the whole reconstruction input.
333
+ */
334
+ private coldResume;
335
+ /**
336
+ * Submit to a freshly materialized Activation or roll it back completely.
337
+ * @param activation - the just-published Activation to admit or release.
338
+ * @param content - the initial or resumed message content.
339
+ * @param source - durable fields naming who supplied the accepted message.
340
+ * @param parent - the live direct parent authorizing admission.
341
+ * @param signal - caller cancellation owning admission until acceptance.
342
+ * @returns the accepted inbox message id.
343
+ */
344
+ private submitMaterialized;
345
+ /**
346
+ * Create or resume the child Agent through the private activation-owner
347
+ * scope, install the handle in a fresh Activation, and register ownership on
348
+ * a continuation-managed parent. Rejection leaves no Activation, no handle,
349
+ * and no ownership membership.
350
+ */
351
+ private materialize;
352
+ /**
353
+ * Perform one tracked materialization. The caller keeps the drain barrier
354
+ * registered until this either returns a resident Activation or finishes
355
+ * rollback.
356
+ */
357
+ private materializeTracked;
358
+ /**
359
+ * Release an Activation whose start edge was not published. The memoized
360
+ * transaction remains in the live map until handle disposal settles, so a
361
+ * concurrent drain or delivery observes the same closing boundary.
362
+ */
363
+ private rollbackUnpublished;
364
+ /**
365
+ * Register the child in a continuation-managed parent's owned set before the
366
+ * child can run, so that parent cannot settle while the child is live. A
367
+ * top-level or other non-continuation Agent has no Activation and stays
368
+ * outside the waiting graph.
369
+ */
370
+ private acquireOwnership;
371
+ /** Remove one child from its live owner's set and let that owner re-check settlement. */
372
+ private releaseOwnership;
373
+ /** Let a settlement watcher re-observe quiescence after ownership or inbox changes. */
374
+ private wake;
375
+ /**
376
+ * Submit one message as the child's next FIFO turn and return its accepted
377
+ * inbox id. Acceptance is the operation's success boundary; the manager owns
378
+ * the Activation independently afterwards.
379
+ */
380
+ private submit;
381
+ /**
382
+ * Account one waking send across a resident Activation's settlement window.
383
+ * @param activation - Activation receiving waking inbox work.
384
+ * @param messageId - stable identity of the message about to be sent.
385
+ * @param send - synchronous send that publishes one enqueue occurrence.
386
+ * @returns the accepted message id.
387
+ */
388
+ private admitWaking;
389
+ /**
390
+ * Cross the final admission cutoff and submit without yielding. Signal abort,
391
+ * manager drain, or Activation disposal that wins before this synchronous
392
+ * span rejects without inbox acceptance.
393
+ */
394
+ private submitAdmitted;
395
+ /**
396
+ * Authorize one operation against the durable direct-parent lineage. Other
397
+ * agents, ancestors, teams, workflows, and hosts remain rejected until an
398
+ * explicit authority protocol has a production consumer.
399
+ */
400
+ private authorizeLineage;
401
+ /**
402
+ * Follow one Activation to settlement: wait for Agent quiescence, then for
403
+ * every owned child to complete disposal, and dispose the handle once both
404
+ * hold. A `next-turn` delivered while `waiting` wakes the same Agent and
405
+ * returns it to `running`, so this re-observes rather than settling early.
406
+ */
407
+ private watchSettlement;
408
+ /**
409
+ * Stop one Activation immediately, then release it child-first. The memoized
410
+ * transaction is installed before cancellation or recursive callbacks, so
411
+ * admission and reentrant teardown converge on the same owner.
412
+ *
413
+ * The final session flush is best effort and never prevents handle disposal
414
+ * or ownership release, because retaining a child would permanently pin its
415
+ * ancestors in `waiting`.
416
+ * @param activation - the residency epoch to stop and release.
417
+ * @returns the one disposal transaction owned by this Activation.
418
+ */
419
+ private dispose;
420
+ /**
421
+ * Propagate stop synchronously, then finish the child-first release.
422
+ * @param activation - the Activation whose disposal transaction is installed.
423
+ * @returns once the handle and ownership edge are released.
424
+ */
425
+ private finishDisposal;
426
+ /**
427
+ * Tell the durable direct parent that this child produced everything it is
428
+ * going to. Unconditional for every child the caller received an id for: it
429
+ * does not consider whether the child reported, because the cases that most
430
+ * need it — a token ceiling, a model failure, cancellation, teardown — are
431
+ * exactly the ones where the child never got to choose. A materialization
432
+ * rolled back before its first acceptance stays silent, since the caller was
433
+ * told that child was not established. A parent that is no longer live is not
434
+ * an error; the child's own Session remains the durable record either way.
435
+ * A parent whose own lineage is already closing receives the notice without a
436
+ * wake, because teardown is not a reason to start a turn.
437
+ *
438
+ * Never blocks disposal. A delivery failure is logged and dropped, because
439
+ * retaining a child to retry a notice would pin its whole ancestry in
440
+ * `waiting` forever.
441
+ * @param activation - the settling Activation, still owned by its parent.
442
+ * @param terminal - how this epoch ended, as the terminal edge will report it.
443
+ */
444
+ private notifySettlement;
445
+ /**
446
+ * Request a best-effort final session flush after the child is quiescent.
447
+ * Listener failure is logged because flush participation cannot identify a
448
+ * particular persistence backend, and teardown must still release ownership.
449
+ * @param activation - the Activation whose final events should be flushed.
450
+ */
451
+ private flushFinalState;
452
+ /** Resolve the persistence service continuable children require, or fail loud. */
453
+ private requirePersistence;
454
+ }
455
+ export type { SubagentDescriptorData };
456
+ export default SubagentContinuationManager;
457
+ //# sourceMappingURL=continuation.d.ts.map