@fishwithcat/dsh-subagent 0.0.0-stage → 0.2.2-alpha.3
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 +121 -0
- package/README.md +258 -2
- package/README.zh.md +259 -0
- package/lib/index.js +3065 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +1086 -0
- package/lib/typert.remote-client.d.ts +29 -0
- package/lib/typert.remote-client.js +122 -0
- package/lib/types/activation.d.ts +110 -0
- package/lib/types/activation.js +112 -0
- package/lib/types/archive-admission.d.ts +23 -0
- package/lib/types/archive-admission.js +75 -0
- package/lib/types/assistant-output.d.ts +48 -0
- package/lib/types/assistant-output.js +73 -0
- package/lib/types/catalog.d.ts +87 -0
- package/lib/types/catalog.js +113 -0
- package/lib/types/child-agent.d.ts +145 -0
- package/lib/types/child-agent.js +229 -0
- package/lib/types/client.d.ts +8 -0
- package/lib/types/client.js +7 -0
- package/lib/types/continuation-messages.d.ts +66 -0
- package/lib/types/continuation-messages.js +116 -0
- package/lib/types/control-types.d.ts +121 -0
- package/lib/types/control-types.js +8 -0
- package/lib/types/control.d.ts +41 -0
- package/lib/types/control.js +75 -0
- package/lib/types/depth.d.ts +31 -0
- package/lib/types/depth.js +39 -0
- package/lib/types/descriptor.d.ts +105 -0
- package/lib/types/descriptor.js +192 -0
- package/lib/types/error.d.ts +11 -0
- package/lib/types/error.js +14 -0
- package/lib/types/index.d.ts +282 -0
- package/lib/types/index.js +398 -0
- package/lib/types/lifecycle.d.ts +54 -0
- package/lib/types/lifecycle.js +89 -0
- package/lib/types/list-children.d.ts +36 -0
- package/lib/types/list-children.js +166 -0
- package/lib/types/manager.d.ts +215 -0
- package/lib/types/manager.js +1171 -0
- package/lib/types/out-of-process.d.ts +92 -0
- package/lib/types/out-of-process.js +177 -0
- package/lib/types/projection-types.d.ts +93 -0
- package/lib/types/projection-types.js +7 -0
- package/lib/types/projection.d.ts +94 -0
- package/lib/types/projection.js +157 -0
- package/lib/types/structured.d.ts +49 -0
- package/lib/types/structured.js +130 -0
- package/lib/types/types.d.ts +331 -0
- package/lib/types/types.js +17 -0
- package/locale/de.json +6 -0
- package/locale/en.json +5 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/pt.json +6 -0
- package/locale/ru.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +131 -4
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parent-owned durable subagent catalog events and their chunked projection.
|
|
3
|
+
*
|
|
4
|
+
* @module @deepseek-ai/dsh-subagent/catalog
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { ChunkedList } from '@deepseek-ai/dsh-chunked-list';
|
|
8
|
+
import type { Session, SessionEvent, SessionHeader, SessionId, SessionLogOffset } from '@deepseek-ai/dsh-session';
|
|
9
|
+
import type { SubagentCatalogEntry } from './projection-types.ts';
|
|
10
|
+
/** Catalog payload version emitted by local child creation. */
|
|
11
|
+
export declare const SUBAGENT_CATALOG_VERSION = 0;
|
|
12
|
+
type KnownCatalogMode = {
|
|
13
|
+
readonly mode: 'one-shot';
|
|
14
|
+
readonly label?: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly mode: 'continuable';
|
|
17
|
+
readonly label: string;
|
|
18
|
+
};
|
|
19
|
+
/** Parent catalog v0 records local modes, v1 adds unknown children, and v2 records external executions. */
|
|
20
|
+
export type SubagentCatalogEvent = {
|
|
21
|
+
readonly childId: SessionId;
|
|
22
|
+
readonly childCreatedAt: number;
|
|
23
|
+
} & (({
|
|
24
|
+
readonly version: 0;
|
|
25
|
+
} & KnownCatalogMode) | ({
|
|
26
|
+
readonly version: 1;
|
|
27
|
+
} & (KnownCatalogMode | {
|
|
28
|
+
readonly mode: 'unknown';
|
|
29
|
+
readonly label?: string;
|
|
30
|
+
})) | {
|
|
31
|
+
readonly version: 2;
|
|
32
|
+
readonly mode: 'external';
|
|
33
|
+
readonly label?: string;
|
|
34
|
+
});
|
|
35
|
+
declare module '@deepseek-ai/dsh-session/types' {
|
|
36
|
+
interface SessionEventMap {
|
|
37
|
+
/**
|
|
38
|
+
* A direct child's identity and available discovery fields.
|
|
39
|
+
* @param data - versioned parent-owned catalog entry.
|
|
40
|
+
*/
|
|
41
|
+
'subagent/catalog': SubagentCatalogEvent;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Host fold state for one parent catalog. */
|
|
45
|
+
export interface SubagentCatalogState {
|
|
46
|
+
readonly inheritedEventCount: SessionLogOffset;
|
|
47
|
+
readonly head?: ChunkedList<SubagentCatalogEvent> | undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Materialize complete and unknown-mode child identities from parent catalog events.
|
|
51
|
+
* @param state - parent catalog fold state.
|
|
52
|
+
* @returns current direct-child rows in parent catalog event order.
|
|
53
|
+
*/
|
|
54
|
+
declare function subagentCatalogEntries(state: SubagentCatalogState): SubagentCatalogEntry[];
|
|
55
|
+
/** Parent-owned direct-child catalog projection; invalid own facts reject restoration. */
|
|
56
|
+
export declare const subagentCatalogProjectionDefinition: {
|
|
57
|
+
key: "subagentCatalog";
|
|
58
|
+
stateSchema: z.ZodType<SubagentCatalogState, unknown, z.core.$ZodTypeInternals<SubagentCatalogState, unknown>>;
|
|
59
|
+
init: (_header: SessionHeader, inheritedEventCount: SessionLogOffset) => {
|
|
60
|
+
inheritedEventCount: SessionLogOffset;
|
|
61
|
+
};
|
|
62
|
+
apply: (state: NoInfer<SubagentCatalogState>, event: SessionEvent) => SubagentCatalogState;
|
|
63
|
+
stateVersion: number;
|
|
64
|
+
wire: {
|
|
65
|
+
viewSchema: z.ZodType<SubagentCatalogEntry[], unknown, z.core.$ZodTypeInternals<SubagentCatalogEntry[], unknown>>;
|
|
66
|
+
view: typeof subagentCatalogEntries;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Append a complete direct-child discovery fact to its parent Session.
|
|
71
|
+
* @param parent - durable direct parent receiving the discovery fact.
|
|
72
|
+
* @param child - established child's immutable Session metadata.
|
|
73
|
+
* @param descriptor - mode-discriminated creation label frozen with the child.
|
|
74
|
+
*/
|
|
75
|
+
export declare function establishCatalogChild(parent: Session, child: SessionHeader, descriptor: {
|
|
76
|
+
readonly mode: 'continuable';
|
|
77
|
+
readonly label: string;
|
|
78
|
+
}): void;
|
|
79
|
+
/**
|
|
80
|
+
* Record an external execution without a local child Session.
|
|
81
|
+
* @param parent - durable direct parent receiving the discovery fact.
|
|
82
|
+
* @param childId - identity returned by the external provider.
|
|
83
|
+
* @param label - display label assigned by the caller.
|
|
84
|
+
*/
|
|
85
|
+
export declare function establishExternalCatalogChild(parent: Session, childId: SessionId, label: string): void;
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=catalog.d.ts.map
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parent-owned durable subagent catalog events and their chunked projection.
|
|
3
|
+
*
|
|
4
|
+
* @module @deepseek-ai/dsh-subagent/catalog
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import { appendChunkedList, chunkedListSchema, iterateChunkedList } from '@deepseek-ai/dsh-chunked-list';
|
|
8
|
+
/** Catalog payload version emitted by local child creation. */
|
|
9
|
+
export const SUBAGENT_CATALOG_VERSION = 0;
|
|
10
|
+
const sessionIdSchema = z.string();
|
|
11
|
+
const oneShotCatalogSchema = z.object({
|
|
12
|
+
version: z.union([z.literal(0), z.literal(1)]),
|
|
13
|
+
childId: sessionIdSchema,
|
|
14
|
+
childCreatedAt: z.number().int().nonnegative(),
|
|
15
|
+
mode: z.literal('one-shot'),
|
|
16
|
+
label: z.string().optional(),
|
|
17
|
+
}).strict();
|
|
18
|
+
const continuableCatalogSchema = z.object({
|
|
19
|
+
version: z.union([z.literal(0), z.literal(1)]),
|
|
20
|
+
childId: sessionIdSchema,
|
|
21
|
+
childCreatedAt: z.number().int().nonnegative(),
|
|
22
|
+
mode: z.literal('continuable'),
|
|
23
|
+
label: z.string(),
|
|
24
|
+
}).strict();
|
|
25
|
+
const externalCatalogSchema = oneShotCatalogSchema.extend({ version: z.literal(2), mode: z.literal('external') });
|
|
26
|
+
const unknownCatalogSchema = oneShotCatalogSchema.extend({ version: z.literal(1), mode: z.literal('unknown') });
|
|
27
|
+
const eventDataSchema = z.union([
|
|
28
|
+
oneShotCatalogSchema,
|
|
29
|
+
externalCatalogSchema,
|
|
30
|
+
continuableCatalogSchema,
|
|
31
|
+
unknownCatalogSchema,
|
|
32
|
+
]);
|
|
33
|
+
const viewSchema = z.array(z.union([
|
|
34
|
+
oneShotCatalogSchema.omit({ version: true, childId: true, childCreatedAt: true }).extend({
|
|
35
|
+
id: sessionIdSchema,
|
|
36
|
+
createdAt: oneShotCatalogSchema.shape.childCreatedAt,
|
|
37
|
+
}),
|
|
38
|
+
externalCatalogSchema.omit({ version: true, childId: true, childCreatedAt: true }).extend({
|
|
39
|
+
id: sessionIdSchema,
|
|
40
|
+
createdAt: externalCatalogSchema.shape.childCreatedAt,
|
|
41
|
+
}),
|
|
42
|
+
continuableCatalogSchema.omit({ version: true, childId: true, childCreatedAt: true }).extend({
|
|
43
|
+
id: sessionIdSchema,
|
|
44
|
+
createdAt: continuableCatalogSchema.shape.childCreatedAt,
|
|
45
|
+
}),
|
|
46
|
+
unknownCatalogSchema.omit({ version: true, childId: true, childCreatedAt: true }).extend({
|
|
47
|
+
id: sessionIdSchema,
|
|
48
|
+
createdAt: unknownCatalogSchema.shape.childCreatedAt,
|
|
49
|
+
}),
|
|
50
|
+
]));
|
|
51
|
+
const stateSchema = z.object({
|
|
52
|
+
inheritedEventCount: z.number().int().nonnegative(),
|
|
53
|
+
head: chunkedListSchema(eventDataSchema).optional(),
|
|
54
|
+
}).strict();
|
|
55
|
+
/**
|
|
56
|
+
* Materialize complete and unknown-mode child identities from parent catalog events.
|
|
57
|
+
* @param state - parent catalog fold state.
|
|
58
|
+
* @returns current direct-child rows in parent catalog event order.
|
|
59
|
+
*/
|
|
60
|
+
function subagentCatalogEntries(state) {
|
|
61
|
+
const entries = [];
|
|
62
|
+
for (const data of iterateChunkedList(state.head)) {
|
|
63
|
+
const { version: _version, childId, childCreatedAt, ...descriptor } = data;
|
|
64
|
+
entries.push({ id: childId, createdAt: childCreatedAt, ...descriptor });
|
|
65
|
+
}
|
|
66
|
+
return entries;
|
|
67
|
+
}
|
|
68
|
+
/** Parent-owned direct-child catalog projection; invalid own facts reject restoration. */
|
|
69
|
+
export const subagentCatalogProjectionDefinition = {
|
|
70
|
+
key: 'subagentCatalog',
|
|
71
|
+
stateSchema,
|
|
72
|
+
init: (_header, inheritedEventCount) => ({ inheritedEventCount }),
|
|
73
|
+
apply: (state, event) => {
|
|
74
|
+
if (event.type !== 'subagent/catalog' || event.seq < state.inheritedEventCount)
|
|
75
|
+
return state;
|
|
76
|
+
return { ...state, head: appendChunkedList(state.head, eventDataSchema.parse(event.data)) };
|
|
77
|
+
},
|
|
78
|
+
stateVersion: 6,
|
|
79
|
+
wire: { viewSchema, view: subagentCatalogEntries },
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Append a complete direct-child discovery fact to its parent Session.
|
|
83
|
+
* @param parent - durable direct parent receiving the discovery fact.
|
|
84
|
+
* @param child - established child's immutable Session metadata.
|
|
85
|
+
* @param descriptor - mode-discriminated creation label frozen with the child.
|
|
86
|
+
*/
|
|
87
|
+
export function establishCatalogChild(parent, child, descriptor) {
|
|
88
|
+
parent.append('subagent/catalog', {
|
|
89
|
+
version: SUBAGENT_CATALOG_VERSION,
|
|
90
|
+
childId: child.id,
|
|
91
|
+
childCreatedAt: child.createdAt,
|
|
92
|
+
mode: descriptor.mode,
|
|
93
|
+
label: descriptor.label,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** Catalog payload version emitted by external execution creation. */
|
|
97
|
+
const EXTERNAL_SUBAGENT_CATALOG_VERSION = 2;
|
|
98
|
+
/**
|
|
99
|
+
* Record an external execution without a local child Session.
|
|
100
|
+
* @param parent - durable direct parent receiving the discovery fact.
|
|
101
|
+
* @param childId - identity returned by the external provider.
|
|
102
|
+
* @param label - display label assigned by the caller.
|
|
103
|
+
*/
|
|
104
|
+
export function establishExternalCatalogChild(parent, childId, label) {
|
|
105
|
+
parent.append('subagent/catalog', {
|
|
106
|
+
version: EXTERNAL_SUBAGENT_CATALOG_VERSION,
|
|
107
|
+
childId,
|
|
108
|
+
childCreatedAt: Date.now(),
|
|
109
|
+
mode: 'external',
|
|
110
|
+
label,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared in-process child composition: the delegation-depth budget, the
|
|
3
|
+
* durable session metadata, the resolved child `AgentOptions`, the delegated
|
|
4
|
+
* policy seed, and the scoped setup used by local activations.
|
|
5
|
+
*
|
|
6
|
+
* @module @deepseek-ai/dsh-subagent/child-agent
|
|
7
|
+
*/
|
|
8
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
9
|
+
import type { Agent, AgentOptions, CreateAgentOptions } from '@deepseek-ai/dsh-agent';
|
|
10
|
+
import type { SandboxMode } from '@deepseek-ai/dsh-sandbox';
|
|
11
|
+
import type { Session } from '@deepseek-ai/dsh-session';
|
|
12
|
+
import type { ToolRestriction } from '@deepseek-ai/dsh-tools';
|
|
13
|
+
import type { ApprovalPolicy } from '@deepseek-ai/dsh-user-approval';
|
|
14
|
+
/** Thrown when starting a child would exceed the requested depth cap. */
|
|
15
|
+
export declare class SubagentDepthError extends Error {
|
|
16
|
+
readonly attemptedDepth: number;
|
|
17
|
+
readonly maxDepth: number;
|
|
18
|
+
constructor(attemptedDepth: number, maxDepth: number);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Resolve the child's delegation depth from its parent and enforce an optional
|
|
22
|
+
* cap. The persisted parent header is the monotone floor, so a resumed parent
|
|
23
|
+
* cannot delegate as if it were top-level.
|
|
24
|
+
* @param parent - the delegating parent agent.
|
|
25
|
+
* @param maxDepth - optional absolute cap the resolved depth must not exceed.
|
|
26
|
+
* @returns the child's non-negative safe-integer depth.
|
|
27
|
+
* @throws {SubagentDepthError} when the resolved depth exceeds `maxDepth`.
|
|
28
|
+
* @throws {RangeError} when the resolved depth leaves the safe-integer range.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveChildDepth(parent: Agent, maxDepth: number | undefined): number;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve the parent values inherited by a child. The latest request header
|
|
33
|
+
* owns provider, model, and reasoning effort after request-time selection;
|
|
34
|
+
* creation options remain the fallback before the first request and retain
|
|
35
|
+
* the configured output-token limit.
|
|
36
|
+
* @param parent - delegating parent Agent.
|
|
37
|
+
* @returns detached Agent options for child-option merging.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parentAgentOptionsForDelegation(parent: Agent): AgentOptions;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the child's `AgentOptions`: the parent's provider/model,
|
|
42
|
+
* reasoning-effort, and maxTokens values unless the request overrides them,
|
|
43
|
+
* stamped with the child's own delegation depth. Changing the route without
|
|
44
|
+
* naming an effort clears the parent's route-owned effort so the selected
|
|
45
|
+
* model resolves its own default.
|
|
46
|
+
* @param parent - the delegating parent whose route the child inherits.
|
|
47
|
+
* @param requested - per-child overrides, if any.
|
|
48
|
+
* @param childDepth - the resolved delegation depth to stamp.
|
|
49
|
+
* @returns the resolved options for `ctx.agents.create()`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function resolveChildAgentOptions(parent: Agent, requested: AgentOptions | undefined, childDepth: number): AgentOptions;
|
|
52
|
+
/**
|
|
53
|
+
* Build the child session's durable creation metadata: the parent's workspace,
|
|
54
|
+
* its direct lineage, coarse product origin, the recursion budget that must
|
|
55
|
+
* survive persistence, the seed boundary that separates inherited parent
|
|
56
|
+
* history from child work, and the composition the child runs under.
|
|
57
|
+
*
|
|
58
|
+
* Omitted selection uses the parent's live composition, including any switch
|
|
59
|
+
* made while the parent was blank.
|
|
60
|
+
* @param parent - the delegating parent agent.
|
|
61
|
+
* @param childDepth - the resolved delegation depth to persist.
|
|
62
|
+
* @param isSeeded - whether this child inherits a parent-log prefix, including an explicitly empty one.
|
|
63
|
+
* @param selectedPreset - independent selection, or omission to inherit the parent.
|
|
64
|
+
* @returns the `meta` for `ctx.agents.create()`.
|
|
65
|
+
*/
|
|
66
|
+
export declare function childSessionMeta(parent: Agent, childDepth: number, isSeeded: boolean, selectedPreset?: string): NonNullable<CreateAgentOptions['meta']>;
|
|
67
|
+
/** The scoped composition a child agent's creation window applies. */
|
|
68
|
+
export interface ChildComposition {
|
|
69
|
+
/** Preset to mount; omission shares a supplied creator or uses host composition. */
|
|
70
|
+
readonly agentPreset?: string | undefined;
|
|
71
|
+
/** Historical descriptor persona reapplied only during cold resume. */
|
|
72
|
+
readonly persona?: string | undefined;
|
|
73
|
+
/** Historical descriptor tool restriction reapplied only during cold resume. */
|
|
74
|
+
readonly toolFilter?: ToolRestriction | undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Model-facing delegation-scope statement for an in-process child whose approval
|
|
78
|
+
* policy is `never`. A runtime-context contribution rather than a system-prompt
|
|
79
|
+
* section, so the deployment's system prompt stays uniform across parents and
|
|
80
|
+
* children.
|
|
81
|
+
*/
|
|
82
|
+
export declare const SUBAGENT_DELEGATION_CONTEXT: string;
|
|
83
|
+
/**
|
|
84
|
+
* Model-facing delegation-scope statement for an in-process child whose approval
|
|
85
|
+
* policy is `ask`: the scope stays fixed, but one operation may request a
|
|
86
|
+
* decision from the user who owns the answerers.
|
|
87
|
+
*/
|
|
88
|
+
export declare const SUBAGENT_DELEGATION_INTERACTIVE_CONTEXT: string;
|
|
89
|
+
/**
|
|
90
|
+
* Compose a child before publication and restore historical descriptor overrides.
|
|
91
|
+
* Explicit selection mounts the named preset. Omission joins a supplied creator's
|
|
92
|
+
* current generation; a restored child without a saved preset uses host composition.
|
|
93
|
+
* Registrations belong to the child's scope.
|
|
94
|
+
* @param childCtx - the child agent's scoped creation context.
|
|
95
|
+
* @param parent - creator for fresh delegation; absent during target-only restoration.
|
|
96
|
+
* @param composition - independent preset and any overrides read from a historical descriptor.
|
|
97
|
+
* @param approvalPolicy - the child's effective approval policy, selecting its delegation statement.
|
|
98
|
+
* @returns A promise when mounting an independent preset; otherwise completes synchronously.
|
|
99
|
+
*/
|
|
100
|
+
export declare function applyChildComposition(childCtx: Context, parent: Agent | undefined, composition: ChildComposition, approvalPolicy: ApprovalPolicy | undefined): void | Promise<void>;
|
|
101
|
+
/** How a delegated child's approval policy is seeded at creation. */
|
|
102
|
+
export type DelegatedApprovalPolicy = 'never' | 'inherit';
|
|
103
|
+
/** Policy seeded onto a child session's log at the delegation boundary. */
|
|
104
|
+
export interface DelegatedPolicyOverrides {
|
|
105
|
+
/**
|
|
106
|
+
* The parent's current preset identity when it runs in Auto or Full access;
|
|
107
|
+
* the child keeps it under the delegated approval policy.
|
|
108
|
+
*/
|
|
109
|
+
readonly permissionPreset: 'auto' | 'danger-full-access' | undefined;
|
|
110
|
+
/** The parent session's explicit sandbox-mode override, or `undefined` without one. */
|
|
111
|
+
readonly sandboxMode: SandboxMode | undefined;
|
|
112
|
+
/**
|
|
113
|
+
* The policy to append to the child's own log, or `undefined` without an
|
|
114
|
+
* approval capability. `'never'` keeps every ask deterministic; `'ask'`
|
|
115
|
+
* inherits an interactive parent's policy so a composed answerer may decide
|
|
116
|
+
* the child's requests.
|
|
117
|
+
*/
|
|
118
|
+
readonly approvalPolicy: ApprovalPolicy | undefined;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Capture the permission state to seed into one delegation. Call synchronously before
|
|
122
|
+
* the child start's first await: a later parent switch belongs to the
|
|
123
|
+
* parent's future, not to this child. Auto and Full access identities are
|
|
124
|
+
* inherited only through the in-process DSH path so either can replace a stale
|
|
125
|
+
* same-bundle fork value. Only the parent session's explicit sandbox override
|
|
126
|
+
* is captured — never deployment defaults or one-shot grants. Approval is
|
|
127
|
+
* pinned to `'never'` by default; `'inherit'` seeds the parent's current
|
|
128
|
+
* effective policy instead, which only a surface that also answers descendant
|
|
129
|
+
* Agents can turn into a prompt.
|
|
130
|
+
* @param parent - the delegating parent agent.
|
|
131
|
+
* @param delegatedApproval - `'never'` to pin rejection, `'inherit'` to seed the parent's effective policy.
|
|
132
|
+
* @returns the sandbox override (or `undefined` without one) and the approval policy seed.
|
|
133
|
+
*/
|
|
134
|
+
export declare function captureDelegatedPolicyOverrides(parent: Agent, delegatedApproval: DelegatedApprovalPolicy): DelegatedPolicyOverrides;
|
|
135
|
+
/**
|
|
136
|
+
* Append the captured delegation policy onto the child's own log as
|
|
137
|
+
* `source: 'delegation'` events after Session announcement and before Agent registration, so the
|
|
138
|
+
* child's effective policy is reconstructable from its log alone. Appends land
|
|
139
|
+
* after any fork seed, so fresh policy wins stale seed state; later child
|
|
140
|
+
* switches still win over these events.
|
|
141
|
+
* @param childSession - the child's announced, writable Session.
|
|
142
|
+
* @param overrides - the policy captured at delegation.
|
|
143
|
+
*/
|
|
144
|
+
export declare function appendDelegatedPolicyOverrides(childSession: Session, overrides: DelegatedPolicyOverrides): void;
|
|
145
|
+
//# sourceMappingURL=child-agent.d.ts.map
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared in-process child composition: the delegation-depth budget, the
|
|
3
|
+
* durable session metadata, the resolved child `AgentOptions`, the delegated
|
|
4
|
+
* policy seed, and the scoped setup used by local activations.
|
|
5
|
+
*
|
|
6
|
+
* @module @deepseek-ai/dsh-subagent/child-agent
|
|
7
|
+
*/
|
|
8
|
+
import { delegationDepthOf } from "./depth.js";
|
|
9
|
+
import { SubagentError } from "./error.js";
|
|
10
|
+
/** Thrown when starting a child would exceed the requested depth cap. */
|
|
11
|
+
export class SubagentDepthError extends Error {
|
|
12
|
+
attemptedDepth;
|
|
13
|
+
maxDepth;
|
|
14
|
+
constructor(attemptedDepth, maxDepth) {
|
|
15
|
+
super(`subagent depth ${attemptedDepth} exceeds maxDepth ${maxDepth}`);
|
|
16
|
+
this.attemptedDepth = attemptedDepth;
|
|
17
|
+
this.maxDepth = maxDepth;
|
|
18
|
+
this.name = 'SubagentDepthError';
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Resolve the child's delegation depth from its parent and enforce an optional
|
|
23
|
+
* cap. The persisted parent header is the monotone floor, so a resumed parent
|
|
24
|
+
* cannot delegate as if it were top-level.
|
|
25
|
+
* @param parent - the delegating parent agent.
|
|
26
|
+
* @param maxDepth - optional absolute cap the resolved depth must not exceed.
|
|
27
|
+
* @returns the child's non-negative safe-integer depth.
|
|
28
|
+
* @throws {SubagentDepthError} when the resolved depth exceeds `maxDepth`.
|
|
29
|
+
* @throws {RangeError} when the resolved depth leaves the safe-integer range.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveChildDepth(parent, maxDepth) {
|
|
32
|
+
const childDepth = delegationDepthOf(parent) + 1;
|
|
33
|
+
if (!Number.isSafeInteger(childDepth)) {
|
|
34
|
+
throw new RangeError('subagent child depth exceeds the safe-integer range');
|
|
35
|
+
}
|
|
36
|
+
if (maxDepth !== undefined && childDepth > maxDepth) {
|
|
37
|
+
throw new SubagentDepthError(childDepth, maxDepth);
|
|
38
|
+
}
|
|
39
|
+
return childDepth;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolve the parent values inherited by a child. The latest request header
|
|
43
|
+
* owns provider, model, and reasoning effort after request-time selection;
|
|
44
|
+
* creation options remain the fallback before the first request and retain
|
|
45
|
+
* the configured output-token limit.
|
|
46
|
+
* @param parent - delegating parent Agent.
|
|
47
|
+
* @returns detached Agent options for child-option merging.
|
|
48
|
+
*/
|
|
49
|
+
export function parentAgentOptionsForDelegation(parent) {
|
|
50
|
+
const requestConfig = parent.session.requestHeader()?.config;
|
|
51
|
+
if (requestConfig === undefined)
|
|
52
|
+
return { ...parent.options };
|
|
53
|
+
const { provider: _createdProvider, model: _createdModel, reasoningEffort: _createdReasoningEffort, ...createdOptions } = parent.options;
|
|
54
|
+
return {
|
|
55
|
+
...createdOptions,
|
|
56
|
+
provider: requestConfig.provider,
|
|
57
|
+
model: requestConfig.model,
|
|
58
|
+
...requestConfig.reasoningEffort === undefined
|
|
59
|
+
? {}
|
|
60
|
+
: { reasoningEffort: requestConfig.reasoningEffort },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the child's `AgentOptions`: the parent's provider/model,
|
|
65
|
+
* reasoning-effort, and maxTokens values unless the request overrides them,
|
|
66
|
+
* stamped with the child's own delegation depth. Changing the route without
|
|
67
|
+
* naming an effort clears the parent's route-owned effort so the selected
|
|
68
|
+
* model resolves its own default.
|
|
69
|
+
* @param parent - the delegating parent whose route the child inherits.
|
|
70
|
+
* @param requested - per-child overrides, if any.
|
|
71
|
+
* @param childDepth - the resolved delegation depth to stamp.
|
|
72
|
+
* @returns the resolved options for `ctx.agents.create()`.
|
|
73
|
+
*/
|
|
74
|
+
export function resolveChildAgentOptions(parent, requested, childDepth) {
|
|
75
|
+
const parentOptions = parentAgentOptionsForDelegation(parent);
|
|
76
|
+
const parentProvider = parentOptions.provider;
|
|
77
|
+
const parentModel = parentOptions.model;
|
|
78
|
+
const parentReasoningEffort = parentOptions.reasoningEffort;
|
|
79
|
+
const parentMaxTokens = parentOptions.maxTokens;
|
|
80
|
+
const resolved = {
|
|
81
|
+
...parentProvider !== undefined ? { provider: parentProvider } : {},
|
|
82
|
+
...parentModel !== undefined ? { model: parentModel } : {},
|
|
83
|
+
...parentReasoningEffort !== undefined ? { reasoningEffort: parentReasoningEffort } : {},
|
|
84
|
+
...parentMaxTokens !== undefined ? { maxTokens: parentMaxTokens } : {},
|
|
85
|
+
...requested,
|
|
86
|
+
subagentDepth: childDepth,
|
|
87
|
+
};
|
|
88
|
+
const routeChanged = resolved.provider !== parentProvider || resolved.model !== parentModel;
|
|
89
|
+
if (routeChanged && requested?.reasoningEffort === undefined)
|
|
90
|
+
delete resolved.reasoningEffort;
|
|
91
|
+
return resolved;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Build the child session's durable creation metadata: the parent's workspace,
|
|
95
|
+
* its direct lineage, coarse product origin, the recursion budget that must
|
|
96
|
+
* survive persistence, the seed boundary that separates inherited parent
|
|
97
|
+
* history from child work, and the composition the child runs under.
|
|
98
|
+
*
|
|
99
|
+
* Omitted selection uses the parent's live composition, including any switch
|
|
100
|
+
* made while the parent was blank.
|
|
101
|
+
* @param parent - the delegating parent agent.
|
|
102
|
+
* @param childDepth - the resolved delegation depth to persist.
|
|
103
|
+
* @param isSeeded - whether this child inherits a parent-log prefix, including an explicitly empty one.
|
|
104
|
+
* @param selectedPreset - independent selection, or omission to inherit the parent.
|
|
105
|
+
* @returns the `meta` for `ctx.agents.create()`.
|
|
106
|
+
*/
|
|
107
|
+
export function childSessionMeta(parent, childDepth, isSeeded, selectedPreset) {
|
|
108
|
+
const parentHeader = parent.session.header;
|
|
109
|
+
const agentPreset = selectedPreset ?? parent.ctx.get('agentPresets')?.composedPreset(parent.ctx);
|
|
110
|
+
return {
|
|
111
|
+
...parentHeader.cwd !== undefined ? { cwd: parentHeader.cwd } : {},
|
|
112
|
+
...agentPreset === undefined ? {} : { agentPreset },
|
|
113
|
+
parentSession: parentHeader.id,
|
|
114
|
+
isSeeded,
|
|
115
|
+
// Navigation classification only; the descriptor remains the authority
|
|
116
|
+
// for mode and continuation capability.
|
|
117
|
+
origin: 'subagent',
|
|
118
|
+
// Durable: the recursion budget must survive persistence and resume.
|
|
119
|
+
delegationDepth: childDepth,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Model-facing delegation-scope statement for an in-process child whose approval
|
|
124
|
+
* policy is `never`. A runtime-context contribution rather than a system-prompt
|
|
125
|
+
* section, so the deployment's system prompt stays uniform across parents and
|
|
126
|
+
* children.
|
|
127
|
+
*/
|
|
128
|
+
export const SUBAGENT_DELEGATION_CONTEXT = 'You are a delegated subagent: your permission scope was fixed when you were started and cannot be '
|
|
129
|
+
+ 'widened from inside this session — operations that require approval are rejected automatically. '
|
|
130
|
+
+ 'When the task needs access beyond that scope, do not retry the denied operation; state the '
|
|
131
|
+
+ 'limitation in your reply so the delegating agent can handle it.';
|
|
132
|
+
/**
|
|
133
|
+
* Model-facing delegation-scope statement for an in-process child whose approval
|
|
134
|
+
* policy is `ask`: the scope stays fixed, but one operation may request a
|
|
135
|
+
* decision from the user who owns the answerers.
|
|
136
|
+
*/
|
|
137
|
+
export const SUBAGENT_DELEGATION_INTERACTIVE_CONTEXT = 'You are a delegated subagent: your permission scope was fixed when you were started and cannot be '
|
|
138
|
+
+ 'widened from inside this session. An operation that needs access beyond that scope may request '
|
|
139
|
+
+ 'approval from the user, who can allow or reject it. Do not retry a rejected or denied operation; '
|
|
140
|
+
+ 'state the limitation in your reply so the delegating agent can handle it.';
|
|
141
|
+
/**
|
|
142
|
+
* Compose a child before publication and restore historical descriptor overrides.
|
|
143
|
+
* Explicit selection mounts the named preset. Omission joins a supplied creator's
|
|
144
|
+
* current generation; a restored child without a saved preset uses host composition.
|
|
145
|
+
* Registrations belong to the child's scope.
|
|
146
|
+
* @param childCtx - the child agent's scoped creation context.
|
|
147
|
+
* @param parent - creator for fresh delegation; absent during target-only restoration.
|
|
148
|
+
* @param composition - independent preset and any overrides read from a historical descriptor.
|
|
149
|
+
* @param approvalPolicy - the child's effective approval policy, selecting its delegation statement.
|
|
150
|
+
* @returns A promise when mounting an independent preset; otherwise completes synchronously.
|
|
151
|
+
*/
|
|
152
|
+
export function applyChildComposition(childCtx, parent, composition, approvalPolicy) {
|
|
153
|
+
if (composition.agentPreset !== undefined) {
|
|
154
|
+
const presets = childCtx.get('agentPresets');
|
|
155
|
+
if (presets === undefined) {
|
|
156
|
+
throw new SubagentError('selecting a child agent preset requires the agent-presets service', 'PRESET_UNAVAILABLE');
|
|
157
|
+
}
|
|
158
|
+
return presets.mount(childCtx, composition.agentPreset).then(() => {
|
|
159
|
+
applyChildOverrides(childCtx, composition, approvalPolicy);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (parent !== undefined)
|
|
163
|
+
childCtx.get('agentPresets')?.composeFrom(childCtx, parent.ctx);
|
|
164
|
+
applyChildOverrides(childCtx, composition, approvalPolicy);
|
|
165
|
+
}
|
|
166
|
+
function applyChildOverrides(childCtx, composition, approvalPolicy) {
|
|
167
|
+
childCtx.systemPrompt.context({
|
|
168
|
+
name: 'subagent:delegation',
|
|
169
|
+
order: childCtx.systemPrompt.getContextOrder('SUBAGENT_DELEGATION'),
|
|
170
|
+
text: approvalPolicy === 'ask'
|
|
171
|
+
? SUBAGENT_DELEGATION_INTERACTIVE_CONTEXT
|
|
172
|
+
: SUBAGENT_DELEGATION_CONTEXT,
|
|
173
|
+
});
|
|
174
|
+
if (composition.persona !== undefined) {
|
|
175
|
+
childCtx.systemPrompt.section({
|
|
176
|
+
name: 'deployment:persona-prefix',
|
|
177
|
+
order: childCtx.systemPrompt.getSectionOrder('DEPLOYMENT_PERSONA_PREFIX'),
|
|
178
|
+
text: composition.persona,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
if (composition.toolFilter !== undefined)
|
|
182
|
+
childCtx.tools.restrict(composition.toolFilter);
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Capture the permission state to seed into one delegation. Call synchronously before
|
|
186
|
+
* the child start's first await: a later parent switch belongs to the
|
|
187
|
+
* parent's future, not to this child. Auto and Full access identities are
|
|
188
|
+
* inherited only through the in-process DSH path so either can replace a stale
|
|
189
|
+
* same-bundle fork value. Only the parent session's explicit sandbox override
|
|
190
|
+
* is captured — never deployment defaults or one-shot grants. Approval is
|
|
191
|
+
* pinned to `'never'` by default; `'inherit'` seeds the parent's current
|
|
192
|
+
* effective policy instead, which only a surface that also answers descendant
|
|
193
|
+
* Agents can turn into a prompt.
|
|
194
|
+
* @param parent - the delegating parent agent.
|
|
195
|
+
* @param delegatedApproval - `'never'` to pin rejection, `'inherit'` to seed the parent's effective policy.
|
|
196
|
+
* @returns the sandbox override (or `undefined` without one) and the approval policy seed.
|
|
197
|
+
*/
|
|
198
|
+
export function captureDelegatedPolicyOverrides(parent, delegatedApproval) {
|
|
199
|
+
const preset = parent.ctx.get('permissionPresets')?.current(parent.session);
|
|
200
|
+
const approval = parent.ctx.get('approval');
|
|
201
|
+
return {
|
|
202
|
+
permissionPreset: preset === 'auto' || preset === 'danger-full-access' ? preset : undefined,
|
|
203
|
+
sandboxMode: parent.ctx.get('sandboxPolicy')?.overrideOf(parent.session),
|
|
204
|
+
approvalPolicy: approval === undefined
|
|
205
|
+
? undefined
|
|
206
|
+
: delegatedApproval === 'inherit' ? approval.effectivePolicy(parent.session) : 'never',
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Append the captured delegation policy onto the child's own log as
|
|
211
|
+
* `source: 'delegation'` events after Session announcement and before Agent registration, so the
|
|
212
|
+
* child's effective policy is reconstructable from its log alone. Appends land
|
|
213
|
+
* after any fork seed, so fresh policy wins stale seed state; later child
|
|
214
|
+
* switches still win over these events.
|
|
215
|
+
* @param childSession - the child's announced, writable Session.
|
|
216
|
+
* @param overrides - the policy captured at delegation.
|
|
217
|
+
*/
|
|
218
|
+
export function appendDelegatedPolicyOverrides(childSession, overrides) {
|
|
219
|
+
if (overrides.sandboxMode !== undefined) {
|
|
220
|
+
childSession.append('sandbox/mode', { mode: overrides.sandboxMode, source: 'delegation' });
|
|
221
|
+
}
|
|
222
|
+
if (overrides.approvalPolicy !== undefined) {
|
|
223
|
+
childSession.append('approval/policy', { policy: overrides.approvalPolicy, source: 'delegation' });
|
|
224
|
+
}
|
|
225
|
+
if (overrides.permissionPreset !== undefined) {
|
|
226
|
+
childSession.append('permission/preset', { preset: overrides.permissionPreset });
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=child-agent.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe subagent projection and control vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* @module @deepseek-ai/dsh-subagent/client
|
|
5
|
+
*/
|
|
6
|
+
export type * from './control-types.ts';
|
|
7
|
+
export type { SubagentCatalogEntry, SubagentIdentityProjection, SubagentTimingProjection } from './projection-types.ts';
|
|
8
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-visible messages owned by continuable-subagent orchestration.
|
|
3
|
+
*
|
|
4
|
+
* @module @deepseek-ai/dsh-subagent/continuation-messages
|
|
5
|
+
*/
|
|
6
|
+
import type { Agent } from '@deepseek-ai/dsh-agent';
|
|
7
|
+
import { createUserMessage } from '@deepseek-ai/dsh-llm';
|
|
8
|
+
import type { ContentBlock } from '@deepseek-ai/dsh-llm';
|
|
9
|
+
import type { SessionId } from '@deepseek-ai/dsh-session';
|
|
10
|
+
import type { SubagentResult } from './types.ts';
|
|
11
|
+
/** Durable attribution for one model-authored message between Agents. */
|
|
12
|
+
export interface AgentMessageSource {
|
|
13
|
+
readonly kind: 'agent-message';
|
|
14
|
+
/** A message another agent addressed to this one (`relay` context form). */
|
|
15
|
+
readonly form: 'relay';
|
|
16
|
+
/** Session id of the Agent whose tool call produced the message. */
|
|
17
|
+
readonly senderSessionId: SessionId;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Durable attribution for the runtime's own account of a continuable child
|
|
21
|
+
* settling. Deliberately a different kind from
|
|
22
|
+
* {@link AgentMessageSource}: an Agent message is content the sender chose,
|
|
23
|
+
* while this message is the manager stating what became of the child, and a
|
|
24
|
+
* transcript that merged them would credit the child with words it never wrote.
|
|
25
|
+
*/
|
|
26
|
+
export interface SubagentSettledMessageSource {
|
|
27
|
+
readonly kind: 'subagent-settled';
|
|
28
|
+
/** A runtime account shown without expanding the row (`notice` context form). */
|
|
29
|
+
readonly form: 'notice';
|
|
30
|
+
/** One-line account of how the child ended. */
|
|
31
|
+
readonly summary: string;
|
|
32
|
+
/** Exact execution stop reason; absent on historical notices. Writers always include it. */
|
|
33
|
+
readonly stopReason?: SubagentResult['stopReason'];
|
|
34
|
+
/** Session id of the child that settled. */
|
|
35
|
+
readonly senderSessionId: SessionId;
|
|
36
|
+
}
|
|
37
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
38
|
+
interface MessageSourceMap {
|
|
39
|
+
'agent-message': AgentMessageSource;
|
|
40
|
+
'subagent-settled': SubagentSettledMessageSource;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Build the model-visible and durable representation of one Agent message.
|
|
45
|
+
* @param sender - exact live Agent that authored the message.
|
|
46
|
+
* @param content - model-visible message blocks supplied by the sender.
|
|
47
|
+
* @returns the durable user-message representation delivered to the recipient.
|
|
48
|
+
*/
|
|
49
|
+
export declare function createAgentMessage(sender: Agent, content: ContentBlock[]): ReturnType<typeof createUserMessage>;
|
|
50
|
+
/**
|
|
51
|
+
* Append automatic result-delivery guidance to a parent-delivered child's initial task.
|
|
52
|
+
* @param prompt - initial model-visible task blocks.
|
|
53
|
+
* @returns task blocks followed by the result-delivery guidance.
|
|
54
|
+
*/
|
|
55
|
+
export declare function withResultDeliveryGuidance(prompt: ContentBlock[]): ContentBlock[];
|
|
56
|
+
/**
|
|
57
|
+
* Build the runtime-owned settlement notice from the child's nonempty closing text.
|
|
58
|
+
* @param childId - durable child session id named in the notice.
|
|
59
|
+
* @param terminal - recorded terminal state for the settled Activation.
|
|
60
|
+
* @param continuable - whether the child can accept another task.
|
|
61
|
+
* @param omitClosingText - replace the closing text when the child's last action
|
|
62
|
+
* was a message to its direct parent.
|
|
63
|
+
* @returns the durable user-message representation delivered to the parent.
|
|
64
|
+
*/
|
|
65
|
+
export declare function createSettlementMessage(childId: SessionId, terminal: SubagentResult, continuable?: boolean, omitClosingText?: boolean): ReturnType<typeof createUserMessage>;
|
|
66
|
+
//# sourceMappingURL=continuation-messages.d.ts.map
|