@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
package/lib/types/index.js
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
|
|
@@ -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
|
-
}
|
|
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
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @param
|
|
155
|
-
* @param
|
|
156
|
-
* @param content -
|
|
157
|
-
* @param options -
|
|
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,
|
|
161
|
-
*
|
|
157
|
+
* @throws when continuation services are unavailable, adjacency is rejected,
|
|
158
|
+
* or the message was not admitted.
|
|
162
159
|
*/
|
|
163
|
-
async
|
|
164
|
-
return this.requireContinuations().
|
|
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 {
|
|
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
|
package/lib/types/lifecycle.js
CHANGED
|
@@ -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.
|
|
105
|
+
boundary = child.session.seq;
|
|
105
106
|
emit('subagent/start', identity, parent);
|
|
106
107
|
},
|
|
107
108
|
capture: (child) => {
|
|
108
|
-
const own = child.session.
|
|
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
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
|
39
|
-
*
|
|
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
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
|
83
|
-
*
|
|
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
|
|
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:
|
|
265
|
-
* projection-cache row
|
|
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
|
-
|
|
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
|
-
//
|
|
288
|
-
//
|
|
289
|
-
//
|
|
290
|
-
//
|
|
291
|
-
|
|
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 <
|
|
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', '
|
|
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
|
|
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:
|
|
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:
|
|
43
|
+
seq: SessionSeq;
|
|
43
44
|
};
|
|
44
45
|
declare module '@deepseek-ai/dsh-session-projection/types' {
|
|
45
46
|
interface SessionProjectionMap {
|
package/lib/types/projection.js
CHANGED
|
@@ -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.
|
|
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-
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
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.
|
|
59
|
-
"@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.
|
|
60
|
-
"@deepseek-ai/dsh-attachment": "^0.1.2-alpha.
|
|
61
|
-
"@deepseek-ai/dsh-invariants": "^0.1.2-alpha.
|
|
62
|
-
"@deepseek-ai/dsh-jobs": "^0.1.2-alpha.
|
|
63
|
-
"@deepseek-ai/dsh-llm": "^0.1.2-alpha.
|
|
64
|
-
"@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.
|
|
65
|
-
"@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.
|
|
66
|
-
"@deepseek-ai/dsh-scope": "^0.1.2-alpha.
|
|
67
|
-
"@deepseek-ai/dsh-session": "^0.1.2-alpha.
|
|
68
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.
|
|
69
|
-
"@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
71
|
-
"@deepseek-ai/dsh-
|
|
72
|
-
"@deepseek-ai/dsh-
|
|
73
|
-
"@deepseek-ai/dsh-
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/dsh-
|
|
76
|
-
"@deepseek-ai/dsh-
|
|
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.
|
|
110
|
-
"@deepseek-ai/dsh-agent-presets": "^0.1.2-alpha.
|
|
111
|
-
"@deepseek-ai/dsh-attachment": "^0.1.2-alpha.
|
|
112
|
-
"@deepseek-ai/dsh-jobs": "^0.1.2-alpha.
|
|
113
|
-
"@deepseek-ai/dsh-
|
|
114
|
-
"@deepseek-ai/dsh-
|
|
115
|
-
"@deepseek-ai/dsh-sandbox": "^0.1.2-alpha.
|
|
116
|
-
"@deepseek-ai/dsh-sandbox-policy": "^0.1.2-alpha.
|
|
117
|
-
"@deepseek-ai/dsh-scope": "^0.1.2-alpha.
|
|
118
|
-
"@deepseek-ai/dsh-session": "^0.1.2-alpha.
|
|
119
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.
|
|
120
|
-
"@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.
|
|
121
|
-
"@deepseek-ai/dsh-session-query": "^0.1.2-alpha.
|
|
122
|
-
"@deepseek-ai/dsh-storage": "^0.1.2-alpha.
|
|
123
|
-
"@deepseek-ai/dsh-storage-domain": "^0.1.2-alpha.
|
|
124
|
-
"@deepseek-ai/dsh-
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.
|
|
127
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.
|
|
128
|
-
"@deepseek-ai/dsh-user-approval": "^0.1.2-alpha.
|
|
129
|
-
"@deepseek-ai/dsh-util-time": "^0.1.2-alpha.
|
|
130
|
-
"@deepseek-ai/dsh-
|
|
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
|