@deepseek-ai/dsh-subagent 0.1.6-alpha.1 → 0.1.6-alpha.2
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 -0
- package/README.zh.md +12 -0
- package/lib/index.js +116 -50
- package/lib/typert.host.js +39 -24
- package/lib/typert.remote-client.js +31 -23
- package/lib/types/continuation-activation.d.ts +17 -1
- package/lib/types/continuation-activation.js +41 -4
- package/lib/types/continuation.d.ts +1 -1
- package/lib/types/continuation.js +2 -2
- package/lib/types/control.js +1 -0
- package/lib/types/index.d.ts +18 -1
- package/lib/types/index.js +29 -3
- package/package.json +54 -48
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/subagent/subagent/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 4634f0a33f71709668732b7070a2bccded3db5c0
|
|
6
|
+
README.zh.md: d3d8a597f23153b0c82e663d98142a9966f48c22
|
package/README.md
CHANGED
|
@@ -42,6 +42,18 @@ Mount the service with a provider and the delegation tool. The provider register
|
|
|
42
42
|
|
|
43
43
|
An agent that calls the tool gets the child's final answer as the tool result. Mounting the service alone changes nothing: nothing can delegate until a provider and a tool are composed.
|
|
44
44
|
|
|
45
|
+
### Delegation settings
|
|
46
|
+
|
|
47
|
+
The limits section on the **Plugins → Subagent** page edits the Host’s `subagent` settings section. User values override this plugin's composition; reset removes the user override. `maxDepth` defaults to `1` and supplies the delegation tools' depth when their own configuration omits it. An explicit tool depth, including `provider-managed`, takes precedence. Depth `0` disables delegation through tools inheriting this setting; depth `1` permits direct children only. Changes apply on the next delegation attempt. Direct service callers continue to supply their own optional request depth.
|
|
48
|
+
|
|
49
|
+
### Continuable capacity
|
|
50
|
+
|
|
51
|
+
Set `maxActiveSubagents` on the host `dsh-subagent` plugin to limit live children sharing uninterrupted continuable parent links. It defaults to `8` and accepts positive safe integers. A non-continuable parent starts a separate pool and does not consume a slot; continuable descendants inherit that pool. Fresh creation and cold resume reserve before reconstructing the Agent, and cleanup returns the slot after handle disposal. A waiting parent, pending inbox work, and an Activation being stopped still occupy slots. Messages to a resident child reuse its slot. One-shot and external-provider runs are outside this limit. Pool inheritance does not cross a one-shot parent; its continuable children share a separate pool. Depth remains the delegation tool's separate policy.
|
|
52
|
+
|
|
53
|
+
The current `maxActiveSubagents` value is sampled before every new or cold-resumed Activation. Raising it admits more children in existing trees; lowering it leaves resident children running and refuses further admissions until usage is below the limit.
|
|
54
|
+
|
|
55
|
+
At capacity, creation or cold resume rejects with `ACTIVATION_LIMIT_REACHED` (browser prompts receive `subagent/delivery-unavailable`): wait for a child to finish or continue using the existing agents. Admission does not queue, because a parent waiting for descendants must not wait for its own occupied slot. Slots are process-local and do not constrain cumulative Session history or token usage.
|
|
56
|
+
|
|
45
57
|
### One-shot and continuable children
|
|
46
58
|
|
|
47
59
|
One-shot children run once and settle with a single result, plus an optional structured output and a safe diagnostic on failure. A start request may override the child Agent's provider, model, reasoning effort, and output-token limit through `agentOptions`; every requested option requires the provider's matching capability. Continuable children keep a durable session and accept later messages in order: the caller receives a stable child id, sends adjacent-Agent messages, and can interrupt the current turn without destroying the child. The tool row's `backgroundMode` picks the shape (`one-shot` by default, or `continuable` on providers that support it).
|
package/README.zh.md
CHANGED
|
@@ -42,6 +42,18 @@ kind: "package-reference"
|
|
|
42
42
|
|
|
43
43
|
调用该工具的 agent 会把子 agent 的最终答案作为工具结果收到。只挂载服务本身不会改变任何行为:在组合出提供方和工具之前,什么都不能委派。
|
|
44
44
|
|
|
45
|
+
### 委派设置
|
|
46
|
+
|
|
47
|
+
**插件 → Subagent** 页面的限制部分编辑 Host 的 `subagent` 设置分节。用户值覆盖本插件的组合配置;恢复默认会删除用户覆盖。`maxDepth` 默认为 `1`,在委派工具自身未配置深度时提供默认值。工具显式指定的深度(包括 `provider-managed`)优先。深度 `0` 禁止继承此设置的工具委派;深度 `1` 只允许直接子代理。修改在下一次委派时生效。直接调用服务的调用方仍自行提供可选的请求深度。
|
|
48
|
+
|
|
49
|
+
### 可续接子代理容量
|
|
50
|
+
|
|
51
|
+
在 Host 的 `dsh-subagent` 插件上设置 `maxActiveSubagents`,限制通过连续可续接父子关系共享名额的存活子代理数。默认值为 `8`,接受正安全整数。非可续接父代理建立独立的池,自身不占名额;可续接后代继承该池。新建和冷恢复在重建 Agent 前预占名额,清理在 handle 释放后归还名额。等待后代的父代理、有待处理收件箱内容的代理以及正在停止的 Activation 仍占名额。向驻留子代理发送消息复用其名额。一次性和外部提供方运行不受此限制。池的继承不会跨越一次性父代理;其可续接子代理共享独立的池。深度仍由委派工具的独立策略决定。
|
|
52
|
+
|
|
53
|
+
每次新建或冷恢复 Activation 前都会读取当前 `maxActiveSubagents`。调高后已有树可接纳更多子代理;调低后驻留子代理继续运行,使用量降至上限以下前拒绝新接纳。
|
|
54
|
+
|
|
55
|
+
容量耗尽时,新建或冷恢复以 `ACTIVATION_LIMIT_REACHED` 拒绝(浏览器消息返回 `subagent/delivery-unavailable`):等待子代理完成,或继续使用现有代理。接纳不会排队,避免等待后代的父代理又等待自己占用的名额。名额仅存在于当前进程,不限制累计 Session 历史或 token 用量。
|
|
56
|
+
|
|
45
57
|
### 一次性与可继续子级
|
|
46
58
|
|
|
47
59
|
一次性子 agent 只运行一次,并以单个结果结算,可附带可选的结构化输出与失败时的安全诊断。启动请求可以通过 `agentOptions` 覆盖子 Agent 的提供方、模型、推理强度与输出 token 上限;每个请求的选项都要求提供方声明对应能力。可继续子 agent 保留持久会话并按顺序接受后续消息:调用方收到稳定的子 agent id、发送相邻 Agent 消息,并可中断当前轮次而不销毁子 agent。工具行的 `backgroundMode` 选择形态(默认 `one-shot`,或在支持的提供方上使用 `continuable`)。
|
package/lib/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
1
2
|
import { scopeTarget } from "@deepseek-ai/dsh-scope";
|
|
2
3
|
import { assertObjectJsonSchema } from "@deepseek-ai/dsh-tools";
|
|
3
4
|
import { canonicalClientTimeZone } from "@deepseek-ai/dsh-util-time";
|
|
4
5
|
import { Remote, RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
|
|
5
6
|
import { AttachmentError } from "@deepseek-ai/dsh-attachment";
|
|
6
|
-
import { z } from "zod";
|
|
7
|
+
import { z as z$1 } from "zod";
|
|
7
8
|
import { HarnessError, ReasoningEffortId, boundContextSummary, contentHasImage, createUserMessage, errorChain, joinAssistantStreamText } from "@deepseek-ai/dsh-llm";
|
|
8
9
|
import { randomUUID } from "node:crypto";
|
|
9
10
|
import { foldConsumedWork } from "@deepseek-ai/dsh-agent";
|
|
@@ -35,19 +36,19 @@ var SubagentError = class extends HarnessError {
|
|
|
35
36
|
*
|
|
36
37
|
* @module @deepseek-ai/dsh-subagent
|
|
37
38
|
*/
|
|
38
|
-
const SESSION_ID_SCHEMA = z.string().min(1);
|
|
39
|
+
const SESSION_ID_SCHEMA = z$1.string().min(1);
|
|
39
40
|
const CONTROL_ID_SCHEMAS = {
|
|
40
|
-
"subagent.list": z.object({ parentSessionId: SESSION_ID_SCHEMA }),
|
|
41
|
-
"subagent.prompt": z.object({
|
|
41
|
+
"subagent.list": z$1.object({ parentSessionId: SESSION_ID_SCHEMA }),
|
|
42
|
+
"subagent.prompt": z$1.object({
|
|
42
43
|
parentSessionId: SESSION_ID_SCHEMA,
|
|
43
44
|
childSessionId: SESSION_ID_SCHEMA,
|
|
44
|
-
mode: z.literal("continuable"),
|
|
45
|
-
delivery: z.enum(["queue", "steer"])
|
|
45
|
+
mode: z$1.literal("continuable"),
|
|
46
|
+
delivery: z$1.enum(["queue", "steer"])
|
|
46
47
|
}),
|
|
47
|
-
"subagent.interrupt": z.object({
|
|
48
|
+
"subagent.interrupt": z$1.object({
|
|
48
49
|
parentSessionId: SESSION_ID_SCHEMA,
|
|
49
50
|
childSessionId: SESSION_ID_SCHEMA,
|
|
50
|
-
mode: z.literal("continuable")
|
|
51
|
+
mode: z$1.literal("continuable")
|
|
51
52
|
})
|
|
52
53
|
};
|
|
53
54
|
/**
|
|
@@ -113,6 +114,7 @@ function rejectPrompt(error, childSessionId, signal) {
|
|
|
113
114
|
case "UNAUTHORIZED": throw new RemoteError("subagent/unauthorized", "subagent does not belong to this parent", { childSessionId }, { cause: error });
|
|
114
115
|
case "DRAINING":
|
|
115
116
|
case "ACTIVATION_CLOSING":
|
|
117
|
+
case "ACTIVATION_LIMIT_REACHED":
|
|
116
118
|
case "CONTINUATION_UNAVAILABLE":
|
|
117
119
|
case "PERSISTENCE_UNAVAILABLE": throw new RemoteError("subagent/delivery-unavailable", "subagent follow-up is temporarily unavailable", { childSessionId }, { cause: error });
|
|
118
120
|
default: break;
|
|
@@ -752,6 +754,19 @@ var SubagentInbox = class {
|
|
|
752
754
|
*
|
|
753
755
|
* @module @deepseek-ai/dsh-subagent/continuation-activation
|
|
754
756
|
*/
|
|
757
|
+
/** Process-local slots shared through uninterrupted continuable parent links. */
|
|
758
|
+
var ActivationPool = class {
|
|
759
|
+
slots = /* @__PURE__ */ new Set();
|
|
760
|
+
/** Reserve before reconstruction; the returned release also tolerates unpublished rollback. */
|
|
761
|
+
reserve(capacity) {
|
|
762
|
+
if (this.slots.size >= capacity) throw new SubagentError(`subagent limit reached (active child limit: ${capacity}); wait for an existing child to finish or complete this work with the current agents`, "ACTIVATION_LIMIT_REACHED");
|
|
763
|
+
const slot = Symbol();
|
|
764
|
+
this.slots.add(slot);
|
|
765
|
+
return () => {
|
|
766
|
+
this.slots.delete(slot);
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
};
|
|
755
770
|
/** Serialize each durable child's delivery, release, and disposal. */
|
|
756
771
|
var ChildLock = class {
|
|
757
772
|
tails = /* @__PURE__ */ new Map();
|
|
@@ -775,8 +790,11 @@ var ChildLock = class {
|
|
|
775
790
|
var ContinuableActivationRegistry = class {
|
|
776
791
|
ctx;
|
|
777
792
|
observeActivation;
|
|
793
|
+
maxActiveSubagents;
|
|
778
794
|
/** Child session id → its live Activation. Process-local, never durable. */
|
|
779
795
|
resident = /* @__PURE__ */ new Map();
|
|
796
|
+
/** Root identities retain their pool across child settlement without retaining dead roots. */
|
|
797
|
+
rootPools = /* @__PURE__ */ new WeakMap();
|
|
780
798
|
/** Materializations admitted before drain, tracked through publication or rollback. */
|
|
781
799
|
materializations = /* @__PURE__ */ new Set();
|
|
782
800
|
/** Per-child serializer shared by delivery, release, and disposal. */
|
|
@@ -796,9 +814,10 @@ var ContinuableActivationRegistry = class {
|
|
|
796
814
|
* @param ctx - context providing Agents, Sessions, and teardown ownership.
|
|
797
815
|
* @param observeActivation - build the lifecycle observer for one residency epoch.
|
|
798
816
|
*/
|
|
799
|
-
constructor(ctx, observeActivation) {
|
|
817
|
+
constructor(ctx, observeActivation, maxActiveSubagents) {
|
|
800
818
|
this.ctx = ctx;
|
|
801
819
|
this.observeActivation = observeActivation;
|
|
820
|
+
this.maxActiveSubagents = maxActiveSubagents;
|
|
802
821
|
const scope = ctx.plugin(function activationOwner() {});
|
|
803
822
|
this.ownerCtx = scope.ctx;
|
|
804
823
|
ctx.on("agent/disposed", ({ agent }) => {
|
|
@@ -979,14 +998,20 @@ var ContinuableActivationRegistry = class {
|
|
|
979
998
|
*/
|
|
980
999
|
materialize(inputs) {
|
|
981
1000
|
this.assertAdmitting(inputs.parent);
|
|
982
|
-
|
|
1001
|
+
inputs.signal.throwIfAborted();
|
|
983
1002
|
const lineage = this.liveLineage(inputs.parent);
|
|
1003
|
+
const pool = this.resident.get(inputs.parent.id)?.pool ?? this.rootPool(inputs.parent);
|
|
1004
|
+
const releaseSlot = pool.reserve(this.maxActiveSubagents());
|
|
1005
|
+
const settled = Promise.withResolvers();
|
|
984
1006
|
const materialization = {
|
|
985
1007
|
lineage,
|
|
986
1008
|
settled: settled.promise
|
|
987
1009
|
};
|
|
988
1010
|
this.materializations.add(materialization);
|
|
989
|
-
return this.materializeTracked(inputs, lineage).
|
|
1011
|
+
return this.materializeTracked(inputs, lineage, pool, releaseSlot).catch((error) => {
|
|
1012
|
+
releaseSlot();
|
|
1013
|
+
throw error;
|
|
1014
|
+
}).finally(() => {
|
|
990
1015
|
this.materializations.delete(materialization);
|
|
991
1016
|
settled.resolve();
|
|
992
1017
|
});
|
|
@@ -1061,8 +1086,17 @@ var ContinuableActivationRegistry = class {
|
|
|
1061
1086
|
const lineage = this.liveLineage(agent);
|
|
1062
1087
|
for (const [root, members] of this.closingScopes) if (members.has(agent) || lineage.includes(root)) return root;
|
|
1063
1088
|
}
|
|
1089
|
+
/** Resolve a root's pool once; descendants inherit their resident parent's pool directly. */
|
|
1090
|
+
rootPool(parent) {
|
|
1091
|
+
let pool = this.rootPools.get(parent);
|
|
1092
|
+
if (pool === void 0) {
|
|
1093
|
+
pool = new ActivationPool();
|
|
1094
|
+
this.rootPools.set(parent, pool);
|
|
1095
|
+
}
|
|
1096
|
+
return pool;
|
|
1097
|
+
}
|
|
1064
1098
|
/** Perform one tracked materialization through publication or rollback. */
|
|
1065
|
-
async materializeTracked(inputs, parentLineage) {
|
|
1099
|
+
async materializeTracked(inputs, parentLineage, pool, releaseSlot) {
|
|
1066
1100
|
const { childId, provider, parent, create } = inputs;
|
|
1067
1101
|
inputs.signal.throwIfAborted();
|
|
1068
1102
|
const setup = (childCtx, child) => {
|
|
@@ -1090,6 +1124,8 @@ var ContinuableActivationRegistry = class {
|
|
|
1090
1124
|
setup
|
|
1091
1125
|
});
|
|
1092
1126
|
const activation = {
|
|
1127
|
+
pool,
|
|
1128
|
+
releaseSlot,
|
|
1093
1129
|
childId,
|
|
1094
1130
|
parentSession: parent.id,
|
|
1095
1131
|
provider,
|
|
@@ -1128,6 +1164,7 @@ var ContinuableActivationRegistry = class {
|
|
|
1128
1164
|
await activation.handle.dispose();
|
|
1129
1165
|
} finally {
|
|
1130
1166
|
this.resident.delete(activation.childId);
|
|
1167
|
+
activation.releaseSlot();
|
|
1131
1168
|
this.releaseOwnership(activation.childId);
|
|
1132
1169
|
}
|
|
1133
1170
|
});
|
|
@@ -1241,6 +1278,7 @@ var ContinuableActivationRegistry = class {
|
|
|
1241
1278
|
if (failures.length === 1) failure = failures[0];
|
|
1242
1279
|
else if (failures.length > 1) failure = new SubagentError(`subagent "${childId}" activation teardown failed at ${failures.length} boundaries: ` + failures.map((item) => errorChain(item)).join("; "), "ACTIVATION_TEARDOWN_FAILED", { cause: new AggregateError(failures) });
|
|
1243
1280
|
this.resident.delete(childId);
|
|
1281
|
+
activation.releaseSlot();
|
|
1244
1282
|
this.notifySettlement(activation, activation.observer.terminal(failure));
|
|
1245
1283
|
this.releaseOwnership(childId);
|
|
1246
1284
|
activation.observer.settle(failure);
|
|
@@ -1432,23 +1470,23 @@ function foldSubagentDescriptor(events) {
|
|
|
1432
1470
|
if (event === void 0) return void 0;
|
|
1433
1471
|
return parseSubagentDescriptor(event.data);
|
|
1434
1472
|
}
|
|
1435
|
-
const sessionIdSchema = z.string();
|
|
1436
|
-
const oneShotCatalogSchema = z.object({
|
|
1437
|
-
version: z.literal(0),
|
|
1473
|
+
const sessionIdSchema = z$1.string();
|
|
1474
|
+
const oneShotCatalogSchema = z$1.object({
|
|
1475
|
+
version: z$1.literal(0),
|
|
1438
1476
|
childId: sessionIdSchema,
|
|
1439
|
-
childCreatedAt: z.number().int().nonnegative(),
|
|
1440
|
-
mode: z.literal("one-shot"),
|
|
1441
|
-
label: z.string().optional()
|
|
1477
|
+
childCreatedAt: z$1.number().int().nonnegative(),
|
|
1478
|
+
mode: z$1.literal("one-shot"),
|
|
1479
|
+
label: z$1.string().optional()
|
|
1442
1480
|
}).strict();
|
|
1443
|
-
const continuableCatalogSchema = z.object({
|
|
1444
|
-
version: z.literal(0),
|
|
1481
|
+
const continuableCatalogSchema = z$1.object({
|
|
1482
|
+
version: z$1.literal(0),
|
|
1445
1483
|
childId: sessionIdSchema,
|
|
1446
|
-
childCreatedAt: z.number().int().nonnegative(),
|
|
1447
|
-
mode: z.literal("continuable"),
|
|
1448
|
-
label: z.string()
|
|
1484
|
+
childCreatedAt: z$1.number().int().nonnegative(),
|
|
1485
|
+
mode: z$1.literal("continuable"),
|
|
1486
|
+
label: z$1.string()
|
|
1449
1487
|
}).strict();
|
|
1450
|
-
const eventDataSchema = z.union([oneShotCatalogSchema, continuableCatalogSchema]);
|
|
1451
|
-
const viewSchema = z.array(z.union([oneShotCatalogSchema.omit({
|
|
1488
|
+
const eventDataSchema = z$1.union([oneShotCatalogSchema, continuableCatalogSchema]);
|
|
1489
|
+
const viewSchema = z$1.array(z$1.union([oneShotCatalogSchema.omit({
|
|
1452
1490
|
version: true,
|
|
1453
1491
|
childId: true,
|
|
1454
1492
|
childCreatedAt: true
|
|
@@ -1463,8 +1501,8 @@ const viewSchema = z.array(z.union([oneShotCatalogSchema.omit({
|
|
|
1463
1501
|
id: sessionIdSchema,
|
|
1464
1502
|
createdAt: continuableCatalogSchema.shape.childCreatedAt
|
|
1465
1503
|
})]));
|
|
1466
|
-
const stateSchema = z.object({
|
|
1467
|
-
inheritedEventCount: z.number().int().nonnegative(),
|
|
1504
|
+
const stateSchema = z$1.object({
|
|
1505
|
+
inheritedEventCount: z$1.number().int().nonnegative(),
|
|
1468
1506
|
head: chunkedListSchema(eventDataSchema).optional()
|
|
1469
1507
|
}).strict();
|
|
1470
1508
|
/**
|
|
@@ -1633,10 +1671,10 @@ var SubagentContinuationManager = class {
|
|
|
1633
1671
|
ctx;
|
|
1634
1672
|
host;
|
|
1635
1673
|
activations;
|
|
1636
|
-
constructor(ctx, host) {
|
|
1674
|
+
constructor(ctx, host, maxActiveSubagents) {
|
|
1637
1675
|
this.ctx = ctx;
|
|
1638
1676
|
this.host = host;
|
|
1639
|
-
this.activations = new ContinuableActivationRegistry(ctx, (provider, childId, parent) => host.observeActivation(provider, childId, parent));
|
|
1677
|
+
this.activations = new ContinuableActivationRegistry(ctx, (provider, childId, parent) => host.observeActivation(provider, childId, parent), maxActiveSubagents);
|
|
1640
1678
|
}
|
|
1641
1679
|
/**
|
|
1642
1680
|
* Start one continuable background child and resolve at initial inbox acceptance.
|
|
@@ -2322,12 +2360,12 @@ function sessionQueryCode(error) {
|
|
|
2322
2360
|
*
|
|
2323
2361
|
* @module @deepseek-ai/dsh-subagent/projection
|
|
2324
2362
|
*/
|
|
2325
|
-
const activeIntervalSchema = z.object({
|
|
2326
|
-
since: z.number().int().nonnegative(),
|
|
2327
|
-
through: z.number().int().nonnegative()
|
|
2363
|
+
const activeIntervalSchema = z$1.object({
|
|
2364
|
+
since: z$1.number().int().nonnegative(),
|
|
2365
|
+
through: z$1.number().int().nonnegative()
|
|
2328
2366
|
}).strict();
|
|
2329
|
-
const projectionSchema = z.object({
|
|
2330
|
-
settledMs: z.number().int().nonnegative(),
|
|
2367
|
+
const projectionSchema = z$1.object({
|
|
2368
|
+
settledMs: z$1.number().int().nonnegative(),
|
|
2331
2369
|
active: activeIntervalSchema.optional()
|
|
2332
2370
|
}).strict().transform(({ settledMs, active }) => ({
|
|
2333
2371
|
settledMs,
|
|
@@ -2343,11 +2381,11 @@ const projectionSchema = z.object({
|
|
|
2343
2381
|
*/
|
|
2344
2382
|
const subagentTimingProjectionDefinition = {
|
|
2345
2383
|
key: "subagentTiming",
|
|
2346
|
-
stateSchema: z.object({
|
|
2347
|
-
settledMs: z.number().int().nonnegative(),
|
|
2384
|
+
stateSchema: z$1.object({
|
|
2385
|
+
settledMs: z$1.number().int().nonnegative(),
|
|
2348
2386
|
active: activeIntervalSchema.optional(),
|
|
2349
|
-
pendingTurnStart: z.number().int().nonnegative().optional(),
|
|
2350
|
-
descriptorSeen: z.boolean()
|
|
2387
|
+
pendingTurnStart: z$1.number().int().nonnegative().optional(),
|
|
2388
|
+
descriptorSeen: z$1.boolean()
|
|
2351
2389
|
}).strict(),
|
|
2352
2390
|
init: () => ({
|
|
2353
2391
|
descriptorSeen: false,
|
|
@@ -2406,17 +2444,17 @@ const subagentTimingProjectionDefinition = {
|
|
|
2406
2444
|
},
|
|
2407
2445
|
stateVersion: 2
|
|
2408
2446
|
};
|
|
2409
|
-
const identityValueSchema = z.discriminatedUnion("mode", [z.object({
|
|
2410
|
-
mode: z.literal("one-shot"),
|
|
2411
|
-
label: z.string().optional(),
|
|
2412
|
-
seq: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq)
|
|
2413
|
-
}).strict(), z.object({
|
|
2414
|
-
mode: z.literal("continuable"),
|
|
2415
|
-
label: z.string(),
|
|
2416
|
-
seq: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq)
|
|
2447
|
+
const identityValueSchema = z$1.discriminatedUnion("mode", [z$1.object({
|
|
2448
|
+
mode: z$1.literal("one-shot"),
|
|
2449
|
+
label: z$1.string().optional(),
|
|
2450
|
+
seq: z$1.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq)
|
|
2451
|
+
}).strict(), z$1.object({
|
|
2452
|
+
mode: z$1.literal("continuable"),
|
|
2453
|
+
label: z$1.string(),
|
|
2454
|
+
seq: z$1.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).transform(SessionSeq)
|
|
2417
2455
|
}).strict()]);
|
|
2418
2456
|
const identitySchema = identityValueSchema.nullable();
|
|
2419
|
-
const identityStateSchema = z.object({ identity: identityValueSchema.optional() }).strict();
|
|
2457
|
+
const identityStateSchema = z$1.object({ identity: identityValueSchema.optional() }).strict();
|
|
2420
2458
|
/** Interpret one `subagent/descriptor` event's identity; no value when the payload cannot be trusted. */
|
|
2421
2459
|
function descriptorIdentity(event) {
|
|
2422
2460
|
let descriptor;
|
|
@@ -2846,7 +2884,12 @@ let SubagentRuntime = (() => {
|
|
|
2846
2884
|
value: _metadata
|
|
2847
2885
|
});
|
|
2848
2886
|
}
|
|
2849
|
-
|
|
2887
|
+
static Config = z.object({
|
|
2888
|
+
maxDepth: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER).default(1),
|
|
2889
|
+
maxActiveSubagents: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER).default(8)
|
|
2890
|
+
});
|
|
2891
|
+
settingsSource = __runInitializers(this, _instanceExtraInitializers);
|
|
2892
|
+
providers = /* @__PURE__ */ new Map();
|
|
2850
2893
|
continuations;
|
|
2851
2894
|
/**
|
|
2852
2895
|
* The contained lifecycle-edge publisher. Built here because scoped dispatch
|
|
@@ -2854,14 +2897,27 @@ let SubagentRuntime = (() => {
|
|
|
2854
2897
|
* composes into the carrier.
|
|
2855
2898
|
*/
|
|
2856
2899
|
emitLifecycle;
|
|
2857
|
-
constructor(ctx) {
|
|
2900
|
+
constructor(ctx, config) {
|
|
2858
2901
|
super(ctx, "subagents");
|
|
2902
|
+
assertSubagentMaxDepth(config.maxDepth);
|
|
2903
|
+
this.settingsSource = () => config;
|
|
2904
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
2905
|
+
settingsCtx.settings.installSection(ctx, "subagent", SubagentRuntime.Config, config, {
|
|
2906
|
+
validate: (value) => {
|
|
2907
|
+
assertSubagentMaxDepth(value.maxDepth);
|
|
2908
|
+
},
|
|
2909
|
+
setSource: (source) => {
|
|
2910
|
+
this.settingsSource = source;
|
|
2911
|
+
},
|
|
2912
|
+
onChange: () => {}
|
|
2913
|
+
});
|
|
2914
|
+
});
|
|
2859
2915
|
this.emitLifecycle = createLifecycleEmitter(this.ctx, (parent) => scopeTarget(this, parent));
|
|
2860
2916
|
ctx.inject(["agents"], (childCtx) => {
|
|
2861
2917
|
const manager = new SubagentContinuationManager(childCtx, {
|
|
2862
2918
|
prepareContinuable: (name, request) => this.prepareContinuable(name, request),
|
|
2863
2919
|
observeActivation: (provider, childId, parent) => this.observeActivation(provider, childId, parent)
|
|
2864
|
-
});
|
|
2920
|
+
}, () => this.settingsSource().maxActiveSubagents);
|
|
2865
2921
|
this.continuations = manager;
|
|
2866
2922
|
childCtx.effect(() => () => {
|
|
2867
2923
|
/* v8 ignore else -- one injected binding owns the slot until its fiber disposes. */
|
|
@@ -2875,6 +2931,15 @@ let SubagentRuntime = (() => {
|
|
|
2875
2931
|
});
|
|
2876
2932
|
}
|
|
2877
2933
|
/**
|
|
2934
|
+
* Resolve a delegation tool's depth policy against the current user setting.
|
|
2935
|
+
* @param configured - Explicit tool limit, or provider-managed for external delegation.
|
|
2936
|
+
* @returns The numeric limit, or undefined when the provider owns depth enforcement.
|
|
2937
|
+
*/
|
|
2938
|
+
resolveMaxDepth(configured) {
|
|
2939
|
+
if (configured === "provider-managed") return void 0;
|
|
2940
|
+
return configured ?? this.settingsSource().maxDepth;
|
|
2941
|
+
}
|
|
2942
|
+
/**
|
|
2878
2943
|
* Establish one durable continuable child and deliver its initial prompt.
|
|
2879
2944
|
* Resolves when the child's inbox accepts that prompt, without waiting for the
|
|
2880
2945
|
* turn to start or for the message to reach the Session log; any earlier
|
|
@@ -3034,6 +3099,7 @@ let SubagentRuntime = (() => {
|
|
|
3034
3099
|
* nearest step and retains the Agent loop's best-effort fallback semantics.
|
|
3035
3100
|
* Image parts are admitted and persisted through the attachment store
|
|
3036
3101
|
* before delivery, and the child's model must accept image input.
|
|
3102
|
+
* Cold resume at capacity rejects with `subagent/delivery-unavailable`.
|
|
3037
3103
|
* @param request - durable address, delivery, minted identity, content, and optional browser zone.
|
|
3038
3104
|
* @param signal - carrier cancellation, owning the call until inbox acceptance.
|
|
3039
3105
|
* @returns the accepted message's inbox identity.
|
package/lib/typert.host.js
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/* Generated by @deepseek-ai/dsh-typert-generator from FaceModel — do not edit. */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const
|
|
4
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema$value
|
|
5
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
6
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema$value
|
|
7
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
8
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema$value
|
|
9
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema$value ??= z.literal("continuable"))
|
|
10
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema$value
|
|
11
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema$value ??= z.object({
|
|
8
12
|
'accepted': z.literal(true).readonly(),
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
const
|
|
13
|
+
}))
|
|
14
|
+
let _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema$value
|
|
15
|
+
const _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
16
|
+
let _deepseek_ai_dsh_subagent_subagents_list_result$schema$value
|
|
17
|
+
const _deepseek_ai_dsh_subagent_subagents_list_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_list_result$schema$value ??= z.object({
|
|
12
18
|
'entries': z.array(z.union([z.intersection(z.object({
|
|
13
19
|
'kind': z.literal("child").readonly(),
|
|
14
20
|
'id': z.intersection(z.string(), z.unknown()).readonly(),
|
|
@@ -31,8 +37,9 @@ const _deepseek_ai_dsh_subagent_subagents_list_result$schema = z.object({
|
|
|
31
37
|
'reason': z.union([z.literal("corrupt"), z.literal("unsupported"), z.literal("unavailable")]).readonly(),
|
|
32
38
|
})])).readonly(),
|
|
33
39
|
'parentAvailable': z.boolean().readonly(),
|
|
34
|
-
})
|
|
35
|
-
|
|
40
|
+
}))
|
|
41
|
+
let _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema$value
|
|
42
|
+
const _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema$value ??= z.object({
|
|
36
43
|
'requestId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
37
44
|
'parentSessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
38
45
|
'childSessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
@@ -48,10 +55,11 @@ const _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema = z.object({
|
|
|
48
55
|
'name': z.string().readonly().optional(),
|
|
49
56
|
})])).readonly(),
|
|
50
57
|
'clientTimeZone': z.string().readonly().optional(),
|
|
51
|
-
})
|
|
52
|
-
|
|
58
|
+
}))
|
|
59
|
+
let _deepseek_ai_dsh_subagent_subagents_prompt_result$schema$value
|
|
60
|
+
const _deepseek_ai_dsh_subagent_subagents_prompt_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_prompt_result$schema$value ??= z.object({
|
|
53
61
|
'messageId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
54
|
-
})
|
|
62
|
+
}))
|
|
55
63
|
|
|
56
64
|
export const TYPERT = {
|
|
57
65
|
package: '@deepseek-ai/dsh-subagent',
|
|
@@ -73,7 +81,7 @@ export const TYPERT = {
|
|
|
73
81
|
codec: {
|
|
74
82
|
mode: 'strict',
|
|
75
83
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
76
|
-
|
|
84
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema,
|
|
77
85
|
},
|
|
78
86
|
},
|
|
79
87
|
{
|
|
@@ -83,7 +91,7 @@ export const TYPERT = {
|
|
|
83
91
|
codec: {
|
|
84
92
|
mode: 'strict',
|
|
85
93
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
86
|
-
|
|
94
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema,
|
|
87
95
|
},
|
|
88
96
|
},
|
|
89
97
|
{
|
|
@@ -93,16 +101,16 @@ export const TYPERT = {
|
|
|
93
101
|
codec: {
|
|
94
102
|
mode: 'strict',
|
|
95
103
|
typeSymbol: '@deepseek-ai/dsh-subagent#subagents/interruptByParent:mode',
|
|
96
|
-
|
|
104
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema,
|
|
97
105
|
},
|
|
98
106
|
},
|
|
99
107
|
],
|
|
100
108
|
result: {
|
|
101
109
|
mode: 'strict',
|
|
102
110
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentInterruptReceipt',
|
|
103
|
-
|
|
111
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema,
|
|
104
112
|
},
|
|
105
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
113
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":515,"column":3},
|
|
106
114
|
},
|
|
107
115
|
{
|
|
108
116
|
id: '@deepseek-ai/dsh-subagent#subagents/list',
|
|
@@ -119,7 +127,7 @@ export const TYPERT = {
|
|
|
119
127
|
codec: {
|
|
120
128
|
mode: 'strict',
|
|
121
129
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
122
|
-
|
|
130
|
+
create: _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema,
|
|
123
131
|
},
|
|
124
132
|
},
|
|
125
133
|
],
|
|
@@ -127,9 +135,9 @@ export const TYPERT = {
|
|
|
127
135
|
result: {
|
|
128
136
|
mode: 'strict',
|
|
129
137
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentCatalog',
|
|
130
|
-
|
|
138
|
+
create: _deepseek_ai_dsh_subagent_subagents_list_result$schema,
|
|
131
139
|
},
|
|
132
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
140
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":420,"column":9},
|
|
133
141
|
},
|
|
134
142
|
{
|
|
135
143
|
id: '@deepseek-ai/dsh-subagent#subagents/prompt',
|
|
@@ -145,7 +153,7 @@ export const TYPERT = {
|
|
|
145
153
|
codec: {
|
|
146
154
|
mode: 'strict',
|
|
147
155
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentPromptRequest',
|
|
148
|
-
|
|
156
|
+
create: _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema,
|
|
149
157
|
},
|
|
150
158
|
},
|
|
151
159
|
],
|
|
@@ -153,9 +161,9 @@ export const TYPERT = {
|
|
|
153
161
|
result: {
|
|
154
162
|
mode: 'strict',
|
|
155
163
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentPromptReceipt',
|
|
156
|
-
|
|
164
|
+
create: _deepseek_ai_dsh_subagent_subagents_prompt_result$schema,
|
|
157
165
|
},
|
|
158
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
166
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":448,"column":9},
|
|
159
167
|
},
|
|
160
168
|
],
|
|
161
169
|
model: {
|
|
@@ -168,6 +176,13 @@ export const TYPERT = {
|
|
|
168
176
|
"key": "subagents",
|
|
169
177
|
"exportName": "SubagentRuntime",
|
|
170
178
|
"members": [
|
|
179
|
+
{
|
|
180
|
+
"kind": "method",
|
|
181
|
+
"name": "resolveMaxDepth",
|
|
182
|
+
"signature": "resolveMaxDepth(configured?: number | 'provider-managed'): number | undefined",
|
|
183
|
+
"summary": "Resolve a delegation tool's depth policy against the current user setting.",
|
|
184
|
+
"jsDoc": "/**\n * Resolve a delegation tool's depth policy against the current user setting.\n * @param configured - Explicit tool limit, or provider-managed for external delegation.\n * @returns The numeric limit, or undefined when the provider owns depth enforcement.\n */"
|
|
185
|
+
},
|
|
171
186
|
{
|
|
172
187
|
"kind": "method",
|
|
173
188
|
"name": "startContinuable",
|
|
@@ -229,7 +244,7 @@ export const TYPERT = {
|
|
|
229
244
|
"name": "prompt",
|
|
230
245
|
"signature": "@Remote('prompt') async prompt(request: SubagentPromptRequest, signal: AbortSignal): Promise<SubagentPromptReceipt>",
|
|
231
246
|
"summary": "Deliver one browser-authored message to a continuable child through the exact live direct parent, retaining the caller-minted request identity and validated browser zone on the accepted message.",
|
|
232
|
-
"jsDoc": "/**\n * Deliver one browser-authored message to a continuable child through the\n * exact live direct parent, retaining the caller-minted request identity and\n * validated browser zone on the accepted message. Success identifies the\n * message the child's inbox accepted; later execution is independent of this\n * call. Queue delivery targets a later turn; steer delivery targets the\n * nearest step and retains the Agent loop's best-effort fallback semantics.\n * Image parts are admitted and persisted through the attachment store\n * before delivery, and the child's model must accept image input.\n * @param request - durable address, delivery, minted identity, content, and optional browser zone.\n * @param signal - carrier cancellation, owning the call until inbox acceptance.\n * @returns the accepted message's inbox identity.\n * @throws {RemoteError} `gateway/bad-request`, `subagent/attachment-invalid`,\n * `subagent/invalid-time-zone`, `subagent/parent-unavailable`,\n * `subagent/not-resumable`, `subagent/unauthorized`,\n * `subagent/delivery-unavailable`, `gateway/cancelled`, or `gateway/internal`.\n */"
|
|
247
|
+
"jsDoc": "/**\n * Deliver one browser-authored message to a continuable child through the\n * exact live direct parent, retaining the caller-minted request identity and\n * validated browser zone on the accepted message. Success identifies the\n * message the child's inbox accepted; later execution is independent of this\n * call. Queue delivery targets a later turn; steer delivery targets the\n * nearest step and retains the Agent loop's best-effort fallback semantics.\n * Image parts are admitted and persisted through the attachment store\n * before delivery, and the child's model must accept image input.\n * Cold resume at capacity rejects with `subagent/delivery-unavailable`.\n * @param request - durable address, delivery, minted identity, content, and optional browser zone.\n * @param signal - carrier cancellation, owning the call until inbox acceptance.\n * @returns the accepted message's inbox identity.\n * @throws {RemoteError} `gateway/bad-request`, `subagent/attachment-invalid`,\n * `subagent/invalid-time-zone`, `subagent/parent-unavailable`,\n * `subagent/not-resumable`, `subagent/unauthorized`,\n * `subagent/delivery-unavailable`, `gateway/cancelled`, or `gateway/internal`.\n */"
|
|
233
248
|
},
|
|
234
249
|
{
|
|
235
250
|
"kind": "method",
|
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
/* Generated by @deepseek-ai/dsh-typert-generator from the Host FaceModel — do not edit. */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
const
|
|
4
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema$value
|
|
5
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
6
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema$value
|
|
7
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
8
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema$value
|
|
9
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema$value ??= z.literal("continuable"))
|
|
10
|
+
let _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema$value
|
|
11
|
+
const _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema$value ??= z.object({
|
|
8
12
|
'accepted': z.literal(true).readonly(),
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
const
|
|
13
|
+
}))
|
|
14
|
+
let _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema$value
|
|
15
|
+
const _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
|
|
16
|
+
let _deepseek_ai_dsh_subagent_subagents_list_result$schema$value
|
|
17
|
+
const _deepseek_ai_dsh_subagent_subagents_list_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_list_result$schema$value ??= z.object({
|
|
12
18
|
'entries': z.array(z.union([z.intersection(z.object({
|
|
13
19
|
'kind': z.literal("child").readonly(),
|
|
14
20
|
'id': z.intersection(z.string(), z.unknown()).readonly(),
|
|
@@ -31,8 +37,9 @@ const _deepseek_ai_dsh_subagent_subagents_list_result$schema = z.object({
|
|
|
31
37
|
'reason': z.union([z.literal("corrupt"), z.literal("unsupported"), z.literal("unavailable")]).readonly(),
|
|
32
38
|
})])).readonly(),
|
|
33
39
|
'parentAvailable': z.boolean().readonly(),
|
|
34
|
-
})
|
|
35
|
-
|
|
40
|
+
}))
|
|
41
|
+
let _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema$value
|
|
42
|
+
const _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema = () => (_deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema$value ??= z.object({
|
|
36
43
|
'requestId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
37
44
|
'parentSessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
38
45
|
'childSessionId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
@@ -48,10 +55,11 @@ const _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema = z.object({
|
|
|
48
55
|
'name': z.string().readonly().optional(),
|
|
49
56
|
})])).readonly(),
|
|
50
57
|
'clientTimeZone': z.string().readonly().optional(),
|
|
51
|
-
})
|
|
52
|
-
|
|
58
|
+
}))
|
|
59
|
+
let _deepseek_ai_dsh_subagent_subagents_prompt_result$schema$value
|
|
60
|
+
const _deepseek_ai_dsh_subagent_subagents_prompt_result$schema = () => (_deepseek_ai_dsh_subagent_subagents_prompt_result$schema$value ??= z.object({
|
|
53
61
|
'messageId': z.intersection(z.string(), z.unknown()).readonly(),
|
|
54
|
-
})
|
|
62
|
+
}))
|
|
55
63
|
|
|
56
64
|
export const TYPERT_REMOTE = {
|
|
57
65
|
package: '@deepseek-ai/dsh-subagent',
|
|
@@ -70,7 +78,7 @@ export const TYPERT_REMOTE = {
|
|
|
70
78
|
codec: {
|
|
71
79
|
mode: 'strict',
|
|
72
80
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
73
|
-
|
|
81
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_0$schema,
|
|
74
82
|
},
|
|
75
83
|
},
|
|
76
84
|
{
|
|
@@ -80,7 +88,7 @@ export const TYPERT_REMOTE = {
|
|
|
80
88
|
codec: {
|
|
81
89
|
mode: 'strict',
|
|
82
90
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
83
|
-
|
|
91
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_1$schema,
|
|
84
92
|
},
|
|
85
93
|
},
|
|
86
94
|
{
|
|
@@ -90,16 +98,16 @@ export const TYPERT_REMOTE = {
|
|
|
90
98
|
codec: {
|
|
91
99
|
mode: 'strict',
|
|
92
100
|
typeSymbol: '@deepseek-ai/dsh-subagent#subagents/interruptByParent:mode',
|
|
93
|
-
|
|
101
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_parameter_2$schema,
|
|
94
102
|
},
|
|
95
103
|
},
|
|
96
104
|
],
|
|
97
105
|
result: {
|
|
98
106
|
mode: 'strict',
|
|
99
107
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentInterruptReceipt',
|
|
100
|
-
|
|
108
|
+
create: _deepseek_ai_dsh_subagent_subagents_interruptByParent_result$schema,
|
|
101
109
|
},
|
|
102
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
110
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":515,"column":3},
|
|
103
111
|
},
|
|
104
112
|
{
|
|
105
113
|
id: '@deepseek-ai/dsh-subagent#subagents/list',
|
|
@@ -116,7 +124,7 @@ export const TYPERT_REMOTE = {
|
|
|
116
124
|
codec: {
|
|
117
125
|
mode: 'strict',
|
|
118
126
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
119
|
-
|
|
127
|
+
create: _deepseek_ai_dsh_subagent_subagents_list_parameter_0$schema,
|
|
120
128
|
},
|
|
121
129
|
},
|
|
122
130
|
],
|
|
@@ -124,9 +132,9 @@ export const TYPERT_REMOTE = {
|
|
|
124
132
|
result: {
|
|
125
133
|
mode: 'strict',
|
|
126
134
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentCatalog',
|
|
127
|
-
|
|
135
|
+
create: _deepseek_ai_dsh_subagent_subagents_list_result$schema,
|
|
128
136
|
},
|
|
129
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
137
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":420,"column":9},
|
|
130
138
|
},
|
|
131
139
|
{
|
|
132
140
|
id: '@deepseek-ai/dsh-subagent#subagents/prompt',
|
|
@@ -142,7 +150,7 @@ export const TYPERT_REMOTE = {
|
|
|
142
150
|
codec: {
|
|
143
151
|
mode: 'strict',
|
|
144
152
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentPromptRequest',
|
|
145
|
-
|
|
153
|
+
create: _deepseek_ai_dsh_subagent_subagents_prompt_parameter_0$schema,
|
|
146
154
|
},
|
|
147
155
|
},
|
|
148
156
|
],
|
|
@@ -150,9 +158,9 @@ export const TYPERT_REMOTE = {
|
|
|
150
158
|
result: {
|
|
151
159
|
mode: 'strict',
|
|
152
160
|
typeSymbol: '@deepseek-ai/dsh-subagent/client#SubagentPromptReceipt',
|
|
153
|
-
|
|
161
|
+
create: _deepseek_ai_dsh_subagent_subagents_prompt_result$schema,
|
|
154
162
|
},
|
|
155
|
-
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":
|
|
163
|
+
sourceLocation: {"file":"packages/subagent/subagent/src/index.ts","line":448,"column":9},
|
|
156
164
|
},
|
|
157
165
|
],
|
|
158
166
|
}
|
|
@@ -18,12 +18,22 @@ import type { SubagentDescriptorData } from './descriptor.ts';
|
|
|
18
18
|
import { SubagentInbox } from './inbox.ts';
|
|
19
19
|
import type { SubagentDelivery } from './inbox.ts';
|
|
20
20
|
import type { ActivationObserver } from './lifecycle.ts';
|
|
21
|
+
/** Process-local slots shared through uninterrupted continuable parent links. */
|
|
22
|
+
declare class ActivationPool {
|
|
23
|
+
private readonly slots;
|
|
24
|
+
/** Reserve before reconstruction; the returned release also tolerates unpublished rollback. */
|
|
25
|
+
reserve(capacity: number): () => void;
|
|
26
|
+
}
|
|
21
27
|
/**
|
|
22
28
|
* One residency epoch for a reconstructed continuable child Agent. It directly
|
|
23
29
|
* owns the published `AgentHandle`; the registry's private activation-owner
|
|
24
30
|
* scope is its structural Cordis owner.
|
|
25
31
|
*/
|
|
26
32
|
export interface Activation {
|
|
33
|
+
/** Shared capacity for this Activation and all its continuable descendants. */
|
|
34
|
+
readonly pool: ActivationPool;
|
|
35
|
+
/** Return this epoch's slot after its handle has finished disposal. */
|
|
36
|
+
readonly releaseSlot: () => void;
|
|
27
37
|
/** The durable child this Activation is an epoch of. */
|
|
28
38
|
readonly childId: SessionId;
|
|
29
39
|
/**
|
|
@@ -104,8 +114,11 @@ export declare class ChildLock {
|
|
|
104
114
|
export declare class ContinuableActivationRegistry {
|
|
105
115
|
private readonly ctx;
|
|
106
116
|
private readonly observeActivation;
|
|
117
|
+
private readonly maxActiveSubagents;
|
|
107
118
|
/** Child session id → its live Activation. Process-local, never durable. */
|
|
108
119
|
private readonly resident;
|
|
120
|
+
/** Root identities retain their pool across child settlement without retaining dead roots. */
|
|
121
|
+
private readonly rootPools;
|
|
109
122
|
/** Materializations admitted before drain, tracked through publication or rollback. */
|
|
110
123
|
private readonly materializations;
|
|
111
124
|
/** Per-child serializer shared by delivery, release, and disposal. */
|
|
@@ -125,7 +138,7 @@ export declare class ContinuableActivationRegistry {
|
|
|
125
138
|
* @param ctx - context providing Agents, Sessions, and teardown ownership.
|
|
126
139
|
* @param observeActivation - build the lifecycle observer for one residency epoch.
|
|
127
140
|
*/
|
|
128
|
-
constructor(ctx: Context, observeActivation: (provider: string, childId: SessionId, parent: Agent) => ActivationObserver);
|
|
141
|
+
constructor(ctx: Context, observeActivation: (provider: string, childId: SessionId, parent: Agent) => ActivationObserver, maxActiveSubagents: () => number);
|
|
129
142
|
/**
|
|
130
143
|
* Return the live Activation for a durable child id, if resident.
|
|
131
144
|
* @param childId - durable child session id to look up.
|
|
@@ -227,6 +240,8 @@ export declare class ContinuableActivationRegistry {
|
|
|
227
240
|
private liveLineage;
|
|
228
241
|
/** Return the teardown that closed continuable admission for this agent's lineage. */
|
|
229
242
|
private closingTeardownFor;
|
|
243
|
+
/** Resolve a root's pool once; descendants inherit their resident parent's pool directly. */
|
|
244
|
+
private rootPool;
|
|
230
245
|
/** Perform one tracked materialization through publication or rollback. */
|
|
231
246
|
private materializeTracked;
|
|
232
247
|
/** Release an Activation whose start edge was not published. */
|
|
@@ -248,4 +263,5 @@ export declare class ContinuableActivationRegistry {
|
|
|
248
263
|
/** Request a best-effort final session flush before closing natural-settlement admission. */
|
|
249
264
|
private flushFinalState;
|
|
250
265
|
}
|
|
266
|
+
export {};
|
|
251
267
|
//# sourceMappingURL=continuation-activation.d.ts.map
|
|
@@ -13,6 +13,20 @@ import { appendDelegatedPolicyOverrides, applyChildComposition, } from "./child-
|
|
|
13
13
|
import { createSettlementMessage } from "./continuation-messages.js";
|
|
14
14
|
import { SubagentError } from "./error.js";
|
|
15
15
|
import { SubagentInbox } from "./inbox.js";
|
|
16
|
+
/** Process-local slots shared through uninterrupted continuable parent links. */
|
|
17
|
+
class ActivationPool {
|
|
18
|
+
slots = new Set();
|
|
19
|
+
/** Reserve before reconstruction; the returned release also tolerates unpublished rollback. */
|
|
20
|
+
reserve(capacity) {
|
|
21
|
+
if (this.slots.size >= capacity) {
|
|
22
|
+
throw new SubagentError(`subagent limit reached (active child limit: ${capacity}); wait for an existing child to finish `
|
|
23
|
+
+ 'or complete this work with the current agents', 'ACTIVATION_LIMIT_REACHED');
|
|
24
|
+
}
|
|
25
|
+
const slot = Symbol();
|
|
26
|
+
this.slots.add(slot);
|
|
27
|
+
return () => { this.slots.delete(slot); };
|
|
28
|
+
}
|
|
29
|
+
}
|
|
16
30
|
/** Serialize each durable child's delivery, release, and disposal. */
|
|
17
31
|
export class ChildLock {
|
|
18
32
|
tails = new Map();
|
|
@@ -40,8 +54,11 @@ export class ChildLock {
|
|
|
40
54
|
export class ContinuableActivationRegistry {
|
|
41
55
|
ctx;
|
|
42
56
|
observeActivation;
|
|
57
|
+
maxActiveSubagents;
|
|
43
58
|
/** Child session id → its live Activation. Process-local, never durable. */
|
|
44
59
|
resident = new Map();
|
|
60
|
+
/** Root identities retain their pool across child settlement without retaining dead roots. */
|
|
61
|
+
rootPools = new WeakMap();
|
|
45
62
|
/** Materializations admitted before drain, tracked through publication or rollback. */
|
|
46
63
|
materializations = new Set();
|
|
47
64
|
/** Per-child serializer shared by delivery, release, and disposal. */
|
|
@@ -61,9 +78,10 @@ export class ContinuableActivationRegistry {
|
|
|
61
78
|
* @param ctx - context providing Agents, Sessions, and teardown ownership.
|
|
62
79
|
* @param observeActivation - build the lifecycle observer for one residency epoch.
|
|
63
80
|
*/
|
|
64
|
-
constructor(ctx, observeActivation) {
|
|
81
|
+
constructor(ctx, observeActivation, maxActiveSubagents) {
|
|
65
82
|
this.ctx = ctx;
|
|
66
83
|
this.observeActivation = observeActivation;
|
|
84
|
+
this.maxActiveSubagents = maxActiveSubagents;
|
|
67
85
|
// Ordinary Cordis owner effects unwind in reverse registration order, which
|
|
68
86
|
// cannot express the dynamic child graph. Register the private scope's
|
|
69
87
|
// structural disposer FIRST and the drain SECOND, so reverse unwind invokes
|
|
@@ -305,14 +323,20 @@ export class ContinuableActivationRegistry {
|
|
|
305
323
|
*/
|
|
306
324
|
materialize(inputs) {
|
|
307
325
|
this.assertAdmitting(inputs.parent);
|
|
308
|
-
|
|
326
|
+
inputs.signal.throwIfAborted();
|
|
309
327
|
const lineage = this.liveLineage(inputs.parent);
|
|
328
|
+
const pool = this.resident.get(inputs.parent.id)?.pool ?? this.rootPool(inputs.parent);
|
|
329
|
+
const releaseSlot = pool.reserve(this.maxActiveSubagents());
|
|
330
|
+
const settled = Promise.withResolvers();
|
|
310
331
|
const materialization = {
|
|
311
332
|
lineage,
|
|
312
333
|
settled: settled.promise,
|
|
313
334
|
};
|
|
314
335
|
this.materializations.add(materialization);
|
|
315
|
-
return this.materializeTracked(inputs, lineage).
|
|
336
|
+
return this.materializeTracked(inputs, lineage, pool, releaseSlot).catch((error) => {
|
|
337
|
+
releaseSlot();
|
|
338
|
+
throw error;
|
|
339
|
+
}).finally(() => {
|
|
316
340
|
this.materializations.delete(materialization);
|
|
317
341
|
settled.resolve();
|
|
318
342
|
});
|
|
@@ -400,8 +424,17 @@ export class ContinuableActivationRegistry {
|
|
|
400
424
|
}
|
|
401
425
|
return undefined;
|
|
402
426
|
}
|
|
427
|
+
/** Resolve a root's pool once; descendants inherit their resident parent's pool directly. */
|
|
428
|
+
rootPool(parent) {
|
|
429
|
+
let pool = this.rootPools.get(parent);
|
|
430
|
+
if (pool === undefined) {
|
|
431
|
+
pool = new ActivationPool();
|
|
432
|
+
this.rootPools.set(parent, pool);
|
|
433
|
+
}
|
|
434
|
+
return pool;
|
|
435
|
+
}
|
|
403
436
|
/** Perform one tracked materialization through publication or rollback. */
|
|
404
|
-
async materializeTracked(inputs, parentLineage) {
|
|
437
|
+
async materializeTracked(inputs, parentLineage, pool, releaseSlot) {
|
|
405
438
|
const { childId, provider, parent, create } = inputs;
|
|
406
439
|
inputs.signal.throwIfAborted();
|
|
407
440
|
const setup = (childCtx, child) => {
|
|
@@ -433,6 +466,8 @@ export class ContinuableActivationRegistry {
|
|
|
433
466
|
setup,
|
|
434
467
|
});
|
|
435
468
|
const activation = {
|
|
469
|
+
pool,
|
|
470
|
+
releaseSlot,
|
|
436
471
|
childId,
|
|
437
472
|
parentSession: parent.id,
|
|
438
473
|
provider,
|
|
@@ -471,6 +506,7 @@ export class ContinuableActivationRegistry {
|
|
|
471
506
|
}
|
|
472
507
|
finally {
|
|
473
508
|
this.resident.delete(activation.childId);
|
|
509
|
+
activation.releaseSlot();
|
|
474
510
|
this.releaseOwnership(activation.childId);
|
|
475
511
|
}
|
|
476
512
|
});
|
|
@@ -622,6 +658,7 @@ export class ContinuableActivationRegistry {
|
|
|
622
658
|
+ failures.map(item => errorChain(item)).join('; '), 'ACTIVATION_TEARDOWN_FAILED', { cause: new AggregateError(failures) });
|
|
623
659
|
}
|
|
624
660
|
this.resident.delete(childId);
|
|
661
|
+
activation.releaseSlot();
|
|
625
662
|
this.notifySettlement(activation, activation.observer.terminal(failure));
|
|
626
663
|
this.releaseOwnership(childId);
|
|
627
664
|
activation.observer.settle(failure);
|
|
@@ -35,7 +35,7 @@ export declare class SubagentContinuationManager {
|
|
|
35
35
|
private readonly ctx;
|
|
36
36
|
private readonly host;
|
|
37
37
|
private readonly activations;
|
|
38
|
-
constructor(ctx: Context, host: ContinuationHost);
|
|
38
|
+
constructor(ctx: Context, host: ContinuationHost, maxActiveSubagents: () => number);
|
|
39
39
|
/**
|
|
40
40
|
* Start one continuable background child and resolve at initial inbox acceptance.
|
|
41
41
|
* Every earlier failure disposes any created handle and rolls back Activation
|
|
@@ -86,10 +86,10 @@ export class SubagentContinuationManager {
|
|
|
86
86
|
ctx;
|
|
87
87
|
host;
|
|
88
88
|
activations;
|
|
89
|
-
constructor(ctx, host) {
|
|
89
|
+
constructor(ctx, host, maxActiveSubagents) {
|
|
90
90
|
this.ctx = ctx;
|
|
91
91
|
this.host = host;
|
|
92
|
-
this.activations = new ContinuableActivationRegistry(ctx, (provider, childId, parent) => host.observeActivation(provider, childId, parent));
|
|
92
|
+
this.activations = new ContinuableActivationRegistry(ctx, (provider, childId, parent) => host.observeActivation(provider, childId, parent), maxActiveSubagents);
|
|
93
93
|
}
|
|
94
94
|
/**
|
|
95
95
|
* Start one continuable background child and resolve at initial inbox acceptance.
|
package/lib/types/control.js
CHANGED
|
@@ -100,6 +100,7 @@ export function rejectPrompt(error, childSessionId, signal) {
|
|
|
100
100
|
throw new RemoteError('subagent/unauthorized', 'subagent does not belong to this parent', { childSessionId }, { cause: error });
|
|
101
101
|
case 'DRAINING':
|
|
102
102
|
case 'ACTIVATION_CLOSING':
|
|
103
|
+
case 'ACTIVATION_LIMIT_REACHED':
|
|
103
104
|
case 'CONTINUATION_UNAVAILABLE':
|
|
104
105
|
case 'PERSISTENCE_UNAVAILABLE':
|
|
105
106
|
throw new RemoteError('subagent/delivery-unavailable', 'subagent follow-up is temporarily unavailable', { childSessionId }, { cause: error });
|
package/lib/types/index.d.ts
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
* @module @deepseek-ai/dsh-subagent
|
|
30
30
|
*/
|
|
31
31
|
import { Context } from '@deepseek-ai/cordis';
|
|
32
|
+
import z from '@deepseek-ai/schemastery';
|
|
32
33
|
import type { Scoped } from '@deepseek-ai/dsh-scope';
|
|
33
34
|
import type { ContentBlock, MessageId } from '@deepseek-ai/dsh-llm';
|
|
34
35
|
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
@@ -94,8 +95,17 @@ declare module '@deepseek-ai/cordis' {
|
|
|
94
95
|
'subagent/end'(this: Scoped<SubagentRuntime>, info: SubagentRunEndInfo): void;
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
/** Host configuration for continuable subagent capacity. */
|
|
99
|
+
export interface Config {
|
|
100
|
+
/** Maximum live children sharing uninterrupted continuable parent links; defaults to 8. */
|
|
101
|
+
maxActiveSubagents?: number;
|
|
102
|
+
/** Default delegation depth for tools without an explicit limit; defaults to 1. */
|
|
103
|
+
maxDepth?: number;
|
|
104
|
+
}
|
|
97
105
|
/** Named provider registry with one-shot runs, durable discovery, and continuable-child operations. */
|
|
98
106
|
export declare class SubagentRuntime extends TypertRemoteService {
|
|
107
|
+
static Config: z<Config>;
|
|
108
|
+
private settingsSource;
|
|
99
109
|
private providers;
|
|
100
110
|
private continuations;
|
|
101
111
|
/**
|
|
@@ -104,7 +114,13 @@ export declare class SubagentRuntime extends TypertRemoteService {
|
|
|
104
114
|
* composes into the carrier.
|
|
105
115
|
*/
|
|
106
116
|
private readonly emitLifecycle;
|
|
107
|
-
constructor(ctx: Context);
|
|
117
|
+
constructor(ctx: Context, config: Config);
|
|
118
|
+
/**
|
|
119
|
+
* Resolve a delegation tool's depth policy against the current user setting.
|
|
120
|
+
* @param configured - Explicit tool limit, or provider-managed for external delegation.
|
|
121
|
+
* @returns The numeric limit, or undefined when the provider owns depth enforcement.
|
|
122
|
+
*/
|
|
123
|
+
resolveMaxDepth(configured?: number | 'provider-managed'): number | undefined;
|
|
108
124
|
/**
|
|
109
125
|
* Establish one durable continuable child and deliver its initial prompt.
|
|
110
126
|
* Resolves when the child's inbox accepts that prompt, without waiting for the
|
|
@@ -238,6 +254,7 @@ export declare class SubagentRuntime extends TypertRemoteService {
|
|
|
238
254
|
* nearest step and retains the Agent loop's best-effort fallback semantics.
|
|
239
255
|
* Image parts are admitted and persisted through the attachment store
|
|
240
256
|
* before delivery, and the child's model must accept image input.
|
|
257
|
+
* Cold resume at capacity rejects with `subagent/delivery-unavailable`.
|
|
241
258
|
* @param request - durable address, delivery, minted identity, content, and optional browser zone.
|
|
242
259
|
* @param signal - carrier cancellation, owning the call until inbox acceptance.
|
|
243
260
|
* @returns the accepted message's inbox identity.
|
package/lib/types/index.js
CHANGED
|
@@ -62,6 +62,7 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
62
62
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
63
63
|
done = true;
|
|
64
64
|
};
|
|
65
|
+
import z from '@deepseek-ai/schemastery';
|
|
65
66
|
import { scopeTarget } from '@deepseek-ai/dsh-scope';
|
|
66
67
|
import { assertObjectJsonSchema } from '@deepseek-ai/dsh-tools';
|
|
67
68
|
import { canonicalClientTimeZone } from '@deepseek-ai/dsh-util-time';
|
|
@@ -102,7 +103,12 @@ let SubagentRuntime = (() => {
|
|
|
102
103
|
__esDecorate(this, null, _interruptByParent_decorators, { kind: "method", name: "interruptByParent", static: false, private: false, access: { has: obj => "interruptByParent" in obj, get: obj => obj.interruptByParent }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
103
104
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
104
105
|
}
|
|
105
|
-
|
|
106
|
+
static Config = z.object({
|
|
107
|
+
maxDepth: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER).default(1),
|
|
108
|
+
maxActiveSubagents: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER).default(8),
|
|
109
|
+
});
|
|
110
|
+
settingsSource = __runInitializers(this, _instanceExtraInitializers);
|
|
111
|
+
providers = new Map();
|
|
106
112
|
continuations;
|
|
107
113
|
/**
|
|
108
114
|
* The contained lifecycle-edge publisher. Built here because scoped dispatch
|
|
@@ -110,14 +116,23 @@ let SubagentRuntime = (() => {
|
|
|
110
116
|
* composes into the carrier.
|
|
111
117
|
*/
|
|
112
118
|
emitLifecycle;
|
|
113
|
-
constructor(ctx) {
|
|
119
|
+
constructor(ctx, config) {
|
|
114
120
|
super(ctx, 'subagents');
|
|
121
|
+
assertSubagentMaxDepth(config.maxDepth);
|
|
122
|
+
this.settingsSource = () => config;
|
|
123
|
+
ctx.inject(['settings'], (settingsCtx) => {
|
|
124
|
+
settingsCtx.settings.installSection(ctx, 'subagent', SubagentRuntime.Config, config, {
|
|
125
|
+
validate: (value) => { assertSubagentMaxDepth(value.maxDepth); },
|
|
126
|
+
setSource: (source) => { this.settingsSource = source; },
|
|
127
|
+
onChange: () => { },
|
|
128
|
+
});
|
|
129
|
+
});
|
|
115
130
|
this.emitLifecycle = createLifecycleEmitter(this.ctx, parent => scopeTarget(this, parent));
|
|
116
131
|
ctx.inject(['agents'], (childCtx) => {
|
|
117
132
|
const manager = new SubagentContinuationManager(childCtx, {
|
|
118
133
|
prepareContinuable: (name, request) => this.prepareContinuable(name, request),
|
|
119
134
|
observeActivation: (provider, childId, parent) => this.observeActivation(provider, childId, parent),
|
|
120
|
-
});
|
|
135
|
+
}, () => this.settingsSource().maxActiveSubagents);
|
|
121
136
|
this.continuations = manager;
|
|
122
137
|
childCtx.effect(() => () => {
|
|
123
138
|
/* v8 ignore else -- one injected binding owns the slot until its fiber disposes. */
|
|
@@ -131,6 +146,16 @@ let SubagentRuntime = (() => {
|
|
|
131
146
|
projectionCtx.sessionProjections.register(subagentIdentityProjectionDefinition);
|
|
132
147
|
});
|
|
133
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* Resolve a delegation tool's depth policy against the current user setting.
|
|
151
|
+
* @param configured - Explicit tool limit, or provider-managed for external delegation.
|
|
152
|
+
* @returns The numeric limit, or undefined when the provider owns depth enforcement.
|
|
153
|
+
*/
|
|
154
|
+
resolveMaxDepth(configured) {
|
|
155
|
+
if (configured === 'provider-managed')
|
|
156
|
+
return undefined;
|
|
157
|
+
return configured ?? this.settingsSource().maxDepth;
|
|
158
|
+
}
|
|
134
159
|
/**
|
|
135
160
|
* Establish one durable continuable child and deliver its initial prompt.
|
|
136
161
|
* Resolves when the child's inbox accepts that prompt, without waiting for the
|
|
@@ -297,6 +322,7 @@ let SubagentRuntime = (() => {
|
|
|
297
322
|
* nearest step and retains the Agent loop's best-effort fallback semantics.
|
|
298
323
|
* Image parts are admitted and persisted through the attachment store
|
|
299
324
|
* before delivery, and the child's model must accept image input.
|
|
325
|
+
* Cold resume at capacity rejects with `subagent/delivery-unavailable`.
|
|
300
326
|
* @param request - durable address, delivery, minted identity, content, and optional browser zone.
|
|
301
327
|
* @param signal - carrier cancellation, owning the call until inbox acceptance.
|
|
302
328
|
* @returns the accepted message's inbox identity.
|
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.6-alpha.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -54,32 +54,34 @@
|
|
|
54
54
|
"license": "MIT",
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"zod": "^4.4.3",
|
|
57
|
-
"@deepseek-ai/dsh-brand": "^0.1.6-alpha.
|
|
58
|
-
"@deepseek-ai/dsh-chunked-list": "^0.1.6-alpha.
|
|
59
|
-
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.
|
|
57
|
+
"@deepseek-ai/dsh-brand": "^0.1.6-alpha.2",
|
|
58
|
+
"@deepseek-ai/dsh-chunked-list": "^0.1.6-alpha.2",
|
|
59
|
+
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2",
|
|
60
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
60
61
|
},
|
|
61
62
|
"peerDependencies": {
|
|
62
63
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/dsh-
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-
|
|
71
|
-
"@deepseek-ai/dsh-session
|
|
72
|
-
"@deepseek-ai/dsh-session-
|
|
73
|
-
"@deepseek-ai/dsh-session-
|
|
74
|
-
"@deepseek-ai/dsh-
|
|
75
|
-
"@deepseek-ai/dsh-
|
|
76
|
-
"@deepseek-ai/dsh-
|
|
77
|
-
"@deepseek-ai/dsh-
|
|
78
|
-
"@deepseek-ai/dsh-
|
|
79
|
-
"@deepseek-ai/dsh-
|
|
80
|
-
"@deepseek-ai/dsh-
|
|
81
|
-
"@deepseek-ai/dsh-
|
|
82
|
-
"@deepseek-ai/dsh-
|
|
64
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-attachment": "^0.1.6-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-invariants": "^0.1.6-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-jobs": "^0.1.6-alpha.2",
|
|
69
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
70
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2",
|
|
71
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
|
|
72
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
73
|
+
"@deepseek-ai/dsh-session-persistence": "^0.1.6-alpha.2",
|
|
74
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
|
|
75
|
+
"@deepseek-ai/dsh-scope": "^0.1.6-alpha.2",
|
|
76
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.6-alpha.2",
|
|
77
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
78
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
79
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
|
|
80
|
+
"@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
|
|
81
|
+
"@deepseek-ai/dsh-util-time": "^0.1.6-alpha.2",
|
|
82
|
+
"@deepseek-ai/dsh-permission-presets": "^0.1.6-alpha.2",
|
|
83
|
+
"@deepseek-ai/dsh-settings": "^0.1.6-alpha.2",
|
|
84
|
+
"@deepseek-ai/dsh-session-query": "^0.1.6-alpha.2"
|
|
83
85
|
},
|
|
84
86
|
"peerDependenciesMeta": {
|
|
85
87
|
"@deepseek-ai/dsh-agent-presets": {
|
|
@@ -111,33 +113,37 @@
|
|
|
111
113
|
},
|
|
112
114
|
"@deepseek-ai/dsh-user-approval": {
|
|
113
115
|
"optional": true
|
|
116
|
+
},
|
|
117
|
+
"@deepseek-ai/dsh-settings": {
|
|
118
|
+
"optional": true
|
|
114
119
|
}
|
|
115
120
|
},
|
|
116
121
|
"devDependencies": {
|
|
117
122
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
118
|
-
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.
|
|
119
|
-
"@deepseek-ai/dsh-
|
|
120
|
-
"@deepseek-ai/dsh-
|
|
121
|
-
"@deepseek-ai/dsh-
|
|
122
|
-
"@deepseek-ai/dsh-
|
|
123
|
-
"@deepseek-ai/dsh-
|
|
124
|
-
"@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.
|
|
125
|
-
"@deepseek-ai/dsh-
|
|
126
|
-
"@deepseek-ai/dsh-
|
|
127
|
-
"@deepseek-ai/dsh-
|
|
128
|
-
"@deepseek-ai/dsh-session": "^0.1.6-alpha.
|
|
129
|
-
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.
|
|
130
|
-
"@deepseek-ai/dsh-session-
|
|
131
|
-
"@deepseek-ai/dsh-
|
|
132
|
-
"@deepseek-ai/dsh-storage": "^0.1.6-alpha.
|
|
133
|
-
"@deepseek-ai/dsh-storage-
|
|
134
|
-
"@deepseek-ai/dsh-
|
|
135
|
-
"@deepseek-ai/dsh-
|
|
136
|
-
"@deepseek-ai/dsh-
|
|
137
|
-
"@deepseek-ai/dsh-
|
|
138
|
-
"@deepseek-ai/dsh-
|
|
139
|
-
"@deepseek-ai/dsh-
|
|
140
|
-
"@deepseek-ai/dsh-
|
|
141
|
-
"@deepseek-ai/dsh-
|
|
123
|
+
"@deepseek-ai/dsh-agent": "^0.1.6-alpha.2",
|
|
124
|
+
"@deepseek-ai/dsh-attachment": "^0.1.6-alpha.2",
|
|
125
|
+
"@deepseek-ai/dsh-invariants": "^0.1.6-alpha.2",
|
|
126
|
+
"@deepseek-ai/dsh-jobs": "^0.1.6-alpha.2",
|
|
127
|
+
"@deepseek-ai/dsh-llm": "^0.1.6-alpha.2",
|
|
128
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.6-alpha.2",
|
|
129
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.6-alpha.2",
|
|
130
|
+
"@deepseek-ai/dsh-agent-presets": "^0.1.6-alpha.2",
|
|
131
|
+
"@deepseek-ai/dsh-scope": "^0.1.6-alpha.2",
|
|
132
|
+
"@deepseek-ai/dsh-session-persistence": "^0.1.6-alpha.2",
|
|
133
|
+
"@deepseek-ai/dsh-session-projection": "^0.1.6-alpha.2",
|
|
134
|
+
"@deepseek-ai/dsh-session-projection-cache": "^0.1.6-alpha.2",
|
|
135
|
+
"@deepseek-ai/dsh-session-query": "^0.1.6-alpha.2",
|
|
136
|
+
"@deepseek-ai/dsh-storage": "^0.1.6-alpha.2",
|
|
137
|
+
"@deepseek-ai/dsh-storage-domain": "^0.1.6-alpha.2",
|
|
138
|
+
"@deepseek-ai/dsh-storage-json": "^0.1.6-alpha.2",
|
|
139
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.6-alpha.2",
|
|
140
|
+
"@deepseek-ai/dsh-tools": "^0.1.6-alpha.2",
|
|
141
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.6-alpha.2",
|
|
142
|
+
"@deepseek-ai/dsh-user-approval": "^0.1.6-alpha.2",
|
|
143
|
+
"@deepseek-ai/dsh-util-time": "^0.1.6-alpha.2",
|
|
144
|
+
"@deepseek-ai/dsh-permission-presets": "^0.1.6-alpha.2",
|
|
145
|
+
"@deepseek-ai/dsh-settings": "^0.1.6-alpha.2",
|
|
146
|
+
"@deepseek-ai/dsh-session": "^0.1.6-alpha.2",
|
|
147
|
+
"@deepseek-ai/dsh-schedule": "^0.1.6-alpha.2"
|
|
142
148
|
}
|
|
143
149
|
}
|