@deepseek-ai/dsh-subagent 0.1.2-alpha.2 → 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 +238 -324
- package/lib/typert.host.js +52 -157
- package/lib/typert.remote-client.js +8 -91
- package/lib/types/child-agent.d.ts +2 -2
- package/lib/types/child-agent.js +3 -3
- package/lib/types/continuation.d.ts +50 -69
- package/lib/types/continuation.js +173 -105
- package/lib/types/control-types.d.ts +11 -27
- package/lib/types/control.d.ts +1 -17
- package/lib/types/control.js +6 -24
- package/lib/types/descriptor-seed.d.ts +1 -1
- package/lib/types/descriptor-seed.js +1 -1
- package/lib/types/index.d.ts +32 -43
- package/lib/types/index.js +51 -50
- 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
|
@@ -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-
|
|
69
|
-
"@deepseek-ai/dsh-session-projection-cache": "^0.1.2-alpha.
|
|
70
|
-
"@deepseek-ai/dsh-session-query": "^0.1.2-alpha.
|
|
71
|
-
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.
|
|
72
|
-
"@deepseek-ai/dsh-tools": "^0.1.2-alpha.
|
|
73
|
-
"@deepseek-ai/dsh-typert-protocol": "^0.1.2-alpha.
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/dsh-
|
|
76
|
-
"@deepseek-ai/dsh-util-time": "^0.1.2-alpha.
|
|
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-
|
|
111
|
-
"@deepseek-ai/dsh-
|
|
112
|
-
"@deepseek-ai/dsh-
|
|
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-
|
|
120
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.2-alpha.
|
|
121
|
-
"@deepseek-ai/dsh-session-
|
|
122
|
-
"@deepseek-ai/dsh-storage
|
|
123
|
-
"@deepseek-ai/dsh-storage-
|
|
124
|
-
"@deepseek-ai/dsh-system-prompt": "^0.1.2-alpha.
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-
|
|
127
|
-
"@deepseek-ai/dsh-
|
|
128
|
-
"@deepseek-ai/dsh-
|
|
129
|
-
"@deepseek-ai/dsh-
|
|
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
|
|
@@ -1,148 +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 { errorChain } from '@deepseek-ai/dsh-llm';
|
|
14
|
-
import { SubagentError } from "./error.js";
|
|
15
|
-
/** Re-read mutable removal state after a contribution may have revoked itself. */
|
|
16
|
-
function isRemoved(registration) {
|
|
17
|
-
return registration.removed;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Owns continuable-child setup registrations, installations, rollback, child
|
|
21
|
-
* cleanup, and immediate live revocation.
|
|
22
|
-
*/
|
|
23
|
-
export class SubagentActivationSetupRegistry {
|
|
24
|
-
/** Live contributions in installation order. */
|
|
25
|
-
registrations = new Set();
|
|
26
|
-
/** Child context to its live installations. */
|
|
27
|
-
byChild = new Map();
|
|
28
|
-
/**
|
|
29
|
-
* Register one contribution.
|
|
30
|
-
* @param contribution - synchronous child-scope installer.
|
|
31
|
-
* @returns an idempotent registration undo.
|
|
32
|
-
* @throws after attempting every installation when any disposer fails.
|
|
33
|
-
*/
|
|
34
|
-
register(contribution) {
|
|
35
|
-
const registration = { contribution, removed: false, installations: new Set() };
|
|
36
|
-
this.registrations.add(registration);
|
|
37
|
-
return () => {
|
|
38
|
-
if (registration.removed)
|
|
39
|
-
return;
|
|
40
|
-
// Close before disposal so a snapshotted apply() cannot install after
|
|
41
|
-
// revocation reports completion.
|
|
42
|
-
registration.removed = true;
|
|
43
|
-
this.registrations.delete(registration);
|
|
44
|
-
this.releaseAll([...registration.installations], 'contribution removal');
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Install every live contribution into one unpublished child context.
|
|
49
|
-
* @param childCtx - the child's unpublished scoped context.
|
|
50
|
-
* @returns the provisioning commit consumed at Agent publication.
|
|
51
|
-
*/
|
|
52
|
-
apply(childCtx) {
|
|
53
|
-
const state = { installations: [], invalidated: false };
|
|
54
|
-
try {
|
|
55
|
-
for (const registration of [...this.registrations]) {
|
|
56
|
-
/* v8 ignore next -- only a synchronous re-entrant revocation of an
|
|
57
|
-
* already-snapshotted registration reaches this guard. */
|
|
58
|
-
if (registration.removed)
|
|
59
|
-
continue;
|
|
60
|
-
const installation = {
|
|
61
|
-
registration,
|
|
62
|
-
childCtx,
|
|
63
|
-
dispose: registration.contribution(childCtx),
|
|
64
|
-
released: false,
|
|
65
|
-
transaction: state,
|
|
66
|
-
};
|
|
67
|
-
registration.installations.add(installation);
|
|
68
|
-
state.installations.push(installation);
|
|
69
|
-
let indexed = this.byChild.get(childCtx);
|
|
70
|
-
if (indexed === undefined) {
|
|
71
|
-
indexed = new Set();
|
|
72
|
-
this.byChild.set(childCtx, indexed);
|
|
73
|
-
}
|
|
74
|
-
indexed.add(installation);
|
|
75
|
-
// An installer may revoke itself before its installation record exists.
|
|
76
|
-
// Dispose that escaped record and invalidate the provisioning batch.
|
|
77
|
-
if (isRemoved(registration))
|
|
78
|
-
this.release(installation);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (error) {
|
|
82
|
-
// Keep the installer failure authoritative, but attempt every rollback.
|
|
83
|
-
try {
|
|
84
|
-
this.releaseAll([...state.installations], 'setup rollback');
|
|
85
|
-
}
|
|
86
|
-
catch (releaseFailure) {
|
|
87
|
-
/* v8 ignore next -- requires independent installer and rollback faults. */
|
|
88
|
-
void releaseFailure;
|
|
89
|
-
}
|
|
90
|
-
throw error;
|
|
91
|
-
}
|
|
92
|
-
childCtx.effect(() => () => { this.releaseChild(childCtx); }, 'subagents.activationSetup()');
|
|
93
|
-
return {
|
|
94
|
-
commit: () => {
|
|
95
|
-
if (state.invalidated) {
|
|
96
|
-
throw new SubagentError('a continuable-subagent setup contribution was revoked while this child was being built; '
|
|
97
|
-
+ 'the child was not established', 'ACTIVATION_SETUP_REVOKED');
|
|
98
|
-
}
|
|
99
|
-
for (const installation of state.installations)
|
|
100
|
-
installation.transaction = undefined;
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
/** Release every remaining installation owned by one disposed child scope. */
|
|
105
|
-
releaseChild(childCtx) {
|
|
106
|
-
const indexed = this.byChild.get(childCtx) ?? [];
|
|
107
|
-
this.releaseAll([...indexed], 'child scope disposal');
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Release a batch completely before reporting disposer failures.
|
|
111
|
-
* @param installations - records to release.
|
|
112
|
-
* @param during - operation name for diagnostics.
|
|
113
|
-
*/
|
|
114
|
-
releaseAll(installations, during) {
|
|
115
|
-
const failures = [];
|
|
116
|
-
for (const installation of installations) {
|
|
117
|
-
try {
|
|
118
|
-
this.release(installation);
|
|
119
|
-
}
|
|
120
|
-
catch (error) {
|
|
121
|
-
failures.push(error);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (failures.length === 0)
|
|
125
|
-
return;
|
|
126
|
-
throw new SubagentError(`continuable-subagent setup ${during} failed to release ${failures.length} installation(s): `
|
|
127
|
-
+ failures.map(failure => errorChain(failure)).join('; '), 'ACTIVATION_SETUP_RELEASE_FAILED');
|
|
128
|
-
}
|
|
129
|
-
/** Drop one installation from both indices and dispose it exactly once. */
|
|
130
|
-
release(installation) {
|
|
131
|
-
if (installation.released)
|
|
132
|
-
return;
|
|
133
|
-
installation.released = true;
|
|
134
|
-
installation.registration.installations.delete(installation);
|
|
135
|
-
const indexed = this.byChild.get(installation.childCtx);
|
|
136
|
-
/* v8 ignore next 4 -- every live installation is indexed until this method removes it. */
|
|
137
|
-
if (indexed !== undefined) {
|
|
138
|
-
indexed.delete(installation);
|
|
139
|
-
if (indexed.size === 0)
|
|
140
|
-
this.byChild.delete(installation.childCtx);
|
|
141
|
-
}
|
|
142
|
-
if (installation.transaction !== undefined)
|
|
143
|
-
installation.transaction.invalidated = true;
|
|
144
|
-
installation.dispose();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
export default SubagentActivationSetupRegistry;
|
|
148
|
-
//# sourceMappingURL=activation-setup-registry.js.map
|