zeitlich 0.2.33 → 0.2.34
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 +17 -6
- package/dist/{activities-fnX8-vhR.d.cts → activities-JOqPfKP0.d.cts} +2 -2
- package/dist/{activities-YBD5BaHh.d.ts → activities-WwMsjRwm.d.ts} +2 -2
- package/dist/adapters/sandbox/bedrock/index.cjs +2 -0
- package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/index.d.cts +4 -3
- package/dist/adapters/sandbox/bedrock/index.d.ts +4 -3
- package/dist/adapters/sandbox/bedrock/index.js +2 -0
- package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.cjs +1 -0
- package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
- package/dist/adapters/sandbox/bedrock/workflow.js +1 -0
- package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
- package/dist/adapters/sandbox/daytona/index.cjs +2 -0
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
- package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
- package/dist/adapters/sandbox/daytona/index.js +2 -0
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.cjs +1 -0
- package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/daytona/workflow.js +1 -0
- package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
- package/dist/adapters/sandbox/e2b/index.cjs +3 -0
- package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/index.d.cts +2 -1
- package/dist/adapters/sandbox/e2b/index.d.ts +2 -1
- package/dist/adapters/sandbox/e2b/index.js +3 -0
- package/dist/adapters/sandbox/e2b/index.js.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.cjs +1 -0
- package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/e2b/workflow.js +1 -0
- package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +2 -0
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +2 -1
- package/dist/adapters/sandbox/inmemory/index.d.ts +2 -1
- package/dist/adapters/sandbox/inmemory/index.js +2 -0
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.cjs +1 -0
- package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/workflow.js +1 -0
- package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
- package/dist/adapters/thread/anthropic/index.d.cts +5 -5
- package/dist/adapters/thread/anthropic/index.d.ts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.d.cts +5 -5
- package/dist/adapters/thread/google-genai/index.d.ts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
- package/dist/adapters/thread/langchain/index.d.cts +5 -5
- package/dist/adapters/thread/langchain/index.d.ts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/index.cjs +114 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -9
- package/dist/index.d.ts +10 -9
- package/dist/index.js +114 -30
- package/dist/index.js.map +1 -1
- package/dist/{proxy-CTCYWjkr.d.cts → proxy-BesT2ioL.d.cts} +1 -1
- package/dist/{proxy-Br4unLTC.d.ts → proxy-Bz6wXYW-.d.ts} +1 -1
- package/dist/{thread-manager-Cv_BR28i.d.cts → thread-manager-CCVAOK8g.d.cts} +1 -1
- package/dist/{thread-manager-CUubPYPH.d.cts → thread-manager-Cf_34H8w.d.cts} +1 -1
- package/dist/{thread-manager-YJLoc1vH.d.ts → thread-manager-ClKAQx78.d.ts} +1 -1
- package/dist/{thread-manager-DKWxHUzD.d.ts → thread-manager-DarJIK_b.d.ts} +1 -1
- package/dist/{types-Bpq5fDI5.d.cts → types-BGLW5Zyj.d.ts} +35 -20
- package/dist/{types-BxiT8w9d.d.ts → types-BVUmLYpj.d.ts} +1 -1
- package/dist/{types-DUvEZSDe.d.cts → types-CBH54cwr.d.cts} +1 -1
- package/dist/{types-NJDyMyUx.d.cts → types-DPAZ3KCs.d.cts} +1 -1
- package/dist/{types-CheCTLeV.d.ts → types-DlLajQcu.d.cts} +35 -20
- package/dist/{types-AujBIMMn.d.cts → types-DxCpFNv_.d.cts} +4 -0
- package/dist/{types-AujBIMMn.d.ts → types-DxCpFNv_.d.ts} +4 -0
- package/dist/{types-DBk-C8zM.d.ts → types-wiGLvxWf.d.ts} +1 -1
- package/dist/{workflow-D9nNERvs.d.ts → workflow-_ZGcacCK.d.ts} +3 -3
- package/dist/{workflow-Od9vx5Jk.d.cts → workflow-hocXpLwg.d.cts} +3 -3
- package/dist/workflow.cjs +108 -30
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3 -3
- package/dist/workflow.d.ts +3 -3
- package/dist/workflow.js +108 -30
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/sandbox/bedrock/index.ts +4 -0
- package/src/adapters/sandbox/bedrock/proxy.ts +1 -0
- package/src/adapters/sandbox/daytona/index.ts +4 -0
- package/src/adapters/sandbox/daytona/proxy.ts +1 -0
- package/src/adapters/sandbox/e2b/index.ts +4 -0
- package/src/adapters/sandbox/e2b/proxy.ts +1 -0
- package/src/adapters/sandbox/inmemory/index.ts +4 -0
- package/src/adapters/sandbox/inmemory/proxy.ts +1 -0
- package/src/lib/lifecycle.ts +7 -3
- package/src/lib/sandbox/manager.ts +7 -0
- package/src/lib/sandbox/types.ts +4 -0
- package/src/lib/session/session-edge-cases.integration.test.ts +194 -0
- package/src/lib/session/session.integration.test.ts +5 -0
- package/src/lib/session/session.ts +9 -0
- package/src/lib/session/types.ts +5 -0
- package/src/lib/subagent/define.ts +1 -1
- package/src/lib/subagent/handler.ts +142 -32
- package/src/lib/subagent/index.ts +5 -1
- package/src/lib/subagent/signals.ts +8 -1
- package/src/lib/subagent/subagent.integration.test.ts +532 -25
- package/src/lib/subagent/types.ts +32 -15
- package/src/lib/subagent/workflow.ts +26 -13
- package/src/lib/virtual-fs/manager.ts +1 -1
- package/src/lib/virtual-fs/types.ts +2 -2
- package/src/lib/virtual-fs/virtual-fs.test.ts +2 -2
|
@@ -22,19 +22,40 @@ import type {
|
|
|
22
22
|
SandboxInit,
|
|
23
23
|
SubagentSandboxShutdown,
|
|
24
24
|
} from "../lifecycle";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
childResultSignal,
|
|
27
|
+
childSandboxReadySignal,
|
|
28
|
+
destroySandboxSignal,
|
|
29
|
+
} from "./signals";
|
|
26
30
|
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
*/
|
|
30
|
-
function resolveSandboxConfig(config?: SubagentSandboxConfig): {
|
|
31
|
+
/** Normalized sandbox config after resolving the union. */
|
|
32
|
+
interface ResolvedSandboxConfig {
|
|
31
33
|
source: "none" | "inherit" | "own";
|
|
34
|
+
init: "per-call" | "once";
|
|
35
|
+
continuation: "continue" | "fork";
|
|
32
36
|
shutdown?: SubagentSandboxShutdown;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function resolveSandboxConfig(
|
|
40
|
+
config?: SubagentSandboxConfig
|
|
41
|
+
): ResolvedSandboxConfig {
|
|
42
|
+
if (!config || config === "none") {
|
|
43
|
+
return { source: "none", init: "per-call", continuation: "fork" };
|
|
44
|
+
}
|
|
45
|
+
if (config.source === "inherit") {
|
|
46
|
+
return {
|
|
47
|
+
source: "inherit",
|
|
48
|
+
init: "per-call",
|
|
49
|
+
continuation: config.continuation,
|
|
50
|
+
shutdown: config.shutdown,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
source: "own",
|
|
55
|
+
init: config.init ?? "per-call",
|
|
56
|
+
continuation: config.continuation,
|
|
57
|
+
shutdown: config.shutdown,
|
|
58
|
+
};
|
|
38
59
|
}
|
|
39
60
|
|
|
40
61
|
/**
|
|
@@ -65,13 +86,30 @@ export function createSubagentHandler<
|
|
|
65
86
|
string,
|
|
66
87
|
Awaited<ReturnType<typeof startChild>>
|
|
67
88
|
>();
|
|
68
|
-
/** Maps childThreadId → sandboxId for sandbox continuation across invocations */
|
|
89
|
+
/** Maps childThreadId → sandboxId for sandbox continuation across invocations (init: per-call) */
|
|
69
90
|
const threadSandboxes = new Map<string, string>();
|
|
91
|
+
/** Maps agentName → sandboxId for persistent sandboxes (init: once) */
|
|
92
|
+
const persistentSandboxes = new Map<string, string>();
|
|
93
|
+
/** Tracks agents whose first lazy sandbox creation is in-flight (guards concurrent init) */
|
|
94
|
+
const persistentSandboxCreating = new Set<string>();
|
|
95
|
+
/** Reverse lookup: childWorkflowId → agentName for in-flight lazy creators */
|
|
96
|
+
const lazyCreatorAgent = new Map<string, string>();
|
|
70
97
|
|
|
71
98
|
setHandler(childResultSignal, ({ childWorkflowId, result }) => {
|
|
72
99
|
childResults.set(childWorkflowId, result);
|
|
73
100
|
});
|
|
74
101
|
|
|
102
|
+
setHandler(
|
|
103
|
+
childSandboxReadySignal,
|
|
104
|
+
({ childWorkflowId, sandboxId }) => {
|
|
105
|
+
const agentName = lazyCreatorAgent.get(childWorkflowId);
|
|
106
|
+
if (agentName && !persistentSandboxes.has(agentName)) {
|
|
107
|
+
persistentSandboxes.set(agentName, sandboxId);
|
|
108
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
|
|
75
113
|
const handler = async (
|
|
76
114
|
args: SubagentArgs,
|
|
77
115
|
context: RouterContext
|
|
@@ -111,25 +149,74 @@ export function createSubagentHandler<
|
|
|
111
149
|
|
|
112
150
|
// --- Build sandbox init ---
|
|
113
151
|
let sandbox: SandboxInit | undefined;
|
|
152
|
+
let sandboxShutdownOverride: SubagentSandboxShutdown | undefined;
|
|
153
|
+
let isLazyCreator = false;
|
|
154
|
+
|
|
114
155
|
if (sandboxCfg.source === "inherit" && parentSandboxId) {
|
|
115
|
-
|
|
116
|
-
mode: "
|
|
117
|
-
|
|
118
|
-
|
|
156
|
+
if (sandboxCfg.continuation === "fork") {
|
|
157
|
+
sandbox = { mode: "fork", sandboxId: parentSandboxId };
|
|
158
|
+
} else {
|
|
159
|
+
sandbox = { mode: "inherit", sandboxId: parentSandboxId };
|
|
160
|
+
}
|
|
119
161
|
} else if (sandboxCfg.source === "own") {
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
if (
|
|
124
|
-
|
|
162
|
+
const isLazy = sandboxCfg.init === "once";
|
|
163
|
+
|
|
164
|
+
let baseSandboxId: string | undefined;
|
|
165
|
+
if (isLazy) {
|
|
166
|
+
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
167
|
+
if (!baseSandboxId) {
|
|
168
|
+
if (persistentSandboxCreating.has(config.agentName)) {
|
|
169
|
+
// Another call is already creating — wait for it to finish
|
|
170
|
+
await condition(() => persistentSandboxes.has(config.agentName));
|
|
171
|
+
baseSandboxId = persistentSandboxes.get(config.agentName);
|
|
172
|
+
} else {
|
|
173
|
+
// We're the first concurrent caller — claim the creator role
|
|
174
|
+
persistentSandboxCreating.add(config.agentName);
|
|
175
|
+
isLazyCreator = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
} else if (continuationThreadId) {
|
|
179
|
+
baseSandboxId = threadSandboxes.get(continuationThreadId);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (baseSandboxId) {
|
|
183
|
+
sandbox = {
|
|
184
|
+
mode: sandboxCfg.continuation === "continue" ? "continue" : "fork",
|
|
185
|
+
sandboxId: baseSandboxId,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Ensure the sandbox survives for future continuation/fork:
|
|
190
|
+
// - first lazy call (creator): pause-until-parent-close so parent can clean up
|
|
191
|
+
// - continuation=continue: sandbox must survive for next call
|
|
192
|
+
// - lazy+fork (non-creator): template must survive for future forks
|
|
193
|
+
//
|
|
194
|
+
// Skip the override when the user already configured a *-until-parent-close
|
|
195
|
+
// shutdown — that already guarantees survival.
|
|
196
|
+
const userShutdown = sandboxCfg.shutdown;
|
|
197
|
+
const alreadySurvives =
|
|
198
|
+
userShutdown === "pause-until-parent-close" ||
|
|
199
|
+
userShutdown === "keep-until-parent-close" ||
|
|
200
|
+
userShutdown === "pause" ||
|
|
201
|
+
userShutdown === "keep";
|
|
202
|
+
|
|
203
|
+
const mustSurvive =
|
|
204
|
+
isLazyCreator ||
|
|
205
|
+
sandboxCfg.continuation === "continue" ||
|
|
206
|
+
(isLazy && sandboxCfg.continuation === "fork");
|
|
207
|
+
|
|
208
|
+
if (mustSurvive && !alreadySurvives) {
|
|
209
|
+
sandboxShutdownOverride = isLazyCreator
|
|
210
|
+
? "pause-until-parent-close"
|
|
211
|
+
: "pause";
|
|
125
212
|
}
|
|
126
|
-
// When no previous sandbox, omit — the child will create its own via sandboxOps
|
|
127
213
|
}
|
|
128
214
|
|
|
129
215
|
const workflowInput: SubagentWorkflowInput = {
|
|
130
216
|
...(thread && { thread }),
|
|
131
217
|
...(sandbox && { sandbox }),
|
|
132
|
-
|
|
218
|
+
sandboxShutdown:
|
|
219
|
+
sandboxShutdownOverride ?? sandboxCfg.shutdown ?? undefined,
|
|
133
220
|
};
|
|
134
221
|
|
|
135
222
|
const resolvedContext =
|
|
@@ -148,6 +235,10 @@ export function createSubagentHandler<
|
|
|
148
235
|
taskQueue: config.taskQueue ?? parentTaskQueue,
|
|
149
236
|
};
|
|
150
237
|
|
|
238
|
+
if (isLazyCreator) {
|
|
239
|
+
lazyCreatorAgent.set(childWorkflowId, config.agentName);
|
|
240
|
+
}
|
|
241
|
+
|
|
151
242
|
log.info("subagent spawned", {
|
|
152
243
|
subagent: config.agentName,
|
|
153
244
|
childWorkflowId,
|
|
@@ -157,14 +248,18 @@ export function createSubagentHandler<
|
|
|
157
248
|
|
|
158
249
|
const childHandle = await startChild(config.workflow, childOpts);
|
|
159
250
|
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
251
|
+
// Track child handles that need signaling at parent shutdown.
|
|
252
|
+
const effectiveShutdown =
|
|
253
|
+
sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
|
|
254
|
+
|
|
255
|
+
if (
|
|
256
|
+
effectiveShutdown === "pause-until-parent-close" ||
|
|
257
|
+
effectiveShutdown === "keep-until-parent-close"
|
|
258
|
+
) {
|
|
259
|
+
const key = isLazyCreator
|
|
260
|
+
? `persistent:${config.agentName}`
|
|
261
|
+
: childWorkflowId;
|
|
262
|
+
pendingDestroys.set(key, childHandle);
|
|
168
263
|
}
|
|
169
264
|
|
|
170
265
|
// Wait for signal from child; race with child completion to propagate failures
|
|
@@ -205,8 +300,23 @@ export function createSubagentHandler<
|
|
|
205
300
|
metadata,
|
|
206
301
|
} = childResult;
|
|
207
302
|
|
|
208
|
-
|
|
209
|
-
|
|
303
|
+
// Store sandbox ID for future continuation/fork
|
|
304
|
+
if (childSandboxId) {
|
|
305
|
+
if (
|
|
306
|
+
sandboxCfg.source === "own" &&
|
|
307
|
+
sandboxCfg.init === "once" &&
|
|
308
|
+
!persistentSandboxes.has(config.agentName)
|
|
309
|
+
) {
|
|
310
|
+
// Fallback: signal may have already set this via childSandboxReadySignal
|
|
311
|
+
persistentSandboxes.set(config.agentName, childSandboxId);
|
|
312
|
+
} else if (allowsContinuation && childThreadId) {
|
|
313
|
+
threadSandboxes.set(childThreadId, childSandboxId);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (isLazyCreator) {
|
|
318
|
+
persistentSandboxCreating.delete(config.agentName);
|
|
319
|
+
lazyCreatorAgent.delete(childWorkflowId);
|
|
210
320
|
}
|
|
211
321
|
|
|
212
322
|
if (!toolResponse) {
|
|
@@ -17,4 +17,8 @@ export { createSubagentHandler } from "./handler";
|
|
|
17
17
|
export { defineSubagent } from "./define";
|
|
18
18
|
export { defineSubagentWorkflow } from "./workflow";
|
|
19
19
|
export { buildSubagentRegistration } from "./register";
|
|
20
|
-
export {
|
|
20
|
+
export {
|
|
21
|
+
childResultSignal,
|
|
22
|
+
childSandboxReadySignal,
|
|
23
|
+
destroySandboxSignal,
|
|
24
|
+
} from "./signals";
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { defineSignal } from "@temporalio/workflow";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
ChildResultSignalPayload,
|
|
4
|
+
ChildSandboxReadySignalPayload,
|
|
5
|
+
} from "./types";
|
|
3
6
|
|
|
4
7
|
export const childResultSignal =
|
|
5
8
|
defineSignal<[ChildResultSignalPayload]>("childResult");
|
|
6
9
|
|
|
10
|
+
/** Sent by a child workflow as soon as its sandbox is created, before the agent loop starts. */
|
|
11
|
+
export const childSandboxReadySignal =
|
|
12
|
+
defineSignal<[ChildSandboxReadySignalPayload]>("childSandboxReady");
|
|
13
|
+
|
|
7
14
|
/** Sent by the parent to tell a subagent it may destroy its sandbox. */
|
|
8
15
|
export const destroySandboxSignal = defineSignal("destroySandbox");
|