@deepseek-ai/dsh-subagent 0.1.2-alpha.3 → 0.1.2-alpha.4
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.
- package/README.i18n.yaml +2 -2
- package/README.md +12 -11
- package/README.zh.md +12 -11
- package/lib/index.js +187 -296
- package/lib/typert.host.js +41 -55
- package/lib/typert.remote-client.js +3 -3
- package/lib/types/child-agent.d.ts +2 -2
- package/lib/types/child-agent.js +3 -3
- package/lib/types/continuation.d.ts +37 -69
- package/lib/types/continuation.js +123 -103
- package/lib/types/descriptor-seed.d.ts +1 -1
- package/lib/types/descriptor-seed.js +1 -1
- package/lib/types/index.d.ts +29 -42
- package/lib/types/index.js +34 -47
- package/lib/types/internal.d.ts +46 -0
- package/lib/types/internal.js +45 -0
- package/lib/types/lifecycle.js +4 -3
- package/lib/types/list-children.d.ts +6 -5
- package/lib/types/list-children.js +23 -22
- package/lib/types/projection-types.d.ts +4 -3
- package/lib/types/projection.js +3 -2
- package/package.json +48 -44
- package/lib/types/activation-setup-registry.d.ts +0 -57
- package/lib/types/activation-setup-registry.js +0 -148
|
@@ -75,11 +75,13 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
75
75
|
import { randomUUID } from 'node:crypto';
|
|
76
76
|
import { brandString } from '@deepseek-ai/dsh-brand';
|
|
77
77
|
import { ReasoningEffortId, boundContextSummary, contentHasImage, createUserMessage, errorChain } from '@deepseek-ai/dsh-llm';
|
|
78
|
+
import { SessionLogOffset } from '@deepseek-ai/dsh-session';
|
|
78
79
|
import { foldSubagentDescriptor, snapshotSubagentDescriptor } from "./descriptor.js";
|
|
79
80
|
import { appendDelegatedPolicyOverrides, applyChildComposition, captureDelegatedPolicyOverrides, childSessionMeta, resolveChildAgentOptions, resolveChildDepth, } from "./child-agent.js";
|
|
80
81
|
import { assertSubagentMaxDepth } from "./depth.js";
|
|
81
82
|
import { seedDescriptorTurn } from "./descriptor-seed.js";
|
|
82
83
|
import { SubagentError } from "./error.js";
|
|
84
|
+
import { isAdjacentAgentSendMessageTool } from "./internal.js";
|
|
83
85
|
/**
|
|
84
86
|
* Read one Activation's current disposal transaction. This indirection exists
|
|
85
87
|
* because TypeScript would otherwise narrow repeated reads of the mutable field
|
|
@@ -90,6 +92,39 @@ import { SubagentError } from "./error.js";
|
|
|
90
92
|
function disposalOf(activation) {
|
|
91
93
|
return activation.disposal;
|
|
92
94
|
}
|
|
95
|
+
/** Build durable attribution for one adjacent-Agent message. */
|
|
96
|
+
function agentMessageSource(sender) {
|
|
97
|
+
return {
|
|
98
|
+
kind: 'agent-message',
|
|
99
|
+
form: 'relay',
|
|
100
|
+
senderSessionId: sender.id,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/** Build the model-visible and durable representation of one adjacent-Agent message. */
|
|
104
|
+
function agentMessage(sender, content) {
|
|
105
|
+
return createUserMessage({
|
|
106
|
+
content: [
|
|
107
|
+
{ type: 'text', text: `Agent ${sender.id} sent a message:` },
|
|
108
|
+
...content,
|
|
109
|
+
],
|
|
110
|
+
source: agentMessageSource(sender),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/** Append adjacent-Agent return guidance to a continuable child's initial task. */
|
|
114
|
+
function continuableInitialPrompt(parentId, prompt) {
|
|
115
|
+
const encodedParentId = JSON.stringify(parentId);
|
|
116
|
+
return [
|
|
117
|
+
...prompt,
|
|
118
|
+
{
|
|
119
|
+
type: 'text',
|
|
120
|
+
text: `Your parent agent id is ${encodedParentId}. Before you finish, send your result to that agent with `
|
|
121
|
+
+ `send_message({ agent_id: ${encodedParentId}, message: "<self-contained result>" }). The parent shares `
|
|
122
|
+
+ 'your workspace but does not automatically receive your transcript, tool output, or reasoning. Send '
|
|
123
|
+
+ 'earlier messages as well when a finding changes what the parent should do next; sending a message '
|
|
124
|
+
+ 'does not end your turn.',
|
|
125
|
+
},
|
|
126
|
+
];
|
|
127
|
+
}
|
|
93
128
|
/**
|
|
94
129
|
* One line telling a parent that a background child is finished and why, in
|
|
95
130
|
* the parent's own task vocabulary.
|
|
@@ -151,7 +186,6 @@ class ChildLock {
|
|
|
151
186
|
export class SubagentContinuationManager {
|
|
152
187
|
ctx;
|
|
153
188
|
host;
|
|
154
|
-
setupRegistry;
|
|
155
189
|
/** Child session id → its live Activation. Process-local, never durable. */
|
|
156
190
|
activations = new Map();
|
|
157
191
|
/** Materializations admitted before drain, tracked through publication or rollback. */
|
|
@@ -167,10 +201,9 @@ export class SubagentContinuationManager {
|
|
|
167
201
|
*/
|
|
168
202
|
closingScopes = new Map();
|
|
169
203
|
draining = false;
|
|
170
|
-
constructor(ctx, host
|
|
204
|
+
constructor(ctx, host) {
|
|
171
205
|
this.ctx = ctx;
|
|
172
206
|
this.host = host;
|
|
173
|
-
this.setupRegistry = setupRegistry;
|
|
174
207
|
// Ordinary Cordis owner effects unwind in reverse registration order, which
|
|
175
208
|
// cannot express the dynamic child graph. Register the private scope's
|
|
176
209
|
// structural disposer FIRST and the drain SECOND, so reverse unwind invokes
|
|
@@ -237,7 +270,7 @@ export class SubagentContinuationManager {
|
|
|
237
270
|
});
|
|
238
271
|
spec.signal.throwIfAborted();
|
|
239
272
|
this.assertAdmitting(parent);
|
|
240
|
-
const
|
|
273
|
+
const inheritedEventCount = SessionLogOffset(prepared.seed?.length ?? 0);
|
|
241
274
|
const seed = seedDescriptorTurn(childId, prepared.seed, descriptor);
|
|
242
275
|
const messageId = await this.locks.run(childId, async () => {
|
|
243
276
|
spec.signal.throwIfAborted();
|
|
@@ -256,12 +289,19 @@ export class SubagentContinuationManager {
|
|
|
256
289
|
childId,
|
|
257
290
|
provider: spec.provider,
|
|
258
291
|
parent,
|
|
259
|
-
create: {
|
|
292
|
+
create: {
|
|
293
|
+
seed,
|
|
294
|
+
meta: childSessionMeta(parent, childDepth, prepared.seed !== undefined),
|
|
295
|
+
inheritedEventCount,
|
|
296
|
+
delegatedPolicies,
|
|
297
|
+
},
|
|
260
298
|
agentOptions,
|
|
261
299
|
composition: { persona: request.persona, toolFilter: request.toolFilter },
|
|
262
300
|
signal: spec.signal,
|
|
263
301
|
});
|
|
264
|
-
return this.submitMaterialized(activation,
|
|
302
|
+
return this.submitMaterialized(activation, isAdjacentAgentSendMessageTool(this.ctx.get('tools')?.get('send_message', activation.handle.agent))
|
|
303
|
+
? continuableInitialPrompt(parent.id, request.prompt)
|
|
304
|
+
: request.prompt, { source: { kind: 'user' }, signal: spec.signal, delivery: 'queue' }, parent);
|
|
265
305
|
});
|
|
266
306
|
return { childId, messageId };
|
|
267
307
|
}
|
|
@@ -272,23 +312,52 @@ export class SubagentContinuationManager {
|
|
|
272
312
|
}
|
|
273
313
|
}
|
|
274
314
|
/**
|
|
275
|
-
* Deliver one
|
|
276
|
-
*
|
|
277
|
-
*
|
|
278
|
-
*
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* @param parent - the exact live direct parent authorizing this delivery.
|
|
285
|
-
* @param childId - the durable child session id.
|
|
286
|
-
* @param content - the user-role content to deliver.
|
|
287
|
-
* @param options - the message source fields and caller cancellation.
|
|
315
|
+
* Deliver one model-authored message to a direct continuable child or to the
|
|
316
|
+
* sender's direct parent. Both directions use Steer: a running target admits
|
|
317
|
+
* the message at its nearest step boundary, while an idle target starts a
|
|
318
|
+
* turn. A missing direct child cold-resumes through the ordinary continuation
|
|
319
|
+
* lifecycle. The caller signal owns the operation only until inbox acceptance.
|
|
320
|
+
* @param sender - exact live Agent authorizing and originating the message.
|
|
321
|
+
* @param targetId - durable direct-parent or direct-child session id.
|
|
322
|
+
* @param content - model-authored content to deliver.
|
|
323
|
+
* @param options - caller cancellation before acceptance.
|
|
288
324
|
* @returns the accepted message's inbox id.
|
|
289
|
-
* @throws when
|
|
325
|
+
* @throws when adjacency, availability, or admission rejects delivery.
|
|
290
326
|
*/
|
|
291
|
-
async
|
|
327
|
+
async sendMessage(sender, targetId, content, options) {
|
|
328
|
+
if (this.ctx.agents.get(sender.id) !== sender) {
|
|
329
|
+
throw new SubagentError('message delivery requires the exact live sender agent', 'UNAUTHORIZED');
|
|
330
|
+
}
|
|
331
|
+
this.assertAdmitting(sender);
|
|
332
|
+
const senderActivation = this.activations.get(sender.id);
|
|
333
|
+
if (senderActivation !== undefined
|
|
334
|
+
&& senderActivation.handle.agent === sender
|
|
335
|
+
&& senderActivation.parentSession === targetId) {
|
|
336
|
+
options.signal.throwIfAborted();
|
|
337
|
+
return this.sendToParent(senderActivation, sender, content);
|
|
338
|
+
}
|
|
339
|
+
if (sender.session.header.parentSession === targetId) {
|
|
340
|
+
throw new SubagentError(`agent "${sender.id}" is not a resident continuable child and cannot send to parent "${targetId}"`, 'UNAUTHORIZED');
|
|
341
|
+
}
|
|
342
|
+
return this.deliverToChild(sender, targetId, content, {
|
|
343
|
+
signal: options.signal,
|
|
344
|
+
delivery: 'steer',
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Queue one human-authored prompt as a distinct direct-child turn.
|
|
349
|
+
* @param parent - exact live direct parent authorizing delivery.
|
|
350
|
+
* @param childId - durable direct-child session id.
|
|
351
|
+
* @param content - human-authored content to deliver.
|
|
352
|
+
* @param source - durable host-protocol provenance.
|
|
353
|
+
* @param signal - caller cancellation before inbox acceptance.
|
|
354
|
+
* @returns the accepted message's inbox id.
|
|
355
|
+
*/
|
|
356
|
+
async queuePrompt(parent, childId, content, source, signal) {
|
|
357
|
+
return this.deliverToChild(parent, childId, content, { source, signal, delivery: 'queue' });
|
|
358
|
+
}
|
|
359
|
+
/** Route one parent-originated delivery through residency and cold resume. */
|
|
360
|
+
async deliverToChild(parent, childId, content, options) {
|
|
292
361
|
this.assertAdmitting(parent);
|
|
293
362
|
while (true) {
|
|
294
363
|
const live = await this.locks.run(childId, async () => {
|
|
@@ -317,7 +386,7 @@ export class SubagentContinuationManager {
|
|
|
317
386
|
return undefined;
|
|
318
387
|
}
|
|
319
388
|
}
|
|
320
|
-
return this.submitAdmitted(activation, content, options
|
|
389
|
+
return this.submitAdmitted(activation, content, options, parent);
|
|
321
390
|
});
|
|
322
391
|
/* v8 ignore start -- only the lost-cutoff arm above returns undefined, so only that
|
|
323
392
|
* race reaches the retry below, which then cold-resumes a new Activation. */
|
|
@@ -378,68 +447,19 @@ export class SubagentContinuationManager {
|
|
|
378
447
|
return;
|
|
379
448
|
activation.handle.agent.cancel(authority.kind === 'user' ? { kind: 'user' } : { kind: 'parent' }, { keepInbox: true });
|
|
380
449
|
}
|
|
381
|
-
/**
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
* child's turn nor changes its Activation lifetime.
|
|
386
|
-
* @param child - exact live reporting child; this is the authority credential.
|
|
387
|
-
* @param content - selected model-facing content.
|
|
388
|
-
* @param options - scheduling policy and pre-acceptance cancellation.
|
|
389
|
-
* @returns the stable identity of the message accepted by the parent.
|
|
390
|
-
* @throws {SubagentError} when the sender is unauthorized, the parent is not
|
|
391
|
-
* live, or continuation admission is closing.
|
|
392
|
-
*/
|
|
393
|
-
// oxlint-disable-next-line typescript/require-await -- keep rejection semantics without yielding during admission
|
|
394
|
-
async reportFrom(child, content, options) {
|
|
395
|
-
options.signal.throwIfAborted();
|
|
396
|
-
this.assertAdmitting(child);
|
|
397
|
-
const activation = this.authorizeReporter(child);
|
|
398
|
-
const parent = this.resolveReportParent(child);
|
|
399
|
-
return this.deliverReport(activation, parent, content, options.delivery);
|
|
400
|
-
}
|
|
401
|
-
/** Authorize only the exact Agent of one resident Activation. */
|
|
402
|
-
authorizeReporter(child) {
|
|
403
|
-
const activation = this.activations.get(child.id);
|
|
404
|
-
if (activation === undefined || activation.handle.agent !== child) {
|
|
405
|
-
throw new SubagentError(`agent "${child.id}" is not a live continuable subagent and cannot report`, 'UNAUTHORIZED');
|
|
406
|
-
}
|
|
407
|
-
/* v8 ignore next 6 -- only a synchronous re-entrant disposer can open this
|
|
408
|
-
* transaction between exact-agent authorization and this no-await cutoff. */
|
|
450
|
+
/** Deliver one resident continuable child's message to its live direct parent. */
|
|
451
|
+
sendToParent(activation, sender, content) {
|
|
452
|
+
/* v8 ignore next 6 -- only synchronous re-entrant teardown can open this
|
|
453
|
+
* transaction between exact-agent authorization and this no-await span. */
|
|
409
454
|
if (activation.disposal !== undefined) {
|
|
410
|
-
throw new SubagentError(`subagent "${
|
|
455
|
+
throw new SubagentError(`subagent "${sender.id}" activation is being disposed; the message was not delivered`, 'ACTIVATION_CLOSING');
|
|
411
456
|
}
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
/** Resolve the reporting child's live direct parent from durable lineage. */
|
|
415
|
-
resolveReportParent(child) {
|
|
416
|
-
const parentId = child.session.header.parentSession;
|
|
417
|
-
/* v8 ignore next -- every continuation-managed child has direct-parent metadata. */
|
|
418
|
-
const parent = parentId === undefined ? undefined : this.ctx.agents.get(parentId);
|
|
457
|
+
const parent = this.ctx.agents.get(activation.parentSession);
|
|
419
458
|
if (parent === undefined) {
|
|
420
|
-
throw new SubagentError('direct parent is not live;
|
|
421
|
-
}
|
|
422
|
-
return parent;
|
|
423
|
-
}
|
|
424
|
-
/** Deliver one framed report through the selected parent scheduling preset. */
|
|
425
|
-
deliverReport(activation, parent, content, delivery) {
|
|
426
|
-
const message = createUserMessage({
|
|
427
|
-
content: [
|
|
428
|
-
{ type: 'text', text: `Background subagent ${activation.childId} reported:` },
|
|
429
|
-
...content,
|
|
430
|
-
],
|
|
431
|
-
source: {
|
|
432
|
-
kind: 'subagent-report',
|
|
433
|
-
form: 'relay',
|
|
434
|
-
senderSessionId: activation.childId,
|
|
435
|
-
},
|
|
436
|
-
});
|
|
437
|
-
if (delivery === 'next-step') {
|
|
438
|
-
this.sendWaking(parent, message, () => { this.sendReport(parent, message, delivery); });
|
|
439
|
-
}
|
|
440
|
-
else {
|
|
441
|
-
this.sendReport(parent, message, delivery);
|
|
459
|
+
throw new SubagentError('direct parent is not live; the message was not delivered', 'PARENT_UNAVAILABLE');
|
|
442
460
|
}
|
|
461
|
+
const message = agentMessage(sender, content);
|
|
462
|
+
this.sendWaking(parent, message, () => { this.sendAgentMessage(parent, message); });
|
|
443
463
|
return message.id;
|
|
444
464
|
}
|
|
445
465
|
/**
|
|
@@ -460,16 +480,13 @@ export class SubagentContinuationManager {
|
|
|
460
480
|
send();
|
|
461
481
|
}
|
|
462
482
|
}
|
|
463
|
-
/** Send one
|
|
464
|
-
|
|
483
|
+
/** Send one Agent message while translating only the target's own rejection. */
|
|
484
|
+
sendAgentMessage(parent, message) {
|
|
465
485
|
try {
|
|
466
|
-
|
|
467
|
-
parent.steer(message);
|
|
468
|
-
else
|
|
469
|
-
parent.inject(message);
|
|
486
|
+
parent.steer(message);
|
|
470
487
|
}
|
|
471
488
|
catch (error) {
|
|
472
|
-
throw new SubagentError('direct parent is not live;
|
|
489
|
+
throw new SubagentError('direct parent is not live; the message was not delivered', 'PARENT_UNAVAILABLE', { cause: error });
|
|
473
490
|
}
|
|
474
491
|
}
|
|
475
492
|
/**
|
|
@@ -706,10 +723,9 @@ export class SubagentContinuationManager {
|
|
|
706
723
|
// Fold only the child's own suffix: a fork seed replays the parent's log,
|
|
707
724
|
// which may carry an ANCESTOR's descriptor when the parent is itself a
|
|
708
725
|
// continuable child.
|
|
709
|
-
const descriptor = foldSubagentDescriptor(source.events.slice(source.
|
|
726
|
+
const descriptor = foldSubagentDescriptor(source.events.slice(source.inheritedEventCount));
|
|
710
727
|
if (descriptor === undefined || descriptor.mode !== 'continuable') {
|
|
711
|
-
throw new SubagentError(`subagent "${childId}" has no supported continuation state and cannot be resumed;
|
|
712
|
-
+ 'do not retry send_message with this id', 'NOT_RESUMABLE');
|
|
728
|
+
throw new SubagentError(`subagent "${childId}" has no supported continuation state and cannot be resumed; choose a different target`, 'NOT_RESUMABLE');
|
|
713
729
|
}
|
|
714
730
|
let activation;
|
|
715
731
|
try {
|
|
@@ -734,7 +750,7 @@ export class SubagentContinuationManager {
|
|
|
734
750
|
throw error;
|
|
735
751
|
throw new SubagentError(`subagent "${childId}" is unavailable`, 'NOT_RESUMABLE', { cause: error });
|
|
736
752
|
}
|
|
737
|
-
return await this.submitMaterialized(activation, content, options
|
|
753
|
+
return await this.submitMaterialized(activation, content, options, parent);
|
|
738
754
|
}
|
|
739
755
|
catch (e_1) {
|
|
740
756
|
env_1.error = e_1;
|
|
@@ -748,23 +764,22 @@ export class SubagentContinuationManager {
|
|
|
748
764
|
* Submit to a freshly materialized Activation or roll it back completely.
|
|
749
765
|
* @param activation - the just-published Activation to admit or release.
|
|
750
766
|
* @param content - the initial or resumed message content.
|
|
751
|
-
* @param
|
|
767
|
+
* @param options - durable source, scheduling, and pre-acceptance cancellation.
|
|
752
768
|
* @param parent - the live direct parent authorizing admission.
|
|
753
|
-
* @param signal - caller cancellation owning admission until acceptance.
|
|
754
769
|
* @returns the accepted inbox message id.
|
|
755
770
|
*/
|
|
756
|
-
async submitMaterialized(activation, content,
|
|
771
|
+
async submitMaterialized(activation, content, options, parent) {
|
|
757
772
|
try {
|
|
758
773
|
if (contentHasImage(content)) {
|
|
759
774
|
// The capability read awaits with the activation already published, so
|
|
760
775
|
// the disposal cutoff is re-checked before the submit; a drain that
|
|
761
776
|
// began during the read turns into a clean closing rejection.
|
|
762
|
-
await this.assertImageCapable(activation.handle.agent, signal);
|
|
777
|
+
await this.assertImageCapable(activation.handle.agent, options.signal);
|
|
763
778
|
if (activation.disposal !== undefined) {
|
|
764
779
|
throw new SubagentError(`subagent "${activation.childId}" is closing`, 'ACTIVATION_CLOSING');
|
|
765
780
|
}
|
|
766
781
|
}
|
|
767
|
-
return this.submitAdmitted(activation, content,
|
|
782
|
+
return this.submitAdmitted(activation, content, options, parent);
|
|
768
783
|
}
|
|
769
784
|
catch (error) {
|
|
770
785
|
/* v8 ignore next -- rollback disposal failures must not mask the
|
|
@@ -839,7 +854,6 @@ export class SubagentContinuationManager {
|
|
|
839
854
|
appendDelegatedPolicyOverrides(childCtx.agent.session, create.delegatedPolicies);
|
|
840
855
|
}
|
|
841
856
|
applyChildComposition(childCtx, parent, inputs.composition);
|
|
842
|
-
return this.setupRegistry.apply(childCtx);
|
|
843
857
|
};
|
|
844
858
|
const observer = this.host.observeActivation(provider, childId, parent);
|
|
845
859
|
// Agent creation owns rollback before handle transfer. A rejection leaves
|
|
@@ -855,6 +869,7 @@ export class SubagentContinuationManager {
|
|
|
855
869
|
sessionId: childId,
|
|
856
870
|
meta: create.meta,
|
|
857
871
|
seed: create.seed,
|
|
872
|
+
inheritedEventCount: create.inheritedEventCount,
|
|
858
873
|
agentOptions: inputs.agentOptions,
|
|
859
874
|
signal: inputs.signal,
|
|
860
875
|
setup,
|
|
@@ -962,13 +977,18 @@ export class SubagentContinuationManager {
|
|
|
962
977
|
* inbox id. Acceptance is the operation's success boundary; the manager owns
|
|
963
978
|
* the Activation independently afterwards.
|
|
964
979
|
*/
|
|
965
|
-
submit(activation, content,
|
|
980
|
+
submit(activation, content, options, parent) {
|
|
966
981
|
// Parent-originated delivery keeps the parent live through ownership, so
|
|
967
982
|
// establish it before the message can enter the child's inbox.
|
|
968
983
|
this.acquireOwnership(parent, activation.childId);
|
|
969
|
-
const message =
|
|
984
|
+
const message = options.delivery === 'steer'
|
|
985
|
+
? agentMessage(parent, content)
|
|
986
|
+
: createUserMessage({ content, source: options.source });
|
|
970
987
|
const accepted = this.admitWaking(activation, message.id, () => {
|
|
971
|
-
|
|
988
|
+
if (options.delivery === 'steer')
|
|
989
|
+
activation.handle.agent.steer(message);
|
|
990
|
+
else
|
|
991
|
+
activation.handle.agent.followup(message);
|
|
972
992
|
});
|
|
973
993
|
// Past this point the caller has an id for this child, so its eventual
|
|
974
994
|
// settlement is something the parent is owed an account of.
|
|
@@ -1003,8 +1023,8 @@ export class SubagentContinuationManager {
|
|
|
1003
1023
|
* manager drain, or Activation disposal that wins before this synchronous
|
|
1004
1024
|
* span rejects without inbox acceptance.
|
|
1005
1025
|
*/
|
|
1006
|
-
submitAdmitted(activation, content,
|
|
1007
|
-
signal.throwIfAborted();
|
|
1026
|
+
submitAdmitted(activation, content, options, parent) {
|
|
1027
|
+
options.signal.throwIfAborted();
|
|
1008
1028
|
this.assertAdmitting(parent);
|
|
1009
1029
|
/* v8 ignore next 6 -- only a synchronous re-entrant disposer can change
|
|
1010
1030
|
* this field between the caller's live check and this no-await boundary. */
|
|
@@ -1012,7 +1032,7 @@ export class SubagentContinuationManager {
|
|
|
1012
1032
|
throw new SubagentError(`subagent "${activation.childId}" activation is being disposed; the message was not accepted`, 'ACTIVATION_CLOSING');
|
|
1013
1033
|
}
|
|
1014
1034
|
this.authorizeLineage(parent, activation.childId, activation.handle.agent.session.header.parentSession);
|
|
1015
|
-
return this.submit(activation, content,
|
|
1035
|
+
return this.submit(activation, content, options, parent);
|
|
1016
1036
|
}
|
|
1017
1037
|
/**
|
|
1018
1038
|
* Authorize one operation against the durable direct-parent lineage. Other
|
|
@@ -17,5 +17,5 @@ import type { SubagentDescriptorData } from './descriptor.ts';
|
|
|
17
17
|
* @param descriptor - the snapshotted composition record to persist.
|
|
18
18
|
* @returns the complete seed events, contiguous from sequence zero.
|
|
19
19
|
*/
|
|
20
|
-
export declare function seedDescriptorTurn(childId: SessionId, seed: readonly SessionEvent[] | undefined, descriptor: SubagentDescriptorData): SessionEvent[];
|
|
20
|
+
export declare function seedDescriptorTurn(childId: SessionId, seed: readonly SessionEvent[] | undefined, descriptor: SubagentDescriptorData): readonly SessionEvent[];
|
|
21
21
|
//# sourceMappingURL=descriptor-seed.d.ts.map
|
|
@@ -19,6 +19,6 @@ import { Session } from '@deepseek-ai/dsh-session';
|
|
|
19
19
|
export function seedDescriptorTurn(childId, seed, descriptor) {
|
|
20
20
|
const staged = Session.create(childId, seed);
|
|
21
21
|
staged.append('subagent/descriptor', descriptor);
|
|
22
|
-
return
|
|
22
|
+
return staged.snapshotEvents();
|
|
23
23
|
}
|
|
24
24
|
//# sourceMappingURL=descriptor-seed.js.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
*
|
|
14
14
|
* Public operations express caller intent: `start` returns one published owned
|
|
15
15
|
* one-shot run, `startContinuable` establishes a durable continuable child, and
|
|
16
|
-
* `
|
|
17
|
-
* resident. Continuable children never become a {@link SubagentRun}: the
|
|
16
|
+
* `sendMessage` steers between adjacent Agents without exposing whether a child
|
|
17
|
+
* is resident. Continuable children never become a {@link SubagentRun}: the
|
|
18
18
|
* continuation manager holds their `AgentHandle` directly and orders every turn
|
|
19
19
|
* through the child's own inbox, so providers contribute only the detached
|
|
20
20
|
* creation spec and see no handle, turn, or teardown. Child and descendant
|
|
@@ -36,9 +36,9 @@ import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
|
36
36
|
import { TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
37
37
|
import type { SubagentCatalog, SubagentInterruptReceipt, SubagentPromptReceipt, SubagentPromptRequest } from './control-types.ts';
|
|
38
38
|
import type { SubagentProvider, SubagentRun, SubagentRunEndInfo, SubagentRunInfo, SubagentStartRequest } from './types.ts';
|
|
39
|
-
import type { ContinuableStart, ContinuableStartSpec,
|
|
40
|
-
import type { ContinuableSetupContribution } from './activation-setup-registry.ts';
|
|
39
|
+
import type { ContinuableStart, ContinuableStartSpec, SubagentInterruptAuthority, SubagentSendMessageOptions } from './continuation.ts';
|
|
41
40
|
import type { SubagentDescendantListEntry, SubagentListEntry } from './list-children.ts';
|
|
41
|
+
import { queueSubagentPrompt } from './internal.ts';
|
|
42
42
|
export * from './out-of-process.ts';
|
|
43
43
|
export { AssistantOutputFold, finalAssistantOutput } from './assistant-output.ts';
|
|
44
44
|
export { SubagentRunId } from './types.ts';
|
|
@@ -51,8 +51,7 @@ export { settleRun } from './run-settlement.ts';
|
|
|
51
51
|
export { assertSubagentMaxDepth, delegationDepthOf } from './depth.ts';
|
|
52
52
|
export { appendDelegatedPolicyOverrides, applyChildComposition, captureDelegatedPolicyOverrides, childSessionMeta, parentAgentOptionsForDelegation, resolveChildAgentOptions, resolveChildDepth, SubagentDepthError, } from './child-agent.ts';
|
|
53
53
|
export type { ChildComposition, DelegatedPolicyOverrides } from './child-agent.ts';
|
|
54
|
-
export type { ContinuableStart, ContinuableStartSpec,
|
|
55
|
-
export type { ContinuableSetupContribution } from './activation-setup-registry.ts';
|
|
54
|
+
export type { AgentMessageSource, ContinuableStart, ContinuableStartSpec, SubagentInterruptAuthority, SubagentSendMessageOptions, SubagentSettledMessageSource, } from './continuation.ts';
|
|
56
55
|
export type * from './control-types.ts';
|
|
57
56
|
export type { SubagentDescendantListEntry } from './list-children.ts';
|
|
58
57
|
export type { SubagentRunEndInfo, SubagentRunInfo } from './types.ts';
|
|
@@ -100,8 +99,6 @@ declare module '@deepseek-ai/cordis' {
|
|
|
100
99
|
export declare class SubagentRuntime extends TypertRemoteService {
|
|
101
100
|
private providers;
|
|
102
101
|
private continuations;
|
|
103
|
-
/** Deployment contributions composed into unpublished continuable children. */
|
|
104
|
-
private readonly setupRegistry;
|
|
105
102
|
/**
|
|
106
103
|
* The contained lifecycle-edge publisher. Built here because scoped dispatch
|
|
107
104
|
* keys its carrier by this exact service instance, whose own context filter
|
|
@@ -120,21 +117,32 @@ export declare class SubagentRuntime extends TypertRemoteService {
|
|
|
120
117
|
*/
|
|
121
118
|
startContinuable(spec: ContinuableStartSpec): Promise<ContinuableStart>;
|
|
122
119
|
/**
|
|
123
|
-
*
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
* @param
|
|
129
|
-
* @param
|
|
130
|
-
* @param content -
|
|
131
|
-
* @param options -
|
|
132
|
-
* operation only before inbox acceptance.
|
|
120
|
+
* Steer one model-authored message to the sender's direct parent or direct
|
|
121
|
+
* continuable child. A running target admits it at the nearest step boundary;
|
|
122
|
+
* an idle target starts a turn, and an absent direct child cold-resumes from
|
|
123
|
+
* persistence. The service derives durable sender attribution from the exact
|
|
124
|
+
* live sender. Caller cancellation stops only pre-acceptance work.
|
|
125
|
+
* @param sender - exact live Agent authorizing and originating the message.
|
|
126
|
+
* @param targetId - durable direct-parent or direct-child session id.
|
|
127
|
+
* @param content - model-authored content to deliver.
|
|
128
|
+
* @param options - caller cancellation before inbox acceptance.
|
|
133
129
|
* @returns the accepted message's inbox id.
|
|
134
|
-
* @throws when continuation services are unavailable,
|
|
135
|
-
*
|
|
130
|
+
* @throws when continuation services are unavailable, adjacency is rejected,
|
|
131
|
+
* or the message was not admitted.
|
|
136
132
|
*/
|
|
137
|
-
|
|
133
|
+
sendMessage(sender: Agent, targetId: SessionId, content: ContentBlock[], options: SubagentSendMessageOptions): Promise<MessageId>;
|
|
134
|
+
/**
|
|
135
|
+
* Queue one host-protocol message as a distinct direct-child turn.
|
|
136
|
+
* Symbol-keyed so host adapters can preserve their own provenance without
|
|
137
|
+
* widening the public Service Definition or impersonating an Agent sender.
|
|
138
|
+
* @param parent - exact live direct parent authorizing delivery.
|
|
139
|
+
* @param childId - durable direct-child session id.
|
|
140
|
+
* @param content - host-authored content to deliver.
|
|
141
|
+
* @param source - durable host-protocol provenance.
|
|
142
|
+
* @param signal - caller cancellation before inbox acceptance.
|
|
143
|
+
* @returns the accepted message's inbox id.
|
|
144
|
+
*/
|
|
145
|
+
private [queueSubagentPrompt];
|
|
138
146
|
/**
|
|
139
147
|
* Interrupt one live continuable child's current turn under a human parent
|
|
140
148
|
* address or an exact live ancestor Agent. Fire-and-return: the cancel
|
|
@@ -151,27 +159,6 @@ export declare class SubagentRuntime extends TypertRemoteService {
|
|
|
151
159
|
* live target.
|
|
152
160
|
*/
|
|
153
161
|
interrupt(targetSessionId: SessionId, authority: SubagentInterruptAuthority): void;
|
|
154
|
-
/**
|
|
155
|
-
* Deliver selected content from one live continuable child to its durable
|
|
156
|
-
* direct parent. The child is the authority credential; callers cannot name a
|
|
157
|
-
* recipient. Reporting does not conclude the child's turn or Activation.
|
|
158
|
-
* @param child - exact live reporting child.
|
|
159
|
-
* @param content - selected model-facing content.
|
|
160
|
-
* @param options - parent scheduling and pre-acceptance cancellation.
|
|
161
|
-
* @returns the stable identity of the parent-accepted message.
|
|
162
|
-
* @throws when continuation services are unavailable, sender authorization
|
|
163
|
-
* fails, or the direct parent is not live.
|
|
164
|
-
*/
|
|
165
|
-
reportFrom(child: Agent, content: ContentBlock[], options: SubagentReportOptions): Promise<MessageId>;
|
|
166
|
-
/**
|
|
167
|
-
* Compose one deployment capability into every continuable child's
|
|
168
|
-
* unpublished creation context on fresh creation and cold resume. Grants wait
|
|
169
|
-
* for the next Activation; removing the contribution revokes every resident
|
|
170
|
-
* installation immediately.
|
|
171
|
-
* @param contribution - synchronous child-scope installer.
|
|
172
|
-
* @returns the exact Cordis effect disposer.
|
|
173
|
-
*/
|
|
174
|
-
registerContinuableSetup(contribution: ContinuableSetupContribution): () => void;
|
|
175
162
|
/**
|
|
176
163
|
* Close continuable admission below exact live parent Agents, stop only their
|
|
177
164
|
* visible descendant Activations synchronously, then await admitted scoped
|