zeitlich 0.2.40 → 0.2.42
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.md +12 -1
- package/dist/{activities-CvUrG3YG.d.cts → activities-Coafq5zr.d.cts} +2 -2
- package/dist/{activities-CULxRzJ1.d.ts → activities-CrN-ghLo.d.ts} +2 -2
- package/dist/adapters/sandbox/daytona/index.cjs +4 -23
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +18 -86
- package/dist/adapters/sandbox/daytona/index.d.ts +18 -86
- package/dist/adapters/sandbox/daytona/index.js +4 -23
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +1 -7
- package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.cts +9 -2
- package/dist/adapters/sandbox/daytona/workflow.d.ts +9 -2
- package/dist/adapters/sandbox/daytona/workflow.js +1 -7
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
- package/dist/adapters/sandbox/e2b/index.cjs +21 -3
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +48 -7
- package/dist/adapters/sandbox/e2b/index.d.ts +48 -7
- package/dist/adapters/sandbox/e2b/index.js +22 -5
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +4 -2
- package/dist/adapters/sandbox/e2b/workflow.d.ts +4 -2
- package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +11 -0
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +11 -3
- package/dist/adapters/sandbox/inmemory/index.d.ts +11 -3
- package/dist/adapters/sandbox/inmemory/index.js +11 -1
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +4 -2
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +4 -2
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
- package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +6 -6
- package/dist/adapters/thread/anthropic/index.d.ts +6 -6
- package/dist/adapters/thread/anthropic/index.js.map +1 -1
- package/dist/adapters/thread/anthropic/workflow.d.cts +6 -6
- package/dist/adapters/thread/anthropic/workflow.d.ts +6 -6
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +6 -6
- package/dist/adapters/thread/google-genai/index.d.ts +6 -6
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/workflow.d.cts +6 -6
- package/dist/adapters/thread/google-genai/workflow.d.ts +6 -6
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +6 -6
- package/dist/adapters/thread/langchain/index.d.ts +6 -6
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/adapters/thread/langchain/workflow.d.cts +6 -6
- package/dist/adapters/thread/langchain/workflow.d.ts +6 -6
- package/dist/index.cjs +316 -119
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +93 -17
- package/dist/index.d.ts +93 -17
- package/dist/index.js +317 -120
- package/dist/index.js.map +1 -1
- package/dist/{proxy-5EbwzaY4.d.cts → proxy-Bf7uI-Hw.d.cts} +1 -1
- package/dist/{proxy-wZufFfBh.d.ts → proxy-COqA95FW.d.ts} +1 -1
- package/dist/{thread-manager-BqBAIsED.d.ts → thread-manager-BhkOyQ1I.d.ts} +2 -2
- package/dist/{thread-manager-BNiIt5r8.d.ts → thread-manager-Bi1XlbpJ.d.ts} +2 -2
- package/dist/{thread-manager-DF8WuCRs.d.cts → thread-manager-BsLO3Fgc.d.cts} +2 -2
- package/dist/{thread-manager-BoN5DOvG.d.cts → thread-manager-wRVVBFgj.d.cts} +2 -2
- package/dist/{types-C7OoY7h8.d.ts → types-BkX4HLzi.d.ts} +1 -1
- package/dist/{types-CuISs0Ub.d.cts → types-C66-BVBr.d.cts} +1 -1
- package/dist/types-CJ7tCdl6.d.cts +266 -0
- package/dist/types-CJ7tCdl6.d.ts +266 -0
- package/dist/{types-DeQH84C_.d.ts → types-CdALEF3z.d.cts} +342 -23
- package/dist/{types-Cn2r3ol3.d.cts → types-ChAy_jSP.d.ts} +342 -23
- package/dist/types-CjY93AWZ.d.cts +84 -0
- package/dist/types-gVa5XCWD.d.ts +84 -0
- package/dist/{workflow-DhplIN65.d.cts → workflow-BwT5EybR.d.ts} +7 -6
- package/dist/{workflow-C2MZZj5K.d.ts → workflow-DMmiaw6w.d.cts} +7 -6
- package/dist/workflow.cjs +138 -77
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +4 -4
- package/dist/workflow.d.ts +4 -4
- package/dist/workflow.js +139 -78
- package/dist/workflow.js.map +1 -1
- package/package.json +17 -33
- package/src/adapters/sandbox/daytona/index.ts +25 -48
- package/src/adapters/sandbox/daytona/proxy.ts +7 -8
- package/src/adapters/sandbox/e2b/README.md +81 -0
- package/src/adapters/sandbox/e2b/index.ts +53 -11
- package/src/adapters/sandbox/e2b/keep-alive.test.ts +115 -0
- package/src/adapters/sandbox/e2b/proxy.ts +3 -2
- package/src/adapters/sandbox/e2b/types.ts +34 -2
- package/src/adapters/sandbox/inmemory/index.ts +21 -1
- package/src/adapters/sandbox/inmemory/proxy.ts +7 -3
- package/src/index.ts +1 -1
- package/src/lib/activity.ts +5 -0
- package/src/lib/sandbox/capability-types.test.ts +859 -0
- package/src/lib/sandbox/index.ts +1 -0
- package/src/lib/sandbox/manager.ts +187 -31
- package/src/lib/sandbox/types.ts +189 -46
- package/src/lib/session/index.ts +1 -0
- package/src/lib/session/session.integration.test.ts +58 -0
- package/src/lib/session/session.ts +109 -50
- package/src/lib/session/types.ts +189 -8
- package/src/lib/subagent/handler.ts +66 -43
- package/src/lib/subagent/subagent.integration.test.ts +2 -0
- package/src/lib/subagent/types.ts +492 -16
- package/src/lib/subagent/workflow.ts +11 -1
- package/src/lib/tool-router/auto-append-sandbox.integration.test.ts +158 -0
- package/src/lib/tool-router/index.ts +1 -1
- package/src/lib/tool-router/with-sandbox.ts +45 -2
- package/src/lib/virtual-fs/filesystem.ts +41 -16
- package/src/lib/virtual-fs/types.ts +19 -0
- package/src/lib/virtual-fs/virtual-fs.test.ts +204 -1
- package/src/tools/read-file/handler.test.ts +83 -0
- package/src/workflow.ts +3 -0
- package/tsup.config.ts +0 -4
- package/dist/adapters/sandbox/bedrock/index.cjs +0 -457
- package/dist/adapters/sandbox/bedrock/index.cjs.map +0 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +0 -25
- package/dist/adapters/sandbox/bedrock/index.d.ts +0 -25
- package/dist/adapters/sandbox/bedrock/index.js +0 -454
- package/dist/adapters/sandbox/bedrock/index.js.map +0 -1
- package/dist/adapters/sandbox/bedrock/workflow.cjs +0 -36
- package/dist/adapters/sandbox/bedrock/workflow.cjs.map +0 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +0 -29
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +0 -29
- package/dist/adapters/sandbox/bedrock/workflow.js +0 -34
- package/dist/adapters/sandbox/bedrock/workflow.js.map +0 -1
- package/dist/types-DAsQ21Rt.d.ts +0 -74
- package/dist/types-lm8tMNJQ.d.cts +0 -74
- package/dist/types-yx0LzPGn.d.cts +0 -173
- package/dist/types-yx0LzPGn.d.ts +0 -173
- package/src/adapters/sandbox/bedrock/filesystem.ts +0 -340
- package/src/adapters/sandbox/bedrock/index.ts +0 -274
- package/src/adapters/sandbox/bedrock/proxy.ts +0 -59
- package/src/adapters/sandbox/bedrock/types.ts +0 -24
|
@@ -11,7 +11,12 @@ import type {
|
|
|
11
11
|
SandboxInit,
|
|
12
12
|
SubagentSandboxShutdown,
|
|
13
13
|
} from "../lifecycle";
|
|
14
|
-
import type {
|
|
14
|
+
import type {
|
|
15
|
+
SandboxCapability,
|
|
16
|
+
SandboxCreateOptions,
|
|
17
|
+
SandboxOps,
|
|
18
|
+
SandboxSnapshot,
|
|
19
|
+
} from "../sandbox/types";
|
|
15
20
|
|
|
16
21
|
/**
|
|
17
22
|
* Subset of {@link ChildWorkflowOptions} that callers may override when a
|
|
@@ -80,6 +85,469 @@ export type SubagentContext =
|
|
|
80
85
|
export type InferSubagentResult<T extends SubagentConfig> =
|
|
81
86
|
T extends SubagentConfig<infer S> ? z.infer<S> : null;
|
|
82
87
|
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Subagent sandbox-lifecycle decision table (SSOT)
|
|
90
|
+
//
|
|
91
|
+
// `createSubagentHandler` (`src/lib/subagent/handler.ts`) auto-injects
|
|
92
|
+
// `sandboxShutdown` for some `(source, continuation, init, shutdown)`
|
|
93
|
+
// combinations (`mustSurvive` + `alreadySurvives` rules). The child
|
|
94
|
+
// session then dispatches gated sandbox methods based on the resolved
|
|
95
|
+
// `(sandbox.mode, sandboxShutdown)` pair (`src/lib/session/session.ts`).
|
|
96
|
+
//
|
|
97
|
+
// Two surfaces have to agree on what gated methods may fire for a given
|
|
98
|
+
// config:
|
|
99
|
+
//
|
|
100
|
+
// 1. The runtime — what the parent injects + what the child session
|
|
101
|
+
// dispatches.
|
|
102
|
+
// 2. The type level — what caps the proxy field has to advertise.
|
|
103
|
+
//
|
|
104
|
+
// `SubagentRequiredCaps<C>` is the SSOT for the type level.
|
|
105
|
+
// `resolveSubagentLifecycle(cfg)` (in `handler.ts`) is the SSOT for the
|
|
106
|
+
// runtime; it returns the specific `(mode, shutdown)` to inject and is
|
|
107
|
+
// the only place the auto-injection rules live. Adding a new runtime
|
|
108
|
+
// branch in `handler.ts` requires extending **both** — the matrix in
|
|
109
|
+
// `src/lib/sandbox/capability-types.test.ts` then locks the agreement.
|
|
110
|
+
//
|
|
111
|
+
// `Continuation`-only / `Shutdown`-only sub-types live below as helpers
|
|
112
|
+
// `_ChildModeCaps` / `_ChildShutdownCaps` so each branch reads cleanly.
|
|
113
|
+
// ============================================================================
|
|
114
|
+
|
|
115
|
+
/** Shutdown classes that the runtime treats equivalently for cap purposes. */
|
|
116
|
+
type _ShutdownPauseLike = "pause" | "pause-until-parent-close";
|
|
117
|
+
type _ShutdownKeepLike = "keep" | "keep-until-parent-close";
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Caps the child session's sandbox-init dispatch invokes for a given
|
|
121
|
+
* `(mode, shutdown)`. Mirror of `src/lib/session/session.ts:230-314`.
|
|
122
|
+
*/
|
|
123
|
+
type _ChildModeCaps<Mode, Shutdown> =
|
|
124
|
+
// mode "fork" → forkSandbox
|
|
125
|
+
| (Mode extends "fork" ? "fork" : never)
|
|
126
|
+
// mode "from-snapshot" → restoreSandbox
|
|
127
|
+
| (Mode extends "from-snapshot" ? "restore" : never)
|
|
128
|
+
// mode "continue" + shutdown "pause-until-parent-close" → resumeSandbox
|
|
129
|
+
| (Mode extends "continue"
|
|
130
|
+
? Shutdown extends "pause-until-parent-close"
|
|
131
|
+
? "resume"
|
|
132
|
+
: never
|
|
133
|
+
: never);
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Caps the child session's exit dispatch invokes for a given `shutdown`.
|
|
137
|
+
* Only fires when `sandboxOwned` is true (mode != "inherit"). Mirror of
|
|
138
|
+
* `src/lib/session/session.ts:598-615`.
|
|
139
|
+
*/
|
|
140
|
+
type _ChildShutdownCaps<Mode, Shutdown> =
|
|
141
|
+
// mode="inherit" → sandboxOwned=false → no exit-shutdown caps fire
|
|
142
|
+
Mode extends "inherit"
|
|
143
|
+
? never
|
|
144
|
+
:
|
|
145
|
+
| (Shutdown extends _ShutdownPauseLike ? "pause" : never)
|
|
146
|
+
| (Shutdown extends "snapshot" ? "snapshot" : never);
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Caps captured on entry for `mode: "new"` + `shutdown: "snapshot"`
|
|
150
|
+
* (the seeding-base-snapshot path). Mirror of
|
|
151
|
+
* `src/lib/session/session.ts:316-317`.
|
|
152
|
+
*/
|
|
153
|
+
type _ChildSeedCaps<Mode, Shutdown> = Mode extends "new"
|
|
154
|
+
? Shutdown extends "snapshot"
|
|
155
|
+
? "snapshot"
|
|
156
|
+
: never
|
|
157
|
+
: never;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Total caps a single child-session invocation calls for the specific
|
|
161
|
+
* `(mode, shutdown)` pair the parent passes. The proxy field's required
|
|
162
|
+
* cap union is the union of this across every `(mode, shutdown)` the
|
|
163
|
+
* runtime might inject for the given config.
|
|
164
|
+
*/
|
|
165
|
+
type _ChildSessionCaps<Mode, Shutdown> =
|
|
166
|
+
| _ChildModeCaps<Mode, Shutdown>
|
|
167
|
+
| _ChildShutdownCaps<Mode, Shutdown>
|
|
168
|
+
| _ChildSeedCaps<Mode, Shutdown>;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Resolves the user's `shutdown` value through the auto-injection rules
|
|
172
|
+
* for `(source: "own", continuation: "continue")`. Mirror of
|
|
173
|
+
* `src/lib/subagent/handler.ts:373-389`:
|
|
174
|
+
*
|
|
175
|
+
* - `pause` / `pause-until-parent-close` / `keep` / `keep-until-parent-close`
|
|
176
|
+
* → propagate (`alreadySurvives = true`).
|
|
177
|
+
* - everything else (undefined, "destroy", "snapshot") → injected
|
|
178
|
+
* `"pause"` (subsequent calls) or `"pause-until-parent-close"`
|
|
179
|
+
* (creator first call). Type-level: union both.
|
|
180
|
+
*/
|
|
181
|
+
type _ContinueShutdown<S> = S extends _ShutdownPauseLike | _ShutdownKeepLike
|
|
182
|
+
? S
|
|
183
|
+
: "pause" | "pause-until-parent-close";
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Resolves the user's `shutdown` value through the auto-injection rules
|
|
187
|
+
* for `(source: "own", continuation: "fork", init: "once")`. Same shape
|
|
188
|
+
* as `_ContinueShutdown` because both are `mustSurvive` paths.
|
|
189
|
+
*/
|
|
190
|
+
type _ForkOnceShutdown<S> = _ContinueShutdown<S>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Modes the child session may be invoked under for `(source: "own",
|
|
194
|
+
* continuation: "continue")`. First call has no `baseSandboxId` (mode
|
|
195
|
+
* "new"); subsequent calls reuse it (mode "continue"). The type takes
|
|
196
|
+
* the union — the matrix can't tell first vs. subsequent statically.
|
|
197
|
+
*/
|
|
198
|
+
type _OwnContinueModes = "new" | "continue";
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Modes the child session may be invoked under for `(source: "own",
|
|
202
|
+
* continuation: "fork")`. Same first-vs-subsequent shape as continue.
|
|
203
|
+
*/
|
|
204
|
+
type _OwnForkModes = "new" | "fork";
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Modes the child session may be invoked under for `(source: "own",
|
|
208
|
+
* continuation: "snapshot")`. First call (no base snapshot yet) uses
|
|
209
|
+
* "new"; subsequent calls (or `init: "once"` after the first creator
|
|
210
|
+
* publishes a base) use "from-snapshot".
|
|
211
|
+
*/
|
|
212
|
+
type _OwnSnapshotModes = "new" | "from-snapshot";
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Caps required on a subagent's `proxy` for the parent's own gated
|
|
216
|
+
* calls. The parent only ever calls `destroySandbox` (base) and
|
|
217
|
+
* `deleteSandboxSnapshot` (`continuation: "snapshot"` cleanup).
|
|
218
|
+
*/
|
|
219
|
+
type _ParentLocalCaps<C> = C extends { continuation: "snapshot" }
|
|
220
|
+
? "snapshot"
|
|
221
|
+
: never;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* **SSOT type.** The full cap union a subagent's `proxy` must expose,
|
|
225
|
+
* derived from `(source, continuation, init, shutdown)`.
|
|
226
|
+
*
|
|
227
|
+
* The shape mirrors the rows of the runtime decision table in
|
|
228
|
+
* `resolveSubagentLifecycle` (`src/lib/subagent/handler.ts`): each
|
|
229
|
+
* branch here corresponds to exactly one runtime branch, and adding a
|
|
230
|
+
* new runtime branch requires adding a matching branch here. The
|
|
231
|
+
* `(adapter × continuation × shutdown × init × source)` matrix in
|
|
232
|
+
* `src/lib/sandbox/capability-types.test.ts` enforces agreement.
|
|
233
|
+
*/
|
|
234
|
+
export type SubagentRequiredCaps<C> = C extends "none"
|
|
235
|
+
? never
|
|
236
|
+
: C extends { source: "inherit"; continuation: "continue" }
|
|
237
|
+
? // mode="inherit", sandboxOwned=false → no gated calls regardless
|
|
238
|
+
// of shutdown value.
|
|
239
|
+
never
|
|
240
|
+
: C extends { source: "inherit"; continuation: "fork" }
|
|
241
|
+
? // mode="fork" + user shutdown propagates verbatim (no
|
|
242
|
+
// auto-injection on the inherit path).
|
|
243
|
+
| "fork"
|
|
244
|
+
| _ChildSessionCaps<
|
|
245
|
+
"fork",
|
|
246
|
+
C extends { shutdown: infer S } ? S : "destroy"
|
|
247
|
+
>
|
|
248
|
+
| _ParentLocalCaps<C>
|
|
249
|
+
: C extends { source: "own"; continuation: "snapshot" }
|
|
250
|
+
? // override = "snapshot" always; modes vary across calls.
|
|
251
|
+
| _ChildSessionCaps<_OwnSnapshotModes, "snapshot">
|
|
252
|
+
| _ParentLocalCaps<C>
|
|
253
|
+
: C extends { source: "own"; continuation: "continue" }
|
|
254
|
+
? // mustSurvive=true; injection rules apply.
|
|
255
|
+
| _ChildSessionCaps<
|
|
256
|
+
_OwnContinueModes,
|
|
257
|
+
_ContinueShutdown<
|
|
258
|
+
C extends { shutdown: infer S } ? S : undefined
|
|
259
|
+
>
|
|
260
|
+
>
|
|
261
|
+
| _ParentLocalCaps<C>
|
|
262
|
+
: C extends {
|
|
263
|
+
source: "own";
|
|
264
|
+
continuation: "fork";
|
|
265
|
+
init?: infer I;
|
|
266
|
+
}
|
|
267
|
+
? // mustSurvive iff init=once.
|
|
268
|
+
| "fork"
|
|
269
|
+
| _ChildSessionCaps<
|
|
270
|
+
_OwnForkModes,
|
|
271
|
+
I extends "once"
|
|
272
|
+
? _ForkOnceShutdown<
|
|
273
|
+
C extends { shutdown: infer S } ? S : undefined
|
|
274
|
+
>
|
|
275
|
+
: C extends { shutdown: infer S }
|
|
276
|
+
? S extends undefined
|
|
277
|
+
? "destroy"
|
|
278
|
+
: S
|
|
279
|
+
: "destroy"
|
|
280
|
+
>
|
|
281
|
+
| _ParentLocalCaps<C>
|
|
282
|
+
: never;
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Backwards-compatible alias retained for external callers that imported
|
|
286
|
+
* the old name. Resolves through the SSOT against a synthetic
|
|
287
|
+
* `{ source: "own", continuation: C }` config.
|
|
288
|
+
*
|
|
289
|
+
* @deprecated Use `SubagentRequiredCaps<C>` against the full subagent
|
|
290
|
+
* sandbox config — `continuation` alone misses `shutdown` and `init`,
|
|
291
|
+
* which is why the previous mapping under-rejected `fork`+`pause` and
|
|
292
|
+
* `continue`+auto-injected pause.
|
|
293
|
+
*/
|
|
294
|
+
export type SubagentContinuationCaps<C extends SubagentContinuation> =
|
|
295
|
+
C extends "snapshot"
|
|
296
|
+
? "snapshot" | "restore"
|
|
297
|
+
: C extends "fork"
|
|
298
|
+
? "fork"
|
|
299
|
+
: never;
|
|
300
|
+
|
|
301
|
+
// ============================================================================
|
|
302
|
+
// Subagent lifecycle SSOT — runtime mirror of `SubagentRequiredCaps`
|
|
303
|
+
//
|
|
304
|
+
// `resolveSubagentLifecycle` is the runtime side of the same table
|
|
305
|
+
// `SubagentRequiredCaps` reads at the type level. Whenever
|
|
306
|
+
// `createSubagentHandler` (`src/lib/subagent/handler.ts`) needs to
|
|
307
|
+
// decide which `(sandbox.mode, sandboxShutdown)` to inject for the
|
|
308
|
+
// child, it calls this function — so the auto-injection rules
|
|
309
|
+
// (`mustSurvive`, `alreadySurvives`, snapshot override) live in
|
|
310
|
+
// **one** place. Adding a new branch to the runtime means changing
|
|
311
|
+
// this function AND the matching branch in `SubagentRequiredCaps`;
|
|
312
|
+
// the `(adapter × continuation × shutdown × init × source)` matrix
|
|
313
|
+
// in `src/lib/sandbox/capability-types.test.ts` enforces the agree.
|
|
314
|
+
// ============================================================================
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Resolved sandbox config after normalising defaults. The handler
|
|
318
|
+
* passes one of these into `resolveSubagentLifecycle`.
|
|
319
|
+
*/
|
|
320
|
+
export interface ResolvedSubagentSandboxConfig {
|
|
321
|
+
source: "none" | "inherit" | "own";
|
|
322
|
+
init: "per-call" | "once";
|
|
323
|
+
continuation: "continue" | "fork" | "snapshot";
|
|
324
|
+
shutdown?: SubagentSandboxShutdown;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Output of `resolveSubagentLifecycle`. The handler reads
|
|
329
|
+
* `shutdownOverride` to decide what to forward to the child workflow,
|
|
330
|
+
* and `mustSurvive` / `isLazyCreator` to drive the in-handler
|
|
331
|
+
* bookkeeping (pendingDestroys, persistentSandboxes, etc.).
|
|
332
|
+
*/
|
|
333
|
+
export interface ResolvedSubagentLifecycle {
|
|
334
|
+
/**
|
|
335
|
+
* Sandbox shutdown the parent forwards to the child workflow. May
|
|
336
|
+
* be auto-injected (`"pause"` / `"pause-until-parent-close"` /
|
|
337
|
+
* `"snapshot"`) when the user's literal would not survive long
|
|
338
|
+
* enough for the parent's continuation strategy.
|
|
339
|
+
*/
|
|
340
|
+
shutdownOverride: SubagentSandboxShutdown | undefined;
|
|
341
|
+
/**
|
|
342
|
+
* Whether the parent must keep the sandbox alive past the child
|
|
343
|
+
* session's exit. Drives the `pendingDestroys` map population.
|
|
344
|
+
*/
|
|
345
|
+
mustSurvive: boolean;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Returns true iff the user's `shutdown` already keeps the sandbox
|
|
350
|
+
* alive (so the handler doesn't need to auto-inject one).
|
|
351
|
+
*
|
|
352
|
+
* Mirror of the type-level `_ShutdownPauseLike` / `_ShutdownKeepLike`
|
|
353
|
+
* checks above.
|
|
354
|
+
*/
|
|
355
|
+
function isSurvivalShutdown(s: SubagentSandboxShutdown | undefined): boolean {
|
|
356
|
+
return (
|
|
357
|
+
s === "pause" ||
|
|
358
|
+
s === "pause-until-parent-close" ||
|
|
359
|
+
s === "keep" ||
|
|
360
|
+
s === "keep-until-parent-close"
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* The single runtime decision-table consumer. Returns the shutdown the
|
|
366
|
+
* parent should forward to the child plus survival metadata.
|
|
367
|
+
*
|
|
368
|
+
* Branches must agree, one-for-one, with `SubagentRequiredCaps<C>` in
|
|
369
|
+
* this file. The matrix in `capability-types.test.ts` covers each
|
|
370
|
+
* branch.
|
|
371
|
+
*/
|
|
372
|
+
export function resolveSubagentLifecycle(
|
|
373
|
+
cfg: ResolvedSubagentSandboxConfig,
|
|
374
|
+
isLazyCreator: boolean
|
|
375
|
+
): ResolvedSubagentLifecycle {
|
|
376
|
+
// none / inherit: no auto-injection. Handler still calls
|
|
377
|
+
// destroySandbox on child exit when mode=inherit, but
|
|
378
|
+
// `sandboxOwned` stays false in the child session so no exit-
|
|
379
|
+
// shutdown caps fire. Parent's pendingDestroys is driven entirely
|
|
380
|
+
// by the user's shutdown propagating verbatim.
|
|
381
|
+
if (cfg.source !== "own") {
|
|
382
|
+
return {
|
|
383
|
+
shutdownOverride: cfg.shutdown,
|
|
384
|
+
mustSurvive: false,
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// own + snapshot: handler always overrides shutdown to "snapshot".
|
|
389
|
+
// No survival flag (snapshots are cleaned up via deleteSandboxSnapshot,
|
|
390
|
+
// not via pendingDestroys).
|
|
391
|
+
if (cfg.continuation === "snapshot") {
|
|
392
|
+
return {
|
|
393
|
+
shutdownOverride: "snapshot",
|
|
394
|
+
mustSurvive: false,
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// own + (continue | fork): mustSurvive iff isLazyCreator OR
|
|
399
|
+
// continuation === "continue" OR (init === "once" + fork).
|
|
400
|
+
const isLazy = cfg.init === "once";
|
|
401
|
+
const mustSurvive =
|
|
402
|
+
isLazyCreator ||
|
|
403
|
+
cfg.continuation === "continue" ||
|
|
404
|
+
(isLazy && cfg.continuation === "fork");
|
|
405
|
+
|
|
406
|
+
if (!mustSurvive) {
|
|
407
|
+
return { shutdownOverride: cfg.shutdown, mustSurvive: false };
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// mustSurvive: auto-inject only if the user's shutdown doesn't
|
|
411
|
+
// already survive.
|
|
412
|
+
if (isSurvivalShutdown(cfg.shutdown)) {
|
|
413
|
+
return { shutdownOverride: cfg.shutdown, mustSurvive };
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
shutdownOverride: isLazyCreator ? "pause-until-parent-close" : "pause",
|
|
417
|
+
mustSurvive,
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/** Continuation values supported when `source` is `"inherit"`. */
|
|
422
|
+
type InheritContinuation = "continue" | "fork";
|
|
423
|
+
/** Continuation values supported when `source` is `"own"`. */
|
|
424
|
+
type OwnContinuation = "continue" | "fork" | "snapshot";
|
|
425
|
+
/** Union of every continuation value across both sources. */
|
|
426
|
+
type SubagentContinuation = InheritContinuation | OwnContinuation;
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Caps required on a subagent's `proxy` when `source: "inherit"`,
|
|
430
|
+
* threaded through the SSOT.
|
|
431
|
+
*
|
|
432
|
+
* The `inherit` source has no `init` field, and the `shutdown` field
|
|
433
|
+
* is the user's literal (or `"destroy"` if omitted). We don't have a
|
|
434
|
+
* way to detect "omitted" in the field type itself, so this row
|
|
435
|
+
* resolves the user's `S | undefined` directly — `undefined` is treated
|
|
436
|
+
* as `"destroy"` to match the runtime default in
|
|
437
|
+
* `src/lib/subagent/handler.ts:469`.
|
|
438
|
+
*/
|
|
439
|
+
type _InheritCaps<C extends InheritContinuation, S> = SubagentRequiredCaps<{
|
|
440
|
+
source: "inherit";
|
|
441
|
+
continuation: C;
|
|
442
|
+
shutdown: S extends undefined ? "destroy" : S;
|
|
443
|
+
}>;
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* Variants for `source: "inherit"`. Continuation × shutdown-presence ×
|
|
447
|
+
* shutdown-literal all distribute, with omitted vs. specified
|
|
448
|
+
* `shutdown` encoded as separate variants — for the same reason
|
|
449
|
+
* `OwnVariant` does (forbid TS from matching a permissive cell when
|
|
450
|
+
* the user omits the field).
|
|
451
|
+
*/
|
|
452
|
+
type InheritVariant<TOptions extends SandboxCreateOptions> =
|
|
453
|
+
InheritContinuation extends infer C
|
|
454
|
+
? C extends InheritContinuation
|
|
455
|
+
? (
|
|
456
|
+
| { _s: undefined; shutdown?: never }
|
|
457
|
+
| (SubagentSandboxShutdown extends infer SL
|
|
458
|
+
? SL extends SubagentSandboxShutdown
|
|
459
|
+
? { _s: SL; shutdown: SL }
|
|
460
|
+
: never
|
|
461
|
+
: never)
|
|
462
|
+
) extends infer S
|
|
463
|
+
? S extends {
|
|
464
|
+
_s: SubagentSandboxShutdown | undefined;
|
|
465
|
+
shutdown?: SubagentSandboxShutdown;
|
|
466
|
+
}
|
|
467
|
+
? Omit<S, "_s"> & {
|
|
468
|
+
source: "inherit";
|
|
469
|
+
continuation: C;
|
|
470
|
+
proxy: (
|
|
471
|
+
scope: string
|
|
472
|
+
) => SandboxOps<
|
|
473
|
+
TOptions,
|
|
474
|
+
unknown,
|
|
475
|
+
_InheritCaps<C, S["_s"]> & SandboxCapability
|
|
476
|
+
>;
|
|
477
|
+
}
|
|
478
|
+
: never
|
|
479
|
+
: never
|
|
480
|
+
: never
|
|
481
|
+
: never;
|
|
482
|
+
|
|
483
|
+
type _OwnCaps<
|
|
484
|
+
C extends OwnContinuation,
|
|
485
|
+
I extends "per-call" | "once" | undefined,
|
|
486
|
+
S,
|
|
487
|
+
> = SubagentRequiredCaps<{
|
|
488
|
+
source: "own";
|
|
489
|
+
continuation: C;
|
|
490
|
+
init: I extends undefined ? "per-call" : I;
|
|
491
|
+
shutdown: S;
|
|
492
|
+
}>;
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Variants for `source: "own"`. Continuation × init-presence × shutdown-
|
|
496
|
+
* presence × shutdown-literal all distribute, so each cell gets its
|
|
497
|
+
* own variant with a precisely-typed `proxy`.
|
|
498
|
+
*
|
|
499
|
+
* Critical: omitted vs. specified `init` / `shutdown` are encoded as
|
|
500
|
+
* *separate* variants. The omitted variant uses `init?: never` /
|
|
501
|
+
* `shutdown?: never` so the field is forbidden when the user doesn't
|
|
502
|
+
* write one — without this, TS would infer `field?: undefined` and
|
|
503
|
+
* happily match an unrelated permissive variant whose caps don't
|
|
504
|
+
* cover the auto-injection.
|
|
505
|
+
*/
|
|
506
|
+
type OwnVariant<TOptions extends SandboxCreateOptions> =
|
|
507
|
+
OwnContinuation extends infer C
|
|
508
|
+
? C extends OwnContinuation
|
|
509
|
+
? // Init: omitted (never present) | "per-call" required | "once" required.
|
|
510
|
+
(
|
|
511
|
+
| { _i: undefined; init?: never }
|
|
512
|
+
| { _i: "per-call"; init: "per-call" }
|
|
513
|
+
| { _i: "once"; init: "once" }
|
|
514
|
+
) extends infer I
|
|
515
|
+
? I extends {
|
|
516
|
+
_i: "per-call" | "once" | undefined;
|
|
517
|
+
init?: "per-call" | "once";
|
|
518
|
+
}
|
|
519
|
+
? // Shutdown: omitted | one of the literal values required.
|
|
520
|
+
(
|
|
521
|
+
| { _s: undefined; shutdown?: never }
|
|
522
|
+
| (SubagentSandboxShutdown extends infer SL
|
|
523
|
+
? SL extends SubagentSandboxShutdown
|
|
524
|
+
? { _s: SL; shutdown: SL }
|
|
525
|
+
: never
|
|
526
|
+
: never)
|
|
527
|
+
) extends infer S
|
|
528
|
+
? S extends {
|
|
529
|
+
_s: SubagentSandboxShutdown | undefined;
|
|
530
|
+
shutdown?: SubagentSandboxShutdown;
|
|
531
|
+
}
|
|
532
|
+
? Omit<I, "_i"> &
|
|
533
|
+
Omit<S, "_s"> & {
|
|
534
|
+
source: "own";
|
|
535
|
+
continuation: C;
|
|
536
|
+
proxy: (
|
|
537
|
+
scope: string
|
|
538
|
+
) => SandboxOps<
|
|
539
|
+
TOptions,
|
|
540
|
+
unknown,
|
|
541
|
+
_OwnCaps<C, I["_i"], S["_s"]> & SandboxCapability
|
|
542
|
+
>;
|
|
543
|
+
}
|
|
544
|
+
: never
|
|
545
|
+
: never
|
|
546
|
+
: never
|
|
547
|
+
: never
|
|
548
|
+
: never
|
|
549
|
+
: never;
|
|
550
|
+
|
|
83
551
|
/**
|
|
84
552
|
* Sandbox configuration for a subagent.
|
|
85
553
|
*
|
|
@@ -97,22 +565,22 @@ export type InferSubagentResult<T extends SubagentConfig> =
|
|
|
97
565
|
* `scope = agentName`, so the returned proxy resolves to the same activity
|
|
98
566
|
* prefix the child session uses. The parent uses it to destroy lingering
|
|
99
567
|
* sandboxes and delete stored snapshots at shutdown.
|
|
568
|
+
*
|
|
569
|
+
* The `proxy` field's required `TCaps` is derived from
|
|
570
|
+
* {@link SubagentRequiredCaps} — the SSOT that mirrors
|
|
571
|
+
* `resolveSubagentLifecycle` in the handler. It folds in `shutdown` and
|
|
572
|
+
* `init` (including the handler's auto-injected `"pause"` /
|
|
573
|
+
* `"pause-until-parent-close"` overrides), so any `(adapter, source,
|
|
574
|
+
* continuation, init, shutdown)` cell that can't execute at runtime
|
|
575
|
+
* fails to typecheck at the `defineSubagent` site.
|
|
576
|
+
*
|
|
577
|
+
* `TOptions` defaults to {@link SandboxCreateOptions} so the wide,
|
|
578
|
+
* un-parameterised `SubagentSandboxConfig` keeps working for callers
|
|
579
|
+
* that don't need adapter-specific options.
|
|
100
580
|
*/
|
|
101
|
-
export type SubagentSandboxConfig
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
source: "inherit";
|
|
105
|
-
continuation: "continue" | "fork";
|
|
106
|
-
shutdown?: SubagentSandboxShutdown;
|
|
107
|
-
proxy: (scope: string) => SandboxOps;
|
|
108
|
-
}
|
|
109
|
-
| {
|
|
110
|
-
source: "own";
|
|
111
|
-
init?: "per-call" | "once";
|
|
112
|
-
continuation: "continue" | "fork" | "snapshot";
|
|
113
|
-
shutdown?: SubagentSandboxShutdown;
|
|
114
|
-
proxy: (scope: string) => SandboxOps;
|
|
115
|
-
};
|
|
581
|
+
export type SubagentSandboxConfig<
|
|
582
|
+
TOptions extends SandboxCreateOptions = SandboxCreateOptions,
|
|
583
|
+
> = "none" | InheritVariant<TOptions> | OwnVariant<TOptions>;
|
|
116
584
|
|
|
117
585
|
/**
|
|
118
586
|
* Configuration for a subagent that can be spawned by the parent workflow.
|
|
@@ -278,5 +746,13 @@ export interface SubagentSessionInput {
|
|
|
278
746
|
sandboxId?: string;
|
|
279
747
|
snapshot?: SandboxSnapshot;
|
|
280
748
|
threadId: string;
|
|
749
|
+
usage: {
|
|
750
|
+
totalInputTokens: number;
|
|
751
|
+
totalOutputTokens: number;
|
|
752
|
+
totalCachedWriteTokens: number;
|
|
753
|
+
totalCachedReadTokens: number;
|
|
754
|
+
totalReasonTokens: number;
|
|
755
|
+
turns: number;
|
|
756
|
+
};
|
|
281
757
|
}) => void;
|
|
282
758
|
}
|
|
@@ -13,6 +13,7 @@ import type {
|
|
|
13
13
|
} from "./types";
|
|
14
14
|
import type { SubagentSandboxShutdown } from "../lifecycle";
|
|
15
15
|
import type { SandboxSnapshot } from "../sandbox/types";
|
|
16
|
+
import type { TokenUsage } from "../types";
|
|
16
17
|
import { childSandboxReadySignal } from "./signals";
|
|
17
18
|
|
|
18
19
|
/**
|
|
@@ -132,6 +133,7 @@ export function defineSubagentWorkflow(
|
|
|
132
133
|
let capturedSnapshot: SandboxSnapshot | undefined;
|
|
133
134
|
let capturedBaseSnapshot: SandboxSnapshot | undefined;
|
|
134
135
|
let capturedThreadId: string | undefined;
|
|
136
|
+
let capturedUsage: TokenUsage | undefined;
|
|
135
137
|
const sessionInput: SubagentSessionInput = {
|
|
136
138
|
agentName: config.name,
|
|
137
139
|
sandboxShutdown: effectiveShutdown,
|
|
@@ -148,10 +150,17 @@ export function defineSubagentWorkflow(
|
|
|
148
150
|
});
|
|
149
151
|
}
|
|
150
152
|
},
|
|
151
|
-
onSessionExit: ({ sandboxId, snapshot, threadId }) => {
|
|
153
|
+
onSessionExit: ({ sandboxId, snapshot, threadId, usage }) => {
|
|
152
154
|
capturedSandboxId = sandboxId;
|
|
153
155
|
capturedSnapshot = snapshot;
|
|
154
156
|
capturedThreadId = threadId;
|
|
157
|
+
capturedUsage = {
|
|
158
|
+
inputTokens: usage.totalInputTokens,
|
|
159
|
+
outputTokens: usage.totalOutputTokens,
|
|
160
|
+
cachedWriteTokens: usage.totalCachedWriteTokens,
|
|
161
|
+
cachedReadTokens: usage.totalCachedReadTokens,
|
|
162
|
+
reasonTokens: usage.totalReasonTokens,
|
|
163
|
+
};
|
|
155
164
|
},
|
|
156
165
|
};
|
|
157
166
|
|
|
@@ -168,6 +177,7 @@ export function defineSubagentWorkflow(
|
|
|
168
177
|
...(capturedBaseSnapshot !== undefined && {
|
|
169
178
|
baseSnapshot: capturedBaseSnapshot,
|
|
170
179
|
}),
|
|
180
|
+
...(capturedUsage !== undefined && { usage: capturedUsage }),
|
|
171
181
|
};
|
|
172
182
|
};
|
|
173
183
|
|