@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.
@@ -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
- * `followup` delivers later content without exposing whether the child is
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
@@ -72,10 +72,10 @@ import { SubagentError } from "./error.js";
72
72
  import { assertSubagentMaxDepth } from "./depth.js";
73
73
  import { createActivationObserver, createLifecycleEmitter, observeRun } from "./lifecycle.js";
74
74
  import SubagentContinuationManager from "./continuation.js";
75
- import SubagentActivationSetupRegistry from "./activation-setup-registry.js";
76
75
  import { listChildren as listSubagentChildren, listDescendants as listSubagentDescendants } from "./list-children.js";
77
76
  import { snapshotSubagentDescriptor } from "./descriptor.js";
78
77
  import { subagentIdentityProjectionDefinition, subagentTimingProjectionDefinition } from "./projection.js";
78
+ import { queueSubagentPrompt } from "./internal.js";
79
79
  export * from "./out-of-process.js";
80
80
  export { AssistantOutputFold, finalAssistantOutput } from "./assistant-output.js";
81
81
  export { SubagentRunId } from "./types.js";
@@ -105,8 +105,6 @@ let SubagentRuntime = (() => {
105
105
  }
106
106
  providers = (__runInitializers(this, _instanceExtraInitializers), new Map());
107
107
  continuations;
108
- /** Deployment contributions composed into unpublished continuable children. */
109
- setupRegistry = new SubagentActivationSetupRegistry();
110
108
  /**
111
109
  * The contained lifecycle-edge publisher. Built here because scoped dispatch
112
110
  * keys its carrier by this exact service instance, whose own context filter
@@ -120,7 +118,7 @@ let SubagentRuntime = (() => {
120
118
  const manager = new SubagentContinuationManager(childCtx, {
121
119
  prepareContinuable: (name, request) => this.prepareContinuable(name, request),
122
120
  observeActivation: (provider, childId, parent) => this.observeActivation(provider, childId, parent),
123
- }, this.setupRegistry);
121
+ });
124
122
  this.continuations = manager;
125
123
  childCtx.effect(() => () => {
126
124
  /* v8 ignore else -- one injected binding owns the slot until its fiber disposes. */
@@ -146,22 +144,35 @@ let SubagentRuntime = (() => {
146
144
  return this.requireContinuations().startContinuable(spec);
147
145
  }
148
146
  /**
149
- * Deliver one later message to a continuable child as its next FIFO turn. A
150
- * resident child's Agent inbox accepts it directly (waking a `waiting`
151
- * Activation), while an absent one is cold-resumed from its persisted
152
- * Session. The Agent inbox is the only queue, so every accepted message has
153
- * one observable order.
154
- * @param parent - the exact live direct parent authorizing this delivery.
155
- * @param childId - durable child session id.
156
- * @param content - user-role content to deliver.
157
- * @param options - the message source fields and caller cancellation, which stops the
158
- * operation only before inbox acceptance.
147
+ * Steer one model-authored message to the sender's direct parent or direct
148
+ * continuable child. A running target admits it at the nearest step boundary;
149
+ * an idle target starts a turn, and an absent direct child cold-resumes from
150
+ * persistence. The service derives durable sender attribution from the exact
151
+ * live sender. Caller cancellation stops only pre-acceptance work.
152
+ * @param sender - exact live Agent authorizing and originating the message.
153
+ * @param targetId - durable direct-parent or direct-child session id.
154
+ * @param content - model-authored content to deliver.
155
+ * @param options - caller cancellation before inbox acceptance.
159
156
  * @returns the accepted message's inbox id.
160
- * @throws when continuation services are unavailable, parent authority is
161
- * rejected, or the message was not admitted.
157
+ * @throws when continuation services are unavailable, adjacency is rejected,
158
+ * or the message was not admitted.
162
159
  */
163
- async followup(parent, childId, content, options) {
164
- return this.requireContinuations().followup(parent, childId, content, options);
160
+ async sendMessage(sender, targetId, content, options) {
161
+ return this.requireContinuations().sendMessage(sender, targetId, content, options);
162
+ }
163
+ /**
164
+ * Queue one host-protocol message as a distinct direct-child turn.
165
+ * Symbol-keyed so host adapters can preserve their own provenance without
166
+ * widening the public Service Definition or impersonating an Agent sender.
167
+ * @param parent - exact live direct parent authorizing delivery.
168
+ * @param childId - durable direct-child session id.
169
+ * @param content - host-authored content to deliver.
170
+ * @param source - durable host-protocol provenance.
171
+ * @param signal - caller cancellation before inbox acceptance.
172
+ * @returns the accepted message's inbox id.
173
+ */
174
+ [queueSubagentPrompt](parent, childId, content, source, signal) {
175
+ return this.requireContinuations().queuePrompt(parent, childId, content, source, signal);
165
176
  }
166
177
  /**
167
178
  * Interrupt one live continuable child's current turn under a human parent
@@ -181,32 +192,6 @@ let SubagentRuntime = (() => {
181
192
  interrupt(targetSessionId, authority) {
182
193
  this.continuations?.interrupt(targetSessionId, authority);
183
194
  }
184
- /**
185
- * Deliver selected content from one live continuable child to its durable
186
- * direct parent. The child is the authority credential; callers cannot name a
187
- * recipient. Reporting does not conclude the child's turn or Activation.
188
- * @param child - exact live reporting child.
189
- * @param content - selected model-facing content.
190
- * @param options - parent scheduling and pre-acceptance cancellation.
191
- * @returns the stable identity of the parent-accepted message.
192
- * @throws when continuation services are unavailable, sender authorization
193
- * fails, or the direct parent is not live.
194
- */
195
- async reportFrom(child, content, options) {
196
- return this.requireContinuations().reportFrom(child, content, options);
197
- }
198
- /**
199
- * Compose one deployment capability into every continuable child's
200
- * unpublished creation context on fresh creation and cold resume. Grants wait
201
- * for the next Activation; removing the contribution revokes every resident
202
- * installation immediately.
203
- * @param contribution - synchronous child-scope installer.
204
- * @returns the exact Cordis effect disposer.
205
- */
206
- registerContinuableSetup(contribution) {
207
- // oxlint-disable-next-line typescript/no-misused-promises -- synchronous disposer
208
- return this.ctx.effect(() => this.setupRegistry.register(contribution), 'subagents.registerContinuableSetup()');
209
- }
210
195
  /**
211
196
  * Close continuable admission below exact live parent Agents, stop only their
212
197
  * visible descendant Activations synchronously, then await admitted scoped
@@ -347,7 +332,9 @@ let SubagentRuntime = (() => {
347
332
  throw new Error('subagent image prompt requires an attachment store');
348
333
  content = await admitPromptContent(attachments, request.content);
349
334
  }
350
- return { messageId: await this.followup(parent, childSessionId, content, { source, signal }) };
335
+ return {
336
+ messageId: await this[queueSubagentPrompt](parent, childSessionId, content, source, signal),
337
+ };
351
338
  }
352
339
  catch (error) {
353
340
  return rejectPrompt(error, childSessionId, signal);
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Continuation integration markers and host adapters outside the public
3
+ * Service Definition and model-facing Agent messaging contract.
4
+ * @module @deepseek-ai/dsh-subagent/internal
5
+ */
6
+ import type { Agent } from '@deepseek-ai/dsh-agent';
7
+ import type { ContentBlock, MessageId, MessageSource } from '@deepseek-ai/dsh-llm';
8
+ import type { SessionId } from '@deepseek-ai/dsh-session';
9
+ import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
10
+ import type SubagentRuntime from './index.ts';
11
+ /** Process-stable identity carried only by the standard adjacent-Agent messaging tool. */
12
+ export declare const adjacentAgentSendMessageTool: unique symbol;
13
+ /**
14
+ * Mark the standard adjacent-Agent messaging tool without changing its model-visible schema.
15
+ * @param definition - the standard `send_message` definition.
16
+ * @returns the same definition with its internal identity installed.
17
+ */
18
+ export declare function markAdjacentAgentSendMessageTool(definition: ToolDefinition): ToolDefinition;
19
+ /**
20
+ * Test whether one visible definition is the standard adjacent-Agent messaging tool.
21
+ * @param definition - the scope-resolved `send_message` candidate.
22
+ * @returns whether the definition carries the internal standard-tool identity.
23
+ */
24
+ export declare function isAdjacentAgentSendMessageTool(definition: ToolDefinition | undefined): boolean;
25
+ /**
26
+ * Process-stable symbol-keyed Queue delivery shared by the bundled runtime
27
+ * entry and this unbundled internal subpath.
28
+ * @internal
29
+ */
30
+ export declare const queueSubagentPrompt: unique symbol;
31
+ /** Runtime face required by the host-only Queue adapter. */
32
+ export interface HostPromptQueue {
33
+ [queueSubagentPrompt](parent: Agent, childId: SessionId, content: ContentBlock[], source: MessageSource, signal: AbortSignal): Promise<MessageId>;
34
+ }
35
+ /**
36
+ * Queue one host-protocol message without exposing another Service operation.
37
+ * @param runtime - subagent runtime owning continuation residency.
38
+ * @param parent - exact live direct parent authorizing delivery.
39
+ * @param childId - durable direct-child session id.
40
+ * @param content - host-authored content to deliver.
41
+ * @param source - durable host-protocol provenance.
42
+ * @param signal - caller cancellation before inbox acceptance.
43
+ * @returns the accepted message's inbox id.
44
+ */
45
+ export declare function queueHostSubagentPrompt(runtime: SubagentRuntime, parent: Agent, childId: SessionId, content: ContentBlock[], source: MessageSource, signal: AbortSignal): Promise<MessageId>;
46
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Continuation integration markers and host adapters outside the public
3
+ * Service Definition and model-facing Agent messaging contract.
4
+ * @module @deepseek-ai/dsh-subagent/internal
5
+ */
6
+ /** Process-stable identity carried only by the standard adjacent-Agent messaging tool. */
7
+ export const adjacentAgentSendMessageTool = Symbol.for('dsh.subagent.adjacentAgentSendMessageTool');
8
+ /**
9
+ * Mark the standard adjacent-Agent messaging tool without changing its model-visible schema.
10
+ * @param definition - the standard `send_message` definition.
11
+ * @returns the same definition with its internal identity installed.
12
+ */
13
+ export function markAdjacentAgentSendMessageTool(definition) {
14
+ Object.defineProperty(definition, adjacentAgentSendMessageTool, { value: true });
15
+ return definition;
16
+ }
17
+ /**
18
+ * Test whether one visible definition is the standard adjacent-Agent messaging tool.
19
+ * @param definition - the scope-resolved `send_message` candidate.
20
+ * @returns whether the definition carries the internal standard-tool identity.
21
+ */
22
+ export function isAdjacentAgentSendMessageTool(definition) {
23
+ return definition !== undefined
24
+ && definition[adjacentAgentSendMessageTool] === true;
25
+ }
26
+ /**
27
+ * Process-stable symbol-keyed Queue delivery shared by the bundled runtime
28
+ * entry and this unbundled internal subpath.
29
+ * @internal
30
+ */
31
+ export const queueSubagentPrompt = Symbol.for('dsh.subagent.queuePrompt');
32
+ /**
33
+ * Queue one host-protocol message without exposing another Service operation.
34
+ * @param runtime - subagent runtime owning continuation residency.
35
+ * @param parent - exact live direct parent authorizing delivery.
36
+ * @param childId - durable direct-child session id.
37
+ * @param content - host-authored content to deliver.
38
+ * @param source - durable host-protocol provenance.
39
+ * @param signal - caller cancellation before inbox acceptance.
40
+ * @returns the accepted message's inbox id.
41
+ */
42
+ export function queueHostSubagentPrompt(runtime, parent, childId, content, source, signal) {
43
+ return runtime[queueSubagentPrompt](parent, childId, content, source, signal);
44
+ }
45
+ //# sourceMappingURL=internal.js.map
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { randomUUID } from 'node:crypto';
17
17
  import { foldConsumedWork } from '@deepseek-ai/dsh-agent';
18
+ import { SessionLogOffset } from '@deepseek-ai/dsh-session';
18
19
  import { finalAssistantOutput } from "./assistant-output.js";
19
20
  import { SubagentRunId } from "./types.js";
20
21
  /**
@@ -90,7 +91,7 @@ export function createActivationObserver(emit, provider, childId, parent) {
90
91
  // A cold resume replays earlier turns, so this epoch's telemetry must come
91
92
  // from the suffix it actually produced — never the whole session, which
92
93
  // would report a previous epoch's answer when this one opened no turn.
93
- let boundary = 0;
94
+ let boundary = SessionLogOffset(0);
94
95
  // Assigned by `capture()`, which the disposal path always runs before
95
96
  // `settle()`; a resident epoch therefore always has its facts by then.
96
97
  let captured = { stopReason: 'completed' };
@@ -101,11 +102,11 @@ export function createActivationObserver(emit, provider, childId, parent) {
101
102
  : { stopReason: 'error' };
102
103
  return {
103
104
  start: (child) => {
104
- boundary = child.session.events.length;
105
+ boundary = child.session.seq;
105
106
  emit('subagent/start', identity, parent);
106
107
  },
107
108
  capture: (child) => {
108
- const own = child.session.events.slice(boundary);
109
+ const own = child.session.snapshotEvents(boundary);
109
110
  const output = finalAssistantOutput(own);
110
111
  captured = {
111
112
  stopReason: epochStopReason(own),
@@ -4,9 +4,10 @@
4
4
  * corpus; each child's mode/label is the registered `subagent` projection
5
5
  * unit's value, resolved
6
6
  * down a three-rung ladder: the registry's watermark cache for a live child,
7
- * a durable projection-cache row when it serves an own-suffix identity (the
8
- * seq gate), and one shared Session observation otherwise, validated against
9
- * the enumerated lifecycle. The projection fold is the single classification
7
+ * an unseeded durable projection-cache row, and one shared Session observation
8
+ * otherwise. A seeded header deliberately lacks its exact inherited cut, so
9
+ * it takes the body-bearing observation path before classifying an identity.
10
+ * The projection fold is the single classification
10
11
  * authority — this module parses no descriptor
11
12
  * itself. Absent persistence, enumeration is live-only: a cold child is
12
13
  * unreachable for resume anyway, so its absence is capability absence, not an
@@ -35,8 +36,8 @@ export type SubagentDescendantListEntry = SubagentListEntry & {
35
36
  * live-preferred merge of `ctx.sessions` and optional session persistence,
36
37
  * serving each identity from the `subagent` projection unit: the registry's
37
38
  * watermark snapshot for a live child; for a cold one, a durable
38
- * projection-cache read when it serves an own-suffix identity (the seq gate),
39
- * else one bounded-concurrency shared Session observation.
39
+ * projection-cache read for an unseeded lifecycle, else one bounded-concurrency
40
+ * shared Session observation carrying the exact inherited cut.
40
41
  * @see SubagentRuntime.listChildren for the public cancellation and failure contract.
41
42
  * @param ctx - context carrying the session store, the projection registry,
42
43
  * optional persistence, and the optional projection cache.
@@ -4,9 +4,10 @@
4
4
  * corpus; each child's mode/label is the registered `subagent` projection
5
5
  * unit's value, resolved
6
6
  * down a three-rung ladder: the registry's watermark cache for a live child,
7
- * a durable projection-cache row when it serves an own-suffix identity (the
8
- * seq gate), and one shared Session observation otherwise, validated against
9
- * the enumerated lifecycle. The projection fold is the single classification
7
+ * an unseeded durable projection-cache row, and one shared Session observation
8
+ * otherwise. A seeded header deliberately lacks its exact inherited cut, so
9
+ * it takes the body-bearing observation path before classifying an identity.
10
+ * The projection fold is the single classification
10
11
  * authority — this module parses no descriptor
11
12
  * itself. Absent persistence, enumeration is live-only: a cold child is
12
13
  * unreachable for resume anyway, so its absence is capability absence, not an
@@ -67,6 +68,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
67
68
  var e = new Error(message);
68
69
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
69
70
  });
71
+ import { SessionLogOffset } from '@deepseek-ai/dsh-session';
70
72
  import { SubagentError } from "./error.js";
71
73
  /**
72
74
  * Concurrent cold observations per explicit catalog listing. Current Session
@@ -79,8 +81,8 @@ const COLD_READ_CONCURRENCY = 4;
79
81
  * live-preferred merge of `ctx.sessions` and optional session persistence,
80
82
  * serving each identity from the `subagent` projection unit: the registry's
81
83
  * watermark snapshot for a live child; for a cold one, a durable
82
- * projection-cache read when it serves an own-suffix identity (the seq gate),
83
- * else one bounded-concurrency shared Session observation.
84
+ * projection-cache read for an unseeded lifecycle, else one bounded-concurrency
85
+ * shared Session observation carrying the exact inherited cut.
84
86
  * @see SubagentRuntime.listChildren for the public cancellation and failure contract.
85
87
  * @param ctx - context carrying the session store, the projection registry,
86
88
  * optional persistence, and the optional projection cache.
@@ -203,7 +205,7 @@ async function resolveCandidateRows(candidates, listing, signal) {
203
205
  // The unit's serializable no-value sentinel is `null`; `undefined` can
204
206
  // only mean the key was dropped at a JSON boundary. Both are no value.
205
207
  if (identity === undefined || identity === null
206
- || identity.seq < (candidate.header.seedLength ?? 0))
208
+ || !candidate.live.isOwnSeq(identity.seq))
207
209
  return;
208
210
  rows[index] = childRow(childId, identity, 'running', subagentParents.has(childId));
209
211
  });
@@ -261,9 +263,8 @@ function compareCorpusRecords(a, b) {
261
263
  return a.header.createdAt - b.header.createdAt || a.header.id.localeCompare(b.header.id);
262
264
  }
263
265
  /**
264
- * Resolve one cold candidate down the remaining ladder: a durable
265
- * projection-cache row when it serves an own-suffix identity (the seq gate),
266
- * otherwise one shared Session observation. An absent or transiently failed
266
+ * Resolve one cold candidate down the remaining ladder: an unseeded durable
267
+ * projection-cache row, otherwise one shared Session observation. An absent or transiently failed
267
268
  * observation is one `unavailable` row retried on the next listing; an observation
268
269
  * source naming another lifecycle, and a
269
270
  * settled log the fold cannot identify — or that makes any registered unit
@@ -273,10 +274,14 @@ async function resolveColdIdentity(query, cache, header, hasChildren, signal) {
273
274
  const env_1 = { stack: [], error: void 0, hasError: false };
274
275
  try {
275
276
  const childId = header.id;
276
- if (cache !== undefined) {
277
+ // A header deliberately exposes only whether a fork cut exists, not its
278
+ // integer. An unseeded lifecycle has the exact cut 0 and may use the cache;
279
+ // a seeded lifecycle must read the body before an identity seq can be
280
+ // classified as inherited or owned.
281
+ if (cache !== undefined && !header.isSeeded) {
277
282
  let cached;
278
283
  try {
279
- cached = cache.cachedSnapshot(header, ['subagent'])?.values.subagent;
284
+ cached = cache.cachedSnapshot(header, SessionLogOffset(0), ['subagent'])?.values.subagent;
280
285
  }
281
286
  catch {
282
287
  // Unlike the preparation fold below, a throwing cache read renders no
@@ -284,15 +289,11 @@ async function resolveColdIdentity(query, cache, header, hasChildren, signal) {
284
289
  // row of ANY unit) silently falls through to the authoritative re-fold.
285
290
  cached = undefined;
286
291
  }
287
- // A child's OWN descriptor is immutable once appended, so a cached
288
- // identity is final only when the seq gate proves it was folded from the
289
- // own suffix: a creation-window checkpoint may instead carry a fork
290
- // seed's replayed ANCESTOR descriptor (seq below `seedLength`), which
291
- // must not outrank the re-fold. Everything else also falls through to
292
- // preparation: an absent key (a cut before any descriptor) and the
293
- // `null` sentinel, whose verdict belongs to the authoritative re-fold,
294
- // not to a derived row.
295
- if (cached !== undefined && cached !== null && cached.seq >= (header.seedLength ?? 0)) {
292
+ // An unseeded child's descriptor is owned at every valid seq. Everything
293
+ // else falls through to preparation: an absent key and the `null`
294
+ // sentinel, whose verdict belongs to the authoritative re-fold, not to a
295
+ // derived row.
296
+ if (cached !== undefined && cached !== null) {
296
297
  return childRow(childId, cached, 'inactive', hasChildren);
297
298
  }
298
299
  }
@@ -326,7 +327,7 @@ async function resolveColdIdentity(query, cache, header, hasChildren, signal) {
326
327
  }
327
328
  const identity = ownedObservation.projections?.values.subagent;
328
329
  if (identity === undefined || identity === null
329
- || identity.seq < (header.seedLength ?? 0)) {
330
+ || identity.seq < ownedObservation.inheritedEventCount) {
330
331
  return { kind: 'diagnostic', id: childId, reason: 'corrupt' };
331
332
  }
332
333
  return childRow(childId, identity, 'inactive', hasChildren);
@@ -361,7 +362,7 @@ function childRow(id, identity, activity, hasChildren) {
361
362
  }
362
363
  /** Immutable header fields that distinguish one session lifecycle from another under the same id. */
363
364
  const LIFECYCLE_WITNESS_KEYS = [
364
- 'version', 'id', 'createdAt', 'cwd', 'parentSession', 'seedLength', 'delegationDepth',
365
+ 'version', 'id', 'createdAt', 'cwd', 'parentSession', 'isSeeded', 'delegationDepth',
365
366
  'origin', 'agentPreset',
366
367
  ];
367
368
  /** Whether an inspected log still belongs to the enumerated lifecycle. */
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * @module @deepseek-ai/dsh-subagent/projection-types
5
5
  */
6
+ import type { SessionSeq } from '@deepseek-ai/dsh-session/types';
6
7
  /** Durable active-turn timing for one descriptor-backed child session. */
7
8
  export interface SubagentTimingProjection {
8
9
  /** Milliseconds accumulated across completed turns after the child's own descriptor. */
@@ -28,18 +29,18 @@ export type SubagentIdentityProjection = {
28
29
  label?: string;
29
30
  /**
30
31
  * Seq of the `subagent/descriptor` event this identity was folded from.
31
- * `seq >= header.seedLength` proves the identity comes from the child's
32
+ * `session.isOwnSeq(seq)` proves the identity comes from the child's
32
33
  * OWN log suffix — where a descriptor is immutable once appended — and
33
34
  * not from a fork seed's replayed ancestor descriptor.
34
35
  */
35
- seq: number;
36
+ seq: SessionSeq;
36
37
  } | {
37
38
  /** A resumable conversation. */
38
39
  mode: 'continuable';
39
40
  /** Durable creation label from the child's descriptor. */
40
41
  label: string;
41
42
  /** Seq of the folded descriptor event; see the one-shot arm for the own-suffix proof. */
42
- seq: number;
43
+ seq: SessionSeq;
43
44
  };
44
45
  declare module '@deepseek-ai/dsh-session-projection/types' {
45
46
  interface SessionProjectionMap {
@@ -5,6 +5,7 @@
5
5
  * @module @deepseek-ai/dsh-subagent/projection
6
6
  */
7
7
  import { z } from 'zod';
8
+ import { SessionSeq } from '@deepseek-ai/dsh-session';
8
9
  import { foldSubagentDescriptor } from "./descriptor.js";
9
10
  const activeIntervalSchema = z.object({
10
11
  since: z.number().int().nonnegative(),
@@ -88,12 +89,12 @@ const identityValueSchema = z.discriminatedUnion('mode', [
88
89
  z.object({
89
90
  mode: z.literal('one-shot'),
90
91
  label: z.string().optional(),
91
- seq: z.number().int().nonnegative(),
92
+ seq: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq),
92
93
  }).strict(),
93
94
  z.object({
94
95
  mode: z.literal('continuable'),
95
96
  label: z.string(),
96
- seq: z.number().int().nonnegative(),
97
+ seq: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq),
97
98
  }).strict(),
98
99
  ]);
99
100
  const identitySchema = identityValueSchema.nullable();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-subagent",
3
3
  "description": "Abstract subagent seam (ctx.subagents): named-provider registry for delegating to child agents",
4
- "version": "0.1.2-alpha.3",
4
+ "version": "0.1.2-alpha.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -18,6 +18,10 @@
18
18
  "types": "./lib/types/index.d.ts",
19
19
  "default": "./lib/index.js"
20
20
  },
21
+ "./internal": {
22
+ "types": "./lib/types/internal.d.ts",
23
+ "default": "./lib/types/internal.js"
24
+ },
21
25
  "./invariant": {
22
26
  "types": "./lib/types/invariant.d.ts",
23
27
  "default": "./lib/invariant.js"
@@ -50,30 +54,30 @@
50
54
  "license": "MIT",
51
55
  "dependencies": {
52
56
  "zod": "^4.4.3",
53
- "@deepseek-ai/dsh-brand": "^0.1.2-alpha.3",
54
- "@deepseek-ai/dsh-util-values": "^0.1.2-alpha.3"
57
+ "@deepseek-ai/dsh-util-values": "^0.1.2-alpha.4",
58
+ "@deepseek-ai/dsh-brand": "^0.1.2-alpha.4"
55
59
  },
56
60
  "peerDependencies": {
57
61
  "@deepseek-ai/cordis": "^4.0.2",
58
- "@deepseek-ai/dsh-agent": "^0.1.2-alpha.3",
59
- "@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.3",
60
- "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.3",
61
- "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.3",
62
- "@deepseek-ai/dsh-jobs": "^0.1.2-alpha.3",
63
- "@deepseek-ai/dsh-llm": "^0.1.2-alpha.3",
64
- "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.3",
65
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.3",
66
- "@deepseek-ai/dsh-scope": "^0.1.2-alpha.3",
67
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.3",
68
- "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.3",
69
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.3",
70
- "@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.3",
71
- "@deepseek-ai/dsh-tools": "^0.1.2-alpha.3",
72
- "@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.3",
73
- "@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.3",
74
- "@deepseek-ai/dsh-session-persistence": "^0.1.2-alpha.3",
75
- "@deepseek-ai/dsh-util-time": "^0.1.2-alpha.3",
76
- "@deepseek-ai/dsh-session-query": "^0.1.2-alpha.3"
62
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.4",
63
+ "@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.4",
64
+ "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",
65
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.4",
66
+ "@deepseek-ai/dsh-jobs": "^0.1.2-alpha.4",
67
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.4",
68
+ "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.4",
69
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.4",
70
+ "@deepseek-ai/dsh-scope": "^0.1.2-alpha.4",
71
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.4",
72
+ "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.4",
73
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.4",
74
+ "@deepseek-ai/dsh-session-query": "^0.1.2-alpha.4",
75
+ "@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.4",
76
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.4",
77
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.4",
78
+ "@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.4",
79
+ "@deepseek-ai/dsh-session-persistence": "^0.1.2-alpha.4",
80
+ "@deepseek-ai/dsh-util-time": "^0.1.2-alpha.4"
77
81
  },
78
82
  "peerDependenciesMeta": {
79
83
  "@deepseek-ai/dsh-agent-presets": {
@@ -106,27 +110,27 @@
106
110
  },
107
111
  "devDependencies": {
108
112
  "@deepseek-ai/cordis": "^4.0.2",
109
- "@deepseek-ai/dsh-agent": "^0.1.2-alpha.3",
110
- "@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.3",
111
- "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.3",
112
- "@deepseek-ai/dsh-jobs": "^0.1.2-alpha.3",
113
- "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.3",
114
- "@deepseek-ai/dsh-llm": "^0.1.2-alpha.3",
115
- "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.3",
116
- "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.3",
117
- "@deepseek-ai/dsh-scope": "^0.1.2-alpha.3",
118
- "@deepseek-ai/dsh-session": "^0.1.2-alpha.3",
119
- "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.3",
120
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.3",
121
- "@deepseek-ai/dsh-session-query": "^0.1.2-alpha.3",
122
- "@deepseek-ai/dsh-storage": "^0.1.2-alpha.3",
123
- "@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.3",
124
- "@deepseek-ai/dsh-storage-json": "^0.1.2-alpha.3",
125
- "@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.3",
126
- "@deepseek-ai/dsh-tools": "^0.1.2-alpha.3",
127
- "@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.3",
128
- "@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.3",
129
- "@deepseek-ai/dsh-util-time": "^0.1.2-alpha.3",
130
- "@deepseek-ai/dsh-session-persistence": "^0.1.2-alpha.3"
113
+ "@deepseek-ai/dsh-agent": "^0.1.2-alpha.4",
114
+ "@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.4",
115
+ "@deepseek-ai/dsh-attachment": "^0.1.2-alpha.4",
116
+ "@deepseek-ai/dsh-jobs": "^0.1.2-alpha.4",
117
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.4",
118
+ "@deepseek-ai/dsh-invariants": "^0.1.2-alpha.4",
119
+ "@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.4",
120
+ "@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.4",
121
+ "@deepseek-ai/dsh-scope": "^0.1.2-alpha.4",
122
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.4",
123
+ "@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.4",
124
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.4",
125
+ "@deepseek-ai/dsh-session-query": "^0.1.2-alpha.4",
126
+ "@deepseek-ai/dsh-storage": "^0.1.2-alpha.4",
127
+ "@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.4",
128
+ "@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.4",
129
+ "@deepseek-ai/dsh-session-persistence": "^0.1.2-alpha.4",
130
+ "@deepseek-ai/dsh-tools": "^0.1.2-alpha.4",
131
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.4",
132
+ "@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.4",
133
+ "@deepseek-ai/dsh-util-time": "^0.1.2-alpha.4",
134
+ "@deepseek-ai/dsh-storage-json": "^0.1.2-alpha.4"
131
135
  }
132
136
  }
@@ -1,57 +0,0 @@
1
- /**
2
- * Internal registry of deployment capabilities composed into every continuable
3
- * child's unpublished creation context.
4
- *
5
- * A contribution grants a child-scoped capability without teaching the
6
- * continuation manager which capabilities exist. The manager owns residency;
7
- * this registry owns the join between plugin lifetime, unpublished setup, and
8
- * Activation disposal, so no installation outlives either owner and no removed
9
- * contribution can be installed after revocation reports completion.
10
- *
11
- * @module @deepseek-ai/dsh-subagent/activation-setup-registry
12
- */
13
- import type { Context } from '@deepseek-ai/cordis';
14
- import type { AgentSetupCommit } from '@deepseek-ai/dsh-agent';
15
- /**
16
- * One deployment capability installed into a continuable child's unpublished
17
- * creation context. It composes synchronously before publication and returns
18
- * the disposer for exactly that installation.
19
- * @param childCtx - the child's unpublished scoped context.
20
- * @returns the disposer revoking this installation.
21
- */
22
- export type ContinuableSetupContribution = (childCtx: Context) => () => void;
23
- /**
24
- * Owns continuable-child setup registrations, installations, rollback, child
25
- * cleanup, and immediate live revocation.
26
- */
27
- export declare class SubagentActivationSetupRegistry {
28
- /** Live contributions in installation order. */
29
- private readonly registrations;
30
- /** Child context to its live installations. */
31
- private readonly byChild;
32
- /**
33
- * Register one contribution.
34
- * @param contribution - synchronous child-scope installer.
35
- * @returns an idempotent registration undo.
36
- * @throws after attempting every installation when any disposer fails.
37
- */
38
- register(contribution: ContinuableSetupContribution): () => void;
39
- /**
40
- * Install every live contribution into one unpublished child context.
41
- * @param childCtx - the child's unpublished scoped context.
42
- * @returns the provisioning commit consumed at Agent publication.
43
- */
44
- apply(childCtx: Context): AgentSetupCommit;
45
- /** Release every remaining installation owned by one disposed child scope. */
46
- private releaseChild;
47
- /**
48
- * Release a batch completely before reporting disposer failures.
49
- * @param installations - records to release.
50
- * @param during - operation name for diagnostics.
51
- */
52
- private releaseAll;
53
- /** Drop one installation from both indices and dispose it exactly once. */
54
- private release;
55
- }
56
- export default SubagentActivationSetupRegistry;
57
- //# sourceMappingURL=activation-setup-registry.d.ts.map