@xneog/dsh-subagent 0.1.0 → 0.1.3-alpha.1

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 (41) hide show
  1. package/README.i18n.yaml +2 -2
  2. package/README.md +108 -76
  3. package/README.zh.md +112 -80
  4. package/lib/index.js +1258 -718
  5. package/lib/typert.host.d.ts +3 -0
  6. package/lib/typert.host.js +923 -0
  7. package/lib/typert.remote-client.d.ts +27 -0
  8. package/lib/typert.remote-client.js +159 -0
  9. package/lib/types/assistant-output.d.ts +3 -3
  10. package/lib/types/assistant-output.js +8 -4
  11. package/lib/types/child-agent.d.ts +16 -5
  12. package/lib/types/child-agent.js +51 -13
  13. package/lib/types/client.d.ts +2 -1
  14. package/lib/types/client.js +1 -1
  15. package/lib/types/continuation.d.ts +100 -72
  16. package/lib/types/continuation.js +439 -169
  17. package/lib/types/control-types.d.ts +144 -0
  18. package/lib/types/control-types.js +9 -0
  19. package/lib/types/control.d.ts +67 -0
  20. package/lib/types/control.js +115 -0
  21. package/lib/types/descriptor-seed.d.ts +1 -1
  22. package/lib/types/descriptor-seed.js +1 -1
  23. package/lib/types/descriptor.d.ts +6 -1
  24. package/lib/types/descriptor.js +6 -2
  25. package/lib/types/index.d.ts +103 -69
  26. package/lib/types/index.js +436 -287
  27. package/lib/types/internal.d.ts +59 -0
  28. package/lib/types/internal.js +58 -0
  29. package/lib/types/lifecycle.js +4 -3
  30. package/lib/types/list-children.d.ts +12 -59
  31. package/lib/types/list-children.js +166 -101
  32. package/lib/types/out-of-process.d.ts +5 -2
  33. package/lib/types/out-of-process.js +42 -4
  34. package/lib/types/projection-types.d.ts +4 -3
  35. package/lib/types/projection.d.ts +55 -8
  36. package/lib/types/projection.js +33 -17
  37. package/lib/types/run-settlement.js +17 -6
  38. package/lib/types/types.d.ts +25 -0
  39. package/package.json +67 -37
  40. package/lib/types/activation-setup-registry.d.ts +0 -57
  41. package/lib/types/activation-setup-registry.js +0 -148
@@ -23,31 +23,22 @@
23
23
  import type { Context } from '@xneog/cordis';
24
24
  import type { Agent } from '@xneog/dsh-agent';
25
25
  import type { ContentBlock, MessageId, MessageSource } from '@xneog/dsh-llm';
26
- import { SessionId } from '@xneog/dsh-session';
26
+ import type { SessionId } from '@xneog/dsh-session';
27
27
  import type { SubagentDescriptorData } from './descriptor.ts';
28
28
  import type { ContinuableCreateRequest, ContinuableCreateSpec, SubagentStartRequest } from './types.ts';
29
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';
30
+ /** Durable attribution for one model-authored message between adjacent Agents. */
31
+ export interface AgentMessageSource {
32
+ readonly kind: 'agent-message';
34
33
  /** A message another agent addressed to this one (`relay` context form). */
35
34
  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. */
35
+ /** Session id of the Agent whose tool call produced the message. */
45
36
  readonly senderSessionId: SessionId;
46
37
  }
47
38
  /**
48
39
  * Durable attribution for the runtime's own account of a continuable child
49
40
  * settling. Deliberately a different kind from
50
- * {@link SubagentReportMessageSource}: a report is content the child chose,
41
+ * {@link AgentMessageSource}: an Agent message is content the sender chose,
51
42
  * while this message is the manager stating what became of the child, and a
52
43
  * transcript that merged them would credit the child with words it never wrote.
53
44
  */
@@ -62,26 +53,22 @@ export interface SubagentSettledMessageSource {
62
53
  }
63
54
  declare module '@xneog/dsh-llm' {
64
55
  interface MessageSourceMap {
65
- coordinator: CoordinatorMessageSource;
66
- 'subagent-report': SubagentReportMessageSource;
56
+ 'agent-message': AgentMessageSource;
67
57
  'subagent-settled': SubagentSettledMessageSource;
68
58
  }
69
59
  }
70
- /** Deployment scheduling policy for accepted child reports. */
71
- export type SubagentReportDelivery = 'quiet' | 'wakeup';
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
60
  /** What a caller asks for when starting a continuable background child. */
80
61
  export interface ContinuableStartSpec {
81
62
  /** The `ctx.subagents` provider whose continuable-creation capability establishes the child. */
82
63
  readonly provider: string;
83
64
  /** The initial delegation's short `description`, persisted as the child's creation label. */
84
65
  readonly label: string;
66
+ /**
67
+ * Optional caller-reserved child identity. Omission preserves the manager's
68
+ * UUID allocation; supplying one lets a durable parent record provisioning
69
+ * before child materialization without a second identity handshake.
70
+ */
71
+ readonly childId?: SessionId;
85
72
  /**
86
73
  * The delegation request. The manager reserves the stable child id, resolves
87
74
  * the durable descriptor, and composes the child itself.
@@ -109,10 +96,8 @@ export type SubagentInterruptAuthority = {
109
96
  readonly kind: 'ancestor';
110
97
  readonly agent: Agent;
111
98
  };
112
- /** Options for following up with one continuable child. */
113
- export interface SubagentFollowupOptions {
114
- /** Durable attribution retained on the delivered message; it grants no authority. */
115
- readonly source: MessageSource;
99
+ /** Options for one model-authored message between adjacent Agents. */
100
+ export interface SubagentSendMessageOptions {
116
101
  /** Caller cancellation, owning the operation only until inbox acceptance. */
117
102
  readonly signal: AbortSignal;
118
103
  }
@@ -149,7 +134,6 @@ interface ContinuationHost {
149
134
  export declare class SubagentContinuationManager {
150
135
  private readonly ctx;
151
136
  private readonly host;
152
- private readonly setupRegistry;
153
137
  /** Child session id → its live Activation. Process-local, never durable. */
154
138
  private activations;
155
139
  /** Materializations admitted before drain, tracked through publication or rollback. */
@@ -165,7 +149,7 @@ export declare class SubagentContinuationManager {
165
149
  */
166
150
  private readonly closingScopes;
167
151
  private draining;
168
- constructor(ctx: Context, host: ContinuationHost, setupRegistry: SubagentActivationSetupRegistry);
152
+ constructor(ctx: Context, host: ContinuationHost);
169
153
  /**
170
154
  * Start one continuable background child: reserve its durable identity,
171
155
  * resolve the provider's detached creation spec, create the child Agent
@@ -183,23 +167,59 @@ export declare class SubagentContinuationManager {
183
167
  */
184
168
  startContinuable(spec: ContinuableStartSpec): Promise<ContinuableStart>;
185
169
  /**
186
- * Deliver one later message to a known continuable child as its next FIFO
187
- * turn. Routing depends only on Activation residency: a `running` Activation
188
- * enqueues, a `waiting` one wakes the same Agent, and an absent one
189
- * cold-resumes a new Activation from the persisted Session. The Agent inbox
190
- * is the only queue, so every accepted message has one observable order.
191
- *
192
- * The caller signal owns lookup, materialization, and admission only until
193
- * inbox acceptance; afterwards the accepted turn cannot be cancelled through
194
- * this service.
195
- * @param parent - the exact live direct parent authorizing this delivery.
196
- * @param childId - the durable child session id.
197
- * @param content - the user-role content to deliver.
198
- * @param options - the message source fields and caller cancellation.
170
+ * Pre-register `childId` in a continuation-managed parent's owned set so the
171
+ * parent cannot settle while a caller is still establishing or resuming that
172
+ * child. Returns a releaser for the failure path; it removes only a hold
173
+ * this call added, and leaves ownership in place once a live Activation for
174
+ * the child exists (an admitted delivery owns it from then on). A parent
175
+ * without an Activation needs no hold: only this manager settles parents.
176
+ * @param parent - the live direct parent the operation is admitted under.
177
+ * @param childId - the durable child the operation addresses.
178
+ * @returns the failure-path releaser; a no-op when nothing was added.
179
+ * @throws {SubagentError} `ACTIVATION_CLOSING` when the parent's own
180
+ * disposal transaction is already open.
181
+ */
182
+ private holdOwnership;
183
+ /** Reject one child identity already owned by a live Agent or Session. */
184
+ private assertChildIdAvailable;
185
+ /**
186
+ * Deliver one model-authored message to a direct continuable child or to the
187
+ * sender's direct parent. Both directions use Steer: a running target admits
188
+ * the message at its nearest step boundary, while an idle target starts a
189
+ * turn. A missing direct child cold-resumes through the ordinary continuation
190
+ * lifecycle. The caller signal owns the operation only until inbox acceptance.
191
+ * @param sender - exact live Agent authorizing and originating the message.
192
+ * @param targetId - durable direct-parent or direct-child session id.
193
+ * @param content - model-authored content to deliver.
194
+ * @param options - caller cancellation before acceptance.
195
+ * @returns the accepted message's inbox id.
196
+ * @throws when adjacency, availability, or admission rejects delivery.
197
+ */
198
+ sendMessage(sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions): Promise<MessageId>;
199
+ /**
200
+ * Queue one human-authored prompt as a distinct direct-child turn.
201
+ * @param parent - exact live direct parent authorizing delivery.
202
+ * @param childId - durable direct-child session id.
203
+ * @param content - human-authored content to deliver.
204
+ * @param source - durable host-protocol provenance.
205
+ * @param signal - caller cancellation before inbox acceptance.
206
+ * @returns the accepted message's inbox id.
207
+ */
208
+ queuePrompt(parent: Agent, childId: SessionId, content: ContentBlock[], source: MessageSource, signal: AbortSignal): Promise<MessageId>;
209
+ /**
210
+ * Steer one host-authored prompt to a direct continuable child.
211
+ * @param parent - exact live direct parent authorizing delivery.
212
+ * @param childId - durable direct-child session id.
213
+ * @param content - host-authored content to deliver.
214
+ * @param source - durable host-protocol provenance.
215
+ * @param signal - caller cancellation before inbox acceptance.
199
216
  * @returns the accepted message's inbox id.
200
- * @throws when parent authority, availability, or admission rejects the delivery.
201
217
  */
202
- followup(parent: Agent, childId: SessionId, content: ContentBlock[], options: SubagentFollowupOptions): Promise<MessageId>;
218
+ steerPrompt(parent: Agent, childId: SessionId, content: ContentBlock[], source: MessageSource, signal: AbortSignal): Promise<MessageId>;
219
+ /** Route one parent-originated delivery through residency and cold resume. */
220
+ private deliverToChild;
221
+ /** The delivery loop behind {@link deliverToChild}, run under the parent hold. */
222
+ private deliverFollowup;
203
223
  /**
204
224
  * Interrupt one live continuable child's current turn. Admission is
205
225
  * synchronous and the effect is asynchronous: this authorizes the caller,
@@ -222,37 +242,20 @@ export declare class SubagentContinuationManager {
222
242
  * an ancestor outside the target's recorded live lineage.
223
243
  */
224
244
  interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;
225
- /**
226
- * Deliver explicitly selected content from one resident continuable child to
227
- * its durable direct parent. Sender authorization, parent resolution, and
228
- * send acceptance share one no-await span. Reporting neither concludes the
229
- * child's turn nor changes its Activation lifetime.
230
- * @param child - exact live reporting child; this is the authority credential.
231
- * @param content - selected model-facing content.
232
- * @param options - scheduling policy and pre-acceptance cancellation.
233
- * @returns the stable identity of the message accepted by the parent.
234
- * @throws {SubagentError} when the sender is unauthorized, the parent is not
235
- * live, or continuation admission is closing.
236
- */
237
- reportFrom(child: Agent, content: ContentBlock[], options: SubagentReportOptions): Promise<MessageId>;
238
- /** Authorize only the exact Agent of one resident Activation. */
239
- private authorizeReporter;
240
- /** Resolve the reporting child's live direct parent from durable lineage. */
241
- private resolveReportParent;
242
- /** Deliver one framed report through the selected parent scheduling preset. */
243
- private deliverReport;
245
+ /** Deliver one resident continuable child's message to its live direct parent. */
246
+ private sendToParent;
244
247
  /**
245
248
  * Perform one waking send to a parent, accounted against that parent's own
246
249
  * Activation when it has one. Registering the id before the send is what
247
250
  * keeps a continuation-managed parent from being judged quiescent in the
248
- * window between `followup()` and the microtask that admits it.
251
+ * window between a waking send and the microtask that admits it.
249
252
  * @param parent - the exact live parent receiving the waking message.
250
253
  * @param message - the message whose id is accounted.
251
254
  * @param send - the synchronous waking send to perform.
252
255
  */
253
256
  private sendWaking;
254
- /** Send one report while translating only the parent's own rejection. */
255
- private sendReport;
257
+ /** Send one Agent message while translating only the target's own rejection. */
258
+ private sendAgentMessage;
256
259
  /**
257
260
  * Close admission, await every already-admitted materialization through
258
261
  * publication or rollback, then dispose the stable live Activation forest
@@ -273,6 +276,17 @@ export declare class SubagentContinuationManager {
273
276
  * @throws an aggregate error after all scoped branches settle when any failed.
274
277
  */
275
278
  drainDescendants(parents: readonly Agent[]): Promise<void>;
279
+ /**
280
+ * Release selected resident direct children of one exact live parent without
281
+ * closing admission for the parent's other continuable children. Owned
282
+ * descendants are released recursively through the same lifecycle.
283
+ * @param parent - exact live direct parent authorizing the selected release.
284
+ * @param childIds - durable direct-child ids to release when resident.
285
+ * @returns once every selected Activation released its handle.
286
+ * @throws {SubagentError} `UNAUTHORIZED` when a resident target is not the
287
+ * parent's direct continuable child or the parent identity is stale.
288
+ */
289
+ drainChildren(parent: Agent, childIds: readonly SessionId[]): Promise<void>;
276
290
  /** Dispose independent roots and report every branch failure after all settle. */
277
291
  private disposeRoots;
278
292
  /** Return the retained member set for one exact scoped-teardown root. */
@@ -304,7 +318,7 @@ export declare class SubagentContinuationManager {
304
318
  */
305
319
  private stateOf;
306
320
  /**
307
- * Cold-resume a persisted child: inspect and authorize its Session, fold the
321
+ * Cold-resume a persisted child: retain and authorize its prepared Session, fold the
308
322
  * generic descriptor, create the Activation through `ctx.agents.resume()`,
309
323
  * and submit the waiting turn. This never dispatches through a subagent
310
324
  * provider — the persisted Session already holds the initial prefix and the
@@ -315,12 +329,24 @@ export declare class SubagentContinuationManager {
315
329
  * Submit to a freshly materialized Activation or roll it back completely.
316
330
  * @param activation - the just-published Activation to admit or release.
317
331
  * @param content - the initial or resumed message content.
318
- * @param source - durable fields naming who supplied the accepted message.
332
+ * @param options - durable source, scheduling, and pre-acceptance cancellation.
319
333
  * @param parent - the live direct parent authorizing admission.
320
- * @param signal - caller cancellation owning admission until acceptance.
321
334
  * @returns the accepted inbox message id.
322
335
  */
323
336
  private submitMaterialized;
337
+ /**
338
+ * Refuse image content addressed to a child whose model accepts text only.
339
+ * Callers guard with `contentHasImage`, so text-only delivery never awaits.
340
+ * The check runs inside the per-child delivery lock, before the message
341
+ * exists, so a rejection leaves no partial user message. When the child's
342
+ * route is not fixed by its options (a request-waterfall listener owns it)
343
+ * or no LLM registry is composed, delivery proceeds and the LLM layer's
344
+ * text-only projection replaces each image with its stable placeholder.
345
+ * @param agent - the live or freshly materialized child agent.
346
+ * @param signal - caller cancellation bounding the model-info read.
347
+ * @throws {SubagentError} `MODEL_DOES_NOT_SUPPORT_IMAGES` when the child's resolved model declines image input.
348
+ */
349
+ private assertImageCapable;
324
350
  /**
325
351
  * Create or resume the child Agent through the private activation-owner
326
352
  * scope, install the handle in a fresh Activation, and register ownership on
@@ -430,6 +456,8 @@ export declare class SubagentContinuationManager {
430
456
  private flushFinalState;
431
457
  /** Resolve the persistence service continuable children require, or fail loud. */
432
458
  private requirePersistence;
459
+ /** Resolve the Session query service used for cold child observations. */
460
+ private requireSessionQuery;
433
461
  }
434
462
  export type { SubagentDescriptorData };
435
463
  export default SubagentContinuationManager;