zeitlich 0.2.33 → 0.2.35

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.
Files changed (141) hide show
  1. package/README.md +17 -6
  2. package/dist/{activities-YBD5BaHh.d.ts → activities-BVI2lTwr.d.ts} +6 -4
  3. package/dist/{activities-fnX8-vhR.d.cts → activities-hd4aNnZE.d.cts} +6 -4
  4. package/dist/adapters/sandbox/bedrock/index.cjs +2 -0
  5. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
  6. package/dist/adapters/sandbox/bedrock/index.d.cts +4 -3
  7. package/dist/adapters/sandbox/bedrock/index.d.ts +4 -3
  8. package/dist/adapters/sandbox/bedrock/index.js +2 -0
  9. package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
  10. package/dist/adapters/sandbox/bedrock/workflow.cjs +1 -0
  11. package/dist/adapters/sandbox/bedrock/workflow.cjs.map +1 -1
  12. package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
  13. package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
  14. package/dist/adapters/sandbox/bedrock/workflow.js +1 -0
  15. package/dist/adapters/sandbox/bedrock/workflow.js.map +1 -1
  16. package/dist/adapters/sandbox/daytona/index.cjs +2 -0
  17. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  18. package/dist/adapters/sandbox/daytona/index.d.cts +2 -1
  19. package/dist/adapters/sandbox/daytona/index.d.ts +2 -1
  20. package/dist/adapters/sandbox/daytona/index.js +2 -0
  21. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  22. package/dist/adapters/sandbox/daytona/workflow.cjs +1 -0
  23. package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -1
  24. package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
  25. package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
  26. package/dist/adapters/sandbox/daytona/workflow.js +1 -0
  27. package/dist/adapters/sandbox/daytona/workflow.js.map +1 -1
  28. package/dist/adapters/sandbox/e2b/index.cjs +3 -0
  29. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  30. package/dist/adapters/sandbox/e2b/index.d.cts +2 -1
  31. package/dist/adapters/sandbox/e2b/index.d.ts +2 -1
  32. package/dist/adapters/sandbox/e2b/index.js +3 -0
  33. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  34. package/dist/adapters/sandbox/e2b/workflow.cjs +1 -0
  35. package/dist/adapters/sandbox/e2b/workflow.cjs.map +1 -1
  36. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  37. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  38. package/dist/adapters/sandbox/e2b/workflow.js +1 -0
  39. package/dist/adapters/sandbox/e2b/workflow.js.map +1 -1
  40. package/dist/adapters/sandbox/inmemory/index.cjs +2 -0
  41. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  42. package/dist/adapters/sandbox/inmemory/index.d.cts +2 -1
  43. package/dist/adapters/sandbox/inmemory/index.d.ts +2 -1
  44. package/dist/adapters/sandbox/inmemory/index.js +2 -0
  45. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  46. package/dist/adapters/sandbox/inmemory/workflow.cjs +1 -0
  47. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -1
  48. package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
  49. package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
  50. package/dist/adapters/sandbox/inmemory/workflow.js +1 -0
  51. package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -1
  52. package/dist/adapters/thread/anthropic/index.cjs +7 -2
  53. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  54. package/dist/adapters/thread/anthropic/index.d.cts +5 -5
  55. package/dist/adapters/thread/anthropic/index.d.ts +5 -5
  56. package/dist/adapters/thread/anthropic/index.js +7 -2
  57. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  58. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
  59. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
  60. package/dist/adapters/thread/google-genai/index.cjs +4 -3
  61. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  62. package/dist/adapters/thread/google-genai/index.d.cts +5 -5
  63. package/dist/adapters/thread/google-genai/index.d.ts +5 -5
  64. package/dist/adapters/thread/google-genai/index.js +4 -3
  65. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  66. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
  67. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
  68. package/dist/adapters/thread/langchain/index.cjs +4 -1
  69. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  70. package/dist/adapters/thread/langchain/index.d.cts +5 -5
  71. package/dist/adapters/thread/langchain/index.d.ts +5 -5
  72. package/dist/adapters/thread/langchain/index.js +4 -1
  73. package/dist/adapters/thread/langchain/index.js.map +1 -1
  74. package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
  75. package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
  76. package/dist/index.cjs +115 -31
  77. package/dist/index.cjs.map +1 -1
  78. package/dist/index.d.cts +10 -9
  79. package/dist/index.d.ts +10 -9
  80. package/dist/index.js +115 -31
  81. package/dist/index.js.map +1 -1
  82. package/dist/{proxy-CTCYWjkr.d.cts → proxy-7RnVaPdJ.d.cts} +1 -1
  83. package/dist/{proxy-Br4unLTC.d.ts → proxy-BjdFGPTm.d.ts} +1 -1
  84. package/dist/{thread-manager-DKWxHUzD.d.ts → thread-manager-BBzNgQWH.d.cts} +5 -2
  85. package/dist/{thread-manager-CUubPYPH.d.cts → thread-manager-CbpiGq1L.d.ts} +6 -3
  86. package/dist/{thread-manager-Cv_BR28i.d.cts → thread-manager-DjN5JYul.d.ts} +5 -2
  87. package/dist/{thread-manager-YJLoc1vH.d.ts → thread-manager-DzXm9eeI.d.cts} +6 -3
  88. package/dist/{types-Bpq5fDI5.d.cts → types-CADc5V_P.d.ts} +39 -24
  89. package/dist/{types-DUvEZSDe.d.cts → types-CBH54cwr.d.cts} +1 -1
  90. package/dist/{types-CheCTLeV.d.ts → types-DQ1l_gXL.d.cts} +39 -24
  91. package/dist/{types-AujBIMMn.d.cts → types-DxCpFNv_.d.cts} +4 -0
  92. package/dist/{types-AujBIMMn.d.ts → types-DxCpFNv_.d.ts} +4 -0
  93. package/dist/{types-NJDyMyUx.d.cts → types-Mc_4BCfT.d.cts} +3 -3
  94. package/dist/{types-DBk-C8zM.d.ts → types-wiGLvxWf.d.ts} +1 -1
  95. package/dist/{types-BxiT8w9d.d.ts → types-yiXmqedU.d.ts} +3 -3
  96. package/dist/{workflow-Od9vx5Jk.d.cts → workflow-DhtWRovz.d.cts} +3 -3
  97. package/dist/{workflow-D9nNERvs.d.ts → workflow-P2pTSfKu.d.ts} +3 -3
  98. package/dist/workflow.cjs +109 -31
  99. package/dist/workflow.cjs.map +1 -1
  100. package/dist/workflow.d.cts +3 -3
  101. package/dist/workflow.d.ts +3 -3
  102. package/dist/workflow.js +109 -31
  103. package/dist/workflow.js.map +1 -1
  104. package/package.json +1 -1
  105. package/src/adapters/sandbox/bedrock/index.ts +4 -0
  106. package/src/adapters/sandbox/bedrock/proxy.ts +1 -0
  107. package/src/adapters/sandbox/daytona/index.ts +4 -0
  108. package/src/adapters/sandbox/daytona/proxy.ts +1 -0
  109. package/src/adapters/sandbox/e2b/index.ts +4 -0
  110. package/src/adapters/sandbox/e2b/proxy.ts +1 -0
  111. package/src/adapters/sandbox/inmemory/index.ts +4 -0
  112. package/src/adapters/sandbox/inmemory/proxy.ts +1 -0
  113. package/src/adapters/thread/anthropic/activities.ts +2 -1
  114. package/src/adapters/thread/anthropic/thread-manager.ts +21 -9
  115. package/src/adapters/thread/google-genai/activities.ts +2 -1
  116. package/src/adapters/thread/google-genai/thread-manager.test.ts +1 -1
  117. package/src/adapters/thread/google-genai/thread-manager.ts +15 -7
  118. package/src/adapters/thread/langchain/activities.ts +2 -1
  119. package/src/adapters/thread/langchain/thread-manager.ts +12 -3
  120. package/src/lib/lifecycle.ts +7 -3
  121. package/src/lib/sandbox/manager.ts +7 -0
  122. package/src/lib/sandbox/types.ts +4 -0
  123. package/src/lib/session/session-edge-cases.integration.test.ts +194 -0
  124. package/src/lib/session/session.integration.test.ts +5 -0
  125. package/src/lib/session/session.ts +13 -1
  126. package/src/lib/session/types.ts +10 -2
  127. package/src/lib/state/manager.ts +2 -2
  128. package/src/lib/state/types.ts +2 -2
  129. package/src/lib/subagent/define.ts +1 -1
  130. package/src/lib/subagent/handler.ts +142 -32
  131. package/src/lib/subagent/index.ts +5 -1
  132. package/src/lib/subagent/signals.ts +8 -1
  133. package/src/lib/subagent/subagent.integration.test.ts +532 -25
  134. package/src/lib/subagent/types.ts +32 -15
  135. package/src/lib/subagent/workflow.ts +26 -13
  136. package/src/lib/thread/types.ts +2 -2
  137. package/src/lib/types.ts +1 -1
  138. package/src/lib/virtual-fs/manager.ts +1 -1
  139. package/src/lib/virtual-fs/types.ts +2 -2
  140. package/src/lib/virtual-fs/virtual-fs.test.ts +2 -2
  141. package/src/workflow.ts +0 -1
package/dist/workflow.cjs CHANGED
@@ -392,23 +392,50 @@ function createSubagentTool(subagents) {
392
392
  };
393
393
  }
394
394
  var childResultSignal = workflow.defineSignal("childResult");
395
+ var childSandboxReadySignal = workflow.defineSignal("childSandboxReady");
395
396
  var destroySandboxSignal = workflow.defineSignal("destroySandbox");
396
397
 
397
398
  // src/lib/subagent/handler.ts
398
399
  function resolveSandboxConfig(config) {
399
- if (!config || config === "none") return { source: "none" };
400
- if (config === "inherit") return { source: "inherit" };
401
- if (config === "own") return { source: "own" };
402
- return { source: "own", shutdown: config.shutdown };
400
+ if (!config || config === "none") {
401
+ return { source: "none", init: "per-call", continuation: "fork" };
402
+ }
403
+ if (config.source === "inherit") {
404
+ return {
405
+ source: "inherit",
406
+ init: "per-call",
407
+ continuation: config.continuation,
408
+ shutdown: config.shutdown
409
+ };
410
+ }
411
+ return {
412
+ source: "own",
413
+ init: config.init ?? "per-call",
414
+ continuation: config.continuation,
415
+ shutdown: config.shutdown
416
+ };
403
417
  }
404
418
  function createSubagentHandler(subagents) {
405
419
  const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
406
420
  const childResults = /* @__PURE__ */ new Map();
407
421
  const pendingDestroys = /* @__PURE__ */ new Map();
408
422
  const threadSandboxes = /* @__PURE__ */ new Map();
423
+ const persistentSandboxes = /* @__PURE__ */ new Map();
424
+ const persistentSandboxCreating = /* @__PURE__ */ new Set();
425
+ const lazyCreatorAgent = /* @__PURE__ */ new Map();
409
426
  workflow.setHandler(childResultSignal, ({ childWorkflowId, result }) => {
410
427
  childResults.set(childWorkflowId, result);
411
428
  });
429
+ workflow.setHandler(
430
+ childSandboxReadySignal,
431
+ ({ childWorkflowId, sandboxId }) => {
432
+ const agentName = lazyCreatorAgent.get(childWorkflowId);
433
+ if (agentName && !persistentSandboxes.has(agentName)) {
434
+ persistentSandboxes.set(agentName, sandboxId);
435
+ lazyCreatorAgent.delete(childWorkflowId);
436
+ }
437
+ }
438
+ );
412
439
  const handler = async (args, context) => {
413
440
  const config = subagents.find((s) => s.agentName === args.subagent);
414
441
  if (!config) {
@@ -435,21 +462,48 @@ function createSubagentHandler(subagents) {
435
462
  };
436
463
  }
437
464
  let sandbox;
465
+ let sandboxShutdownOverride;
466
+ let isLazyCreator = false;
438
467
  if (sandboxCfg.source === "inherit" && parentSandboxId) {
439
- sandbox = {
440
- mode: "inherit",
441
- sandboxId: parentSandboxId
442
- };
468
+ if (sandboxCfg.continuation === "fork") {
469
+ sandbox = { mode: "fork", sandboxId: parentSandboxId };
470
+ } else {
471
+ sandbox = { mode: "inherit", sandboxId: parentSandboxId };
472
+ }
443
473
  } else if (sandboxCfg.source === "own") {
444
- const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
445
- if (prevSbId) {
446
- sandbox = { mode: "fork", sandboxId: prevSbId };
474
+ const isLazy = sandboxCfg.init === "once";
475
+ let baseSandboxId;
476
+ if (isLazy) {
477
+ baseSandboxId = persistentSandboxes.get(config.agentName);
478
+ if (!baseSandboxId) {
479
+ if (persistentSandboxCreating.has(config.agentName)) {
480
+ await workflow.condition(() => persistentSandboxes.has(config.agentName));
481
+ baseSandboxId = persistentSandboxes.get(config.agentName);
482
+ } else {
483
+ persistentSandboxCreating.add(config.agentName);
484
+ isLazyCreator = true;
485
+ }
486
+ }
487
+ } else if (continuationThreadId) {
488
+ baseSandboxId = threadSandboxes.get(continuationThreadId);
489
+ }
490
+ if (baseSandboxId) {
491
+ sandbox = {
492
+ mode: sandboxCfg.continuation === "continue" ? "continue" : "fork",
493
+ sandboxId: baseSandboxId
494
+ };
495
+ }
496
+ const userShutdown = sandboxCfg.shutdown;
497
+ const alreadySurvives = userShutdown === "pause-until-parent-close" || userShutdown === "keep-until-parent-close" || userShutdown === "pause" || userShutdown === "keep";
498
+ const mustSurvive = isLazyCreator || sandboxCfg.continuation === "continue" || isLazy && sandboxCfg.continuation === "fork";
499
+ if (mustSurvive && !alreadySurvives) {
500
+ sandboxShutdownOverride = isLazyCreator ? "pause-until-parent-close" : "pause";
447
501
  }
448
502
  }
449
503
  const workflowInput = {
450
504
  ...thread && { thread },
451
505
  ...sandbox && { sandbox },
452
- ...sandboxCfg.shutdown && { sandboxShutdown: sandboxCfg.shutdown }
506
+ sandboxShutdown: sandboxShutdownOverride ?? sandboxCfg.shutdown ?? void 0
453
507
  };
454
508
  const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
455
509
  const childOpts = {
@@ -457,6 +511,9 @@ function createSubagentHandler(subagents) {
457
511
  args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
458
512
  taskQueue: config.taskQueue ?? parentTaskQueue
459
513
  };
514
+ if (isLazyCreator) {
515
+ lazyCreatorAgent.set(childWorkflowId, config.agentName);
516
+ }
460
517
  workflow.log.info("subagent spawned", {
461
518
  subagent: config.agentName,
462
519
  childWorkflowId,
@@ -464,10 +521,10 @@ function createSubagentHandler(subagents) {
464
521
  sandboxSource: sandboxCfg.source
465
522
  });
466
523
  const childHandle = await workflow.startChild(config.workflow, childOpts);
467
- const effectiveShutdown = sandboxCfg.shutdown ?? "destroy";
468
- const shouldDeferDestroy = effectiveShutdown === "pause-until-parent-close" && (sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit");
469
- if (shouldDeferDestroy) {
470
- pendingDestroys.set(childWorkflowId, childHandle);
524
+ const effectiveShutdown = sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
525
+ if (effectiveShutdown === "pause-until-parent-close" || effectiveShutdown === "keep-until-parent-close") {
526
+ const key = isLazyCreator ? `persistent:${config.agentName}` : childWorkflowId;
527
+ pendingDestroys.set(key, childHandle);
471
528
  }
472
529
  await Promise.race([
473
530
  workflow.condition(() => childResults.has(childWorkflowId)),
@@ -501,8 +558,16 @@ function createSubagentHandler(subagents) {
501
558
  sandboxId: childSandboxId,
502
559
  metadata
503
560
  } = childResult;
504
- if (allowsContinuation && childSandboxId && childThreadId) {
505
- threadSandboxes.set(childThreadId, childSandboxId);
561
+ if (childSandboxId) {
562
+ if (sandboxCfg.source === "own" && sandboxCfg.init === "once" && !persistentSandboxes.has(config.agentName)) {
563
+ persistentSandboxes.set(config.agentName, childSandboxId);
564
+ } else if (allowsContinuation && childThreadId) {
565
+ threadSandboxes.set(childThreadId, childSandboxId);
566
+ }
567
+ }
568
+ if (isLazyCreator) {
569
+ persistentSandboxCreating.delete(config.agentName);
570
+ lazyCreatorAgent.delete(childWorkflowId);
506
571
  }
507
572
  if (!toolResponse) {
508
573
  return {
@@ -708,6 +773,7 @@ async function createSession({
708
773
  thread: threadInit,
709
774
  sandbox: sandboxInit,
710
775
  sandboxShutdown = "destroy",
776
+ onSandboxReady,
711
777
  virtualFs: virtualFsConfig,
712
778
  virtualFsOps
713
779
  }) {
@@ -810,6 +876,9 @@ async function createSession({
810
876
  });
811
877
  }
812
878
  sandboxId = sandboxInit.sandboxId;
879
+ if (sandboxShutdown === "pause-until-parent-close") {
880
+ await sandboxOps.resumeSandbox(sandboxId);
881
+ }
813
882
  sandboxOwned = true;
814
883
  } else if (sandboxMode === "fork") {
815
884
  if (!sandboxOps) {
@@ -832,6 +901,9 @@ async function createSession({
832
901
  sandboxOwned = true;
833
902
  }
834
903
  }
904
+ if (sandboxId && onSandboxReady) {
905
+ onSandboxReady(sandboxId);
906
+ }
835
907
  if (virtualFsConfig) {
836
908
  if (!virtualFsOps) {
837
909
  throw workflow.ApplicationFailure.create({
@@ -877,7 +949,7 @@ async function createSession({
877
949
  await forkThread(sourceThreadId, threadId, threadKey);
878
950
  } else if (threadMode === "continue") ; else {
879
951
  if (appendSystemPrompt) {
880
- if (!systemPrompt || systemPrompt.trim() === "") {
952
+ if (systemPrompt == null || typeof systemPrompt === "string" && systemPrompt.trim() === "") {
881
953
  throw workflow.ApplicationFailure.create({
882
954
  message: "No system prompt in state",
883
955
  nonRetryable: true
@@ -1223,39 +1295,45 @@ function defineSubagent(definition, overrides) {
1223
1295
  function defineSubagentWorkflow(config, fn) {
1224
1296
  const workflow$1 = async (prompt, workflowInput, context) => {
1225
1297
  const effectiveShutdown = workflowInput.sandboxShutdown ?? config.sandboxShutdown ?? "destroy";
1298
+ const { parent } = workflow.workflowInfo();
1299
+ if (!parent) {
1300
+ throw workflow.ApplicationFailure.create({
1301
+ message: "Subagent workflow called without a parent workflow",
1302
+ nonRetryable: true
1303
+ });
1304
+ }
1305
+ const parentHandle = workflow.getExternalWorkflowHandle(parent.workflowId);
1226
1306
  const sessionInput = {
1227
1307
  agentName: config.name,
1228
1308
  sandboxShutdown: effectiveShutdown,
1229
1309
  ...workflowInput.thread && { thread: workflowInput.thread },
1230
- ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
1310
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox },
1311
+ onSandboxReady: (sandboxId) => {
1312
+ void parentHandle.signal(childSandboxReadySignal, {
1313
+ childWorkflowId: workflow.workflowInfo().workflowId,
1314
+ sandboxId
1315
+ });
1316
+ }
1231
1317
  };
1232
1318
  const { destroySandbox, ...result } = await fn(
1233
1319
  prompt,
1234
1320
  sessionInput,
1235
1321
  context ?? {}
1236
1322
  );
1237
- if (effectiveShutdown === "pause-until-parent-close") {
1323
+ if (effectiveShutdown === "pause-until-parent-close" || effectiveShutdown === "keep-until-parent-close") {
1238
1324
  if (!destroySandbox) {
1239
1325
  throw workflow.ApplicationFailure.create({
1240
- message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a destroySandbox callback`,
1326
+ message: `Subagent "${config.name}" has sandboxShutdown="${effectiveShutdown}" but fn did not return a destroySandbox callback`,
1241
1327
  nonRetryable: true
1242
1328
  });
1243
1329
  }
1244
1330
  if (!result.sandboxId) {
1245
1331
  throw workflow.ApplicationFailure.create({
1246
- message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a sandboxId`,
1332
+ message: `Subagent "${config.name}" has sandboxShutdown="${effectiveShutdown}" but fn did not return a sandboxId`,
1247
1333
  nonRetryable: true
1248
1334
  });
1249
1335
  }
1250
1336
  }
1251
- const { parent } = workflow.workflowInfo();
1252
- if (!parent) {
1253
- throw workflow.ApplicationFailure.create({
1254
- message: "Subagent workflow called without a parent workflow",
1255
- nonRetryable: true
1256
- });
1257
- }
1258
- const parentHandle = workflow.getExternalWorkflowHandle(parent.workflowId);
1259
1337
  await parentHandle.signal(childResultSignal, {
1260
1338
  childWorkflowId: workflow.workflowInfo().workflowId,
1261
1339
  result