zeitlich 0.2.38 → 0.2.40

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 (125) hide show
  1. package/README.md +18 -0
  2. package/dist/{activities-BKhMtKDd.d.ts → activities-CULxRzJ1.d.ts} +4 -6
  3. package/dist/{activities-CDcwkRZs.d.cts → activities-CvUrG3YG.d.cts} +4 -6
  4. package/dist/adapter-id-BB-mmrts.d.cts +17 -0
  5. package/dist/adapter-id-BB-mmrts.d.ts +17 -0
  6. package/dist/adapter-id-CMwVrVqv.d.cts +17 -0
  7. package/dist/adapter-id-CMwVrVqv.d.ts +17 -0
  8. package/dist/adapter-id-CbY2zeSt.d.cts +17 -0
  9. package/dist/adapter-id-CbY2zeSt.d.ts +17 -0
  10. package/dist/adapters/thread/anthropic/index.cjs +140 -23
  11. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/index.d.cts +8 -7
  13. package/dist/adapters/thread/anthropic/index.d.ts +8 -7
  14. package/dist/adapters/thread/anthropic/index.js +140 -24
  15. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  16. package/dist/adapters/thread/anthropic/workflow.cjs +8 -3
  17. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  18. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
  19. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
  20. package/dist/adapters/thread/anthropic/workflow.js +8 -4
  21. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  22. package/dist/adapters/thread/google-genai/index.cjs +140 -23
  23. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  24. package/dist/adapters/thread/google-genai/index.d.cts +5 -4
  25. package/dist/adapters/thread/google-genai/index.d.ts +5 -4
  26. package/dist/adapters/thread/google-genai/index.js +140 -24
  27. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  28. package/dist/adapters/thread/google-genai/workflow.cjs +8 -3
  29. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  30. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
  31. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
  32. package/dist/adapters/thread/google-genai/workflow.js +8 -4
  33. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  34. package/dist/adapters/thread/index.cjs +16 -0
  35. package/dist/adapters/thread/index.cjs.map +1 -0
  36. package/dist/adapters/thread/index.d.cts +34 -0
  37. package/dist/adapters/thread/index.d.ts +34 -0
  38. package/dist/adapters/thread/index.js +12 -0
  39. package/dist/adapters/thread/index.js.map +1 -0
  40. package/dist/adapters/thread/langchain/index.cjs +139 -24
  41. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  42. package/dist/adapters/thread/langchain/index.d.cts +8 -7
  43. package/dist/adapters/thread/langchain/index.d.ts +8 -7
  44. package/dist/adapters/thread/langchain/index.js +139 -25
  45. package/dist/adapters/thread/langchain/index.js.map +1 -1
  46. package/dist/adapters/thread/langchain/workflow.cjs +8 -3
  47. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  48. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  49. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  50. package/dist/adapters/thread/langchain/workflow.js +8 -4
  51. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  52. package/dist/index.cjs +267 -48
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.d.cts +6 -6
  55. package/dist/index.d.ts +6 -6
  56. package/dist/index.js +264 -49
  57. package/dist/index.js.map +1 -1
  58. package/dist/{proxy-D_3x7RN4.d.cts → proxy-5EbwzaY4.d.cts} +1 -1
  59. package/dist/{proxy-CUlKSvZS.d.ts → proxy-wZufFfBh.d.ts} +1 -1
  60. package/dist/{thread-manager-CVu7o2cs.d.ts → thread-manager-BNiIt5r8.d.ts} +2 -4
  61. package/dist/{thread-manager-c1gPopAG.d.ts → thread-manager-BoN5DOvG.d.cts} +2 -4
  62. package/dist/{thread-manager-wGi-LqIP.d.cts → thread-manager-BqBAIsED.d.ts} +2 -4
  63. package/dist/{thread-manager-HSwyh28L.d.cts → thread-manager-DF8WuCRs.d.cts} +2 -4
  64. package/dist/{types-BH_IRryz.d.ts → types-C7OoY7h8.d.ts} +54 -6
  65. package/dist/{types-C06FwR96.d.cts → types-Cn2r3ol3.d.cts} +163 -44
  66. package/dist/{types-BaOw4hKI.d.cts → types-CuISs0Ub.d.cts} +54 -6
  67. package/dist/{types-DNr31FzL.d.ts → types-DeQH84C_.d.ts} +163 -44
  68. package/dist/{workflow-CSCkpwAL.d.ts → workflow-C2MZZj5K.d.ts} +82 -2
  69. package/dist/{workflow-DuvMZ8Vm.d.cts → workflow-DhplIN65.d.cts} +82 -2
  70. package/dist/workflow.cjs +189 -37
  71. package/dist/workflow.cjs.map +1 -1
  72. package/dist/workflow.d.cts +2 -2
  73. package/dist/workflow.d.ts +2 -2
  74. package/dist/workflow.js +186 -38
  75. package/dist/workflow.js.map +1 -1
  76. package/package.json +11 -1
  77. package/src/adapters/thread/adapter-id.test.ts +42 -0
  78. package/src/adapters/thread/anthropic/activities.ts +33 -7
  79. package/src/adapters/thread/anthropic/adapter-id.ts +16 -0
  80. package/src/adapters/thread/anthropic/fork-transform.test.ts +291 -0
  81. package/src/adapters/thread/anthropic/index.ts +3 -0
  82. package/src/adapters/thread/anthropic/model-invoker.ts +8 -4
  83. package/src/adapters/thread/anthropic/proxy.ts +3 -2
  84. package/src/adapters/thread/anthropic/thread-manager.ts +27 -4
  85. package/src/adapters/thread/google-genai/activities.ts +33 -7
  86. package/src/adapters/thread/google-genai/adapter-id.ts +16 -0
  87. package/src/adapters/thread/google-genai/fork-transform.test.ts +149 -0
  88. package/src/adapters/thread/google-genai/index.ts +3 -0
  89. package/src/adapters/thread/google-genai/model-invoker.ts +7 -3
  90. package/src/adapters/thread/google-genai/proxy.ts +3 -2
  91. package/src/adapters/thread/google-genai/thread-manager.ts +27 -4
  92. package/src/adapters/thread/index.ts +39 -0
  93. package/src/adapters/thread/langchain/activities.ts +33 -7
  94. package/src/adapters/thread/langchain/adapter-id.ts +16 -0
  95. package/src/adapters/thread/langchain/fork-transform.test.ts +142 -0
  96. package/src/adapters/thread/langchain/index.ts +3 -0
  97. package/src/adapters/thread/langchain/model-invoker.ts +8 -3
  98. package/src/adapters/thread/langchain/proxy.ts +3 -2
  99. package/src/adapters/thread/langchain/thread-manager.ts +27 -4
  100. package/src/lib/lifecycle.ts +3 -1
  101. package/src/lib/model/types.ts +7 -10
  102. package/src/lib/session/session-edge-cases.integration.test.ts +131 -63
  103. package/src/lib/session/session.integration.test.ts +174 -5
  104. package/src/lib/session/session.ts +69 -28
  105. package/src/lib/session/types.ts +61 -9
  106. package/src/lib/state/index.ts +1 -0
  107. package/src/lib/state/manager.integration.test.ts +109 -0
  108. package/src/lib/state/manager.ts +38 -8
  109. package/src/lib/state/types.ts +25 -0
  110. package/src/lib/subagent/handler.ts +124 -11
  111. package/src/lib/subagent/index.ts +5 -1
  112. package/src/lib/subagent/subagent.integration.test.ts +528 -0
  113. package/src/lib/subagent/types.ts +63 -14
  114. package/src/lib/subagent/workflow.ts +29 -2
  115. package/src/lib/thread/index.ts +5 -0
  116. package/src/lib/thread/keys.test.ts +101 -0
  117. package/src/lib/thread/keys.ts +94 -0
  118. package/src/lib/thread/manager.test.ts +139 -0
  119. package/src/lib/thread/manager.ts +92 -14
  120. package/src/lib/thread/proxy.ts +2 -0
  121. package/src/lib/thread/types.ts +60 -6
  122. package/src/lib/tool-router/types.ts +16 -8
  123. package/src/lib/types.ts +12 -0
  124. package/src/workflow.ts +12 -1
  125. package/tsup.config.ts +1 -0
package/dist/workflow.cjs CHANGED
@@ -440,6 +440,7 @@ function createSubagentTool(subagents) {
440
440
  var childSandboxReadySignal = workflow.defineSignal("childSandboxReady");
441
441
 
442
442
  // src/lib/subagent/handler.ts
443
+ var DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT = "1h";
443
444
  function resolveSandboxConfig(config) {
444
445
  if (!config || config === "none") {
445
446
  return { source: "none", init: "per-call", continuation: "fork" };
@@ -471,17 +472,28 @@ function createSubagentHandler(subagents) {
471
472
  const threadSandboxes = /* @__PURE__ */ new Map();
472
473
  const persistentSandboxes = /* @__PURE__ */ new Map();
473
474
  const persistentSandboxCreating = /* @__PURE__ */ new Set();
475
+ const persistentSandboxCreationError = /* @__PURE__ */ new Map();
474
476
  const lazyCreatorAgent = /* @__PURE__ */ new Map();
477
+ const snapshotBaseCreatorAgent = /* @__PURE__ */ new Map();
475
478
  const threadSnapshots = /* @__PURE__ */ new Map();
476
479
  const persistentBaseSnapshot = /* @__PURE__ */ new Map();
477
480
  const persistentBaseSnapshotCreating = /* @__PURE__ */ new Set();
478
- workflow.setHandler(childSandboxReadySignal, ({ childWorkflowId, sandboxId }) => {
479
- const agentName = lazyCreatorAgent.get(childWorkflowId);
480
- if (agentName && !persistentSandboxes.has(agentName)) {
481
- persistentSandboxes.set(agentName, sandboxId);
482
- lazyCreatorAgent.delete(childWorkflowId);
481
+ const persistentBaseSnapshotCreationError = /* @__PURE__ */ new Map();
482
+ workflow.setHandler(
483
+ childSandboxReadySignal,
484
+ ({ childWorkflowId, sandboxId, baseSnapshot }) => {
485
+ const lazyAgent = lazyCreatorAgent.get(childWorkflowId);
486
+ if (lazyAgent && !persistentSandboxes.has(lazyAgent)) {
487
+ persistentSandboxes.set(lazyAgent, sandboxId);
488
+ lazyCreatorAgent.delete(childWorkflowId);
489
+ }
490
+ const snapAgent = snapshotBaseCreatorAgent.get(childWorkflowId);
491
+ if (snapAgent && baseSnapshot && !persistentBaseSnapshot.has(snapAgent)) {
492
+ persistentBaseSnapshot.set(snapAgent, baseSnapshot);
493
+ snapshotBaseCreatorAgent.delete(childWorkflowId);
494
+ }
483
495
  }
484
- });
496
+ );
485
497
  const handler = async (args, context) => {
486
498
  const config = subagents.find((s) => s.agentName === args.subagent);
487
499
  if (!config) {
@@ -537,8 +549,20 @@ function createSubagentHandler(subagents) {
537
549
  baseSnap = persistentBaseSnapshot.get(config.agentName);
538
550
  if (!baseSnap) {
539
551
  if (persistentBaseSnapshotCreating.has(config.agentName)) {
540
- await workflow.condition(() => persistentBaseSnapshot.has(config.agentName));
552
+ await workflow.condition(
553
+ () => persistentBaseSnapshot.has(config.agentName) || persistentBaseSnapshotCreationError.has(config.agentName) || !persistentBaseSnapshotCreating.has(config.agentName)
554
+ );
555
+ const creatorErr = persistentBaseSnapshotCreationError.get(
556
+ config.agentName
557
+ );
558
+ if (creatorErr !== void 0) {
559
+ throw creatorErr;
560
+ }
541
561
  baseSnap = persistentBaseSnapshot.get(config.agentName);
562
+ if (!baseSnap) {
563
+ persistentBaseSnapshotCreating.add(config.agentName);
564
+ isSnapshotBaseCreator = true;
565
+ }
542
566
  } else {
543
567
  persistentBaseSnapshotCreating.add(config.agentName);
544
568
  isSnapshotBaseCreator = true;
@@ -556,8 +580,20 @@ function createSubagentHandler(subagents) {
556
580
  baseSandboxId = persistentSandboxes.get(config.agentName);
557
581
  if (!baseSandboxId) {
558
582
  if (persistentSandboxCreating.has(config.agentName)) {
559
- await workflow.condition(() => persistentSandboxes.has(config.agentName));
583
+ await workflow.condition(
584
+ () => persistentSandboxes.has(config.agentName) || persistentSandboxCreationError.has(config.agentName) || !persistentSandboxCreating.has(config.agentName)
585
+ );
586
+ const creatorErr = persistentSandboxCreationError.get(
587
+ config.agentName
588
+ );
589
+ if (creatorErr !== void 0) {
590
+ throw creatorErr;
591
+ }
560
592
  baseSandboxId = persistentSandboxes.get(config.agentName);
593
+ if (!baseSandboxId) {
594
+ persistentSandboxCreating.add(config.agentName);
595
+ isLazyCreator = true;
596
+ }
561
597
  } else {
562
598
  persistentSandboxCreating.add(config.agentName);
563
599
  isLazyCreator = true;
@@ -586,6 +622,12 @@ function createSubagentHandler(subagents) {
586
622
  };
587
623
  const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
588
624
  const childOpts = {
625
+ // Apply a bounded run timeout by default so a child workflow that
626
+ // fails to initialize or otherwise never reaches a terminal state
627
+ // cannot hang the parent's `Subagent` tool call forever. Callers can
628
+ // raise, lower, or disable it via `workflowOptions.workflowRunTimeout`.
629
+ workflowRunTimeout: DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT,
630
+ ...config.workflowOptions ?? {},
589
631
  workflowId: childWorkflowId,
590
632
  args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
591
633
  taskQueue: config.taskQueue ?? parentTaskQueue
@@ -593,13 +635,39 @@ function createSubagentHandler(subagents) {
593
635
  if (isLazyCreator) {
594
636
  lazyCreatorAgent.set(childWorkflowId, config.agentName);
595
637
  }
638
+ if (isSnapshotBaseCreator) {
639
+ snapshotBaseCreatorAgent.set(childWorkflowId, config.agentName);
640
+ }
596
641
  workflow.log.info("subagent spawned", {
597
642
  subagent: config.agentName,
598
643
  childWorkflowId,
599
644
  threadMode,
600
645
  sandboxSource: sandboxCfg.source
601
646
  });
602
- const childResult = await workflow.executeChild(config.workflow, childOpts);
647
+ let childResult;
648
+ try {
649
+ childResult = await workflow.executeChild(
650
+ config.workflow,
651
+ childOpts
652
+ );
653
+ } catch (err) {
654
+ workflow.log.warn("subagent failed", {
655
+ subagent: config.agentName,
656
+ childWorkflowId,
657
+ error: err instanceof Error ? err.message : String(err)
658
+ });
659
+ if (isLazyCreator) {
660
+ persistentSandboxCreating.delete(config.agentName);
661
+ persistentSandboxCreationError.set(config.agentName, err);
662
+ lazyCreatorAgent.delete(childWorkflowId);
663
+ }
664
+ if (isSnapshotBaseCreator) {
665
+ persistentBaseSnapshotCreating.delete(config.agentName);
666
+ persistentBaseSnapshotCreationError.set(config.agentName, err);
667
+ snapshotBaseCreatorAgent.delete(childWorkflowId);
668
+ }
669
+ throw err;
670
+ }
603
671
  const effectiveShutdown = sandboxShutdownOverride ?? sandboxCfg.shutdown ?? "destroy";
604
672
  workflow.log.info("subagent completed", {
605
673
  subagent: config.agentName,
@@ -643,10 +711,13 @@ function createSubagentHandler(subagents) {
643
711
  }
644
712
  if (isLazyCreator) {
645
713
  persistentSandboxCreating.delete(config.agentName);
714
+ persistentSandboxCreationError.delete(config.agentName);
646
715
  lazyCreatorAgent.delete(childWorkflowId);
647
716
  }
648
717
  if (isSnapshotBaseCreator) {
649
718
  persistentBaseSnapshotCreating.delete(config.agentName);
719
+ persistentBaseSnapshotCreationError.delete(config.agentName);
720
+ snapshotBaseCreatorAgent.delete(childWorkflowId);
650
721
  }
651
722
  if (!toolResponse) {
652
723
  return {
@@ -889,6 +960,7 @@ async function createSession({
889
960
  sandbox: sandboxInit,
890
961
  sandboxShutdown = "destroy",
891
962
  onSandboxReady,
963
+ onSessionExit,
892
964
  virtualFs: virtualFsConfig,
893
965
  virtualFsOps
894
966
  }) {
@@ -914,7 +986,8 @@ async function createSession({
914
986
  appendSystemMessage,
915
987
  appendAgentMessage,
916
988
  forkThread,
917
- truncateThread
989
+ loadThreadState,
990
+ saveThreadState
918
991
  } = threadOps;
919
992
  const plugins = [];
920
993
  let destroySubagentSandboxes;
@@ -1042,7 +1115,10 @@ async function createSession({
1042
1115
  baseSnapshot = await sandboxOps.snapshotSandbox(sandboxId);
1043
1116
  }
1044
1117
  if (sandboxId && sandboxOwned && onSandboxReady) {
1045
- onSandboxReady(sandboxId);
1118
+ onSandboxReady({
1119
+ sandboxId,
1120
+ ...baseSnapshot && { baseSnapshot }
1121
+ });
1046
1122
  }
1047
1123
  if (virtualFsConfig) {
1048
1124
  if (!virtualFsOps) {
@@ -1085,9 +1161,20 @@ async function createSession({
1085
1161
  });
1086
1162
  const sessionStartMs = Date.now();
1087
1163
  const systemPrompt = stateManager.getSystemPrompt();
1164
+ const rehydrateFromSlice = (slice) => {
1165
+ stateManager.mergeUpdate({
1166
+ tasks: new Map(slice.tasks),
1167
+ ...slice.custom
1168
+ });
1169
+ };
1088
1170
  if (threadMode === "fork" && sourceThreadId) {
1089
1171
  await forkThread(sourceThreadId, threadId, threadKey);
1090
- } else if (threadMode === "continue") ; else {
1172
+ const forkedSlice = await loadThreadState(threadId, threadKey);
1173
+ if (forkedSlice) rehydrateFromSlice(forkedSlice);
1174
+ } else if (threadMode === "continue") {
1175
+ const continuedSlice = await loadThreadState(threadId, threadKey);
1176
+ if (continuedSlice) rehydrateFromSlice(continuedSlice);
1177
+ } else {
1091
1178
  if (appendSystemPrompt) {
1092
1179
  if (systemPrompt == null || typeof systemPrompt === "string" && systemPrompt.trim() === "") {
1093
1180
  throw workflow.ApplicationFailure.create({
@@ -1109,24 +1196,21 @@ async function createSession({
1109
1196
  let exitReason = "completed";
1110
1197
  let finalMessage = null;
1111
1198
  try {
1199
+ let assistantId;
1112
1200
  while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
1113
1201
  stateManager.incrementTurns();
1114
1202
  const currentTurn = stateManager.getTurns();
1115
1203
  workflow.log.debug("turn started", { agentName, threadId, turn: currentTurn });
1116
1204
  stateManager.setTools(toolRouter.getToolDefinitions());
1117
- const {
1118
- message,
1119
- rawToolCalls,
1120
- usage,
1121
- threadLengthAtCall
1122
- } = await runAgent({
1205
+ assistantId ??= workflow.uuid4();
1206
+ const { message, rawToolCalls, usage } = await runAgent({
1123
1207
  threadId,
1124
1208
  threadKey,
1125
1209
  agentName,
1126
- metadata
1210
+ metadata,
1211
+ assistantMessageId: assistantId
1127
1212
  });
1128
- const preAssistantLength = threadLengthAtCall;
1129
- await appendAgentMessage(threadId, workflow.uuid4(), message, threadKey);
1213
+ await appendAgentMessage(threadId, assistantId, message, threadKey);
1130
1214
  if (usage) {
1131
1215
  stateManager.updateUsage(usage);
1132
1216
  }
@@ -1180,15 +1264,9 @@ async function createSession({
1180
1264
  toolCallId: rewind.toolCallId,
1181
1265
  toolName: rewind.toolName
1182
1266
  });
1183
- if (preAssistantLength === void 0) {
1184
- throw workflow.ApplicationFailure.create({
1185
- message: "Rewind requested but runAgent did not report `threadLengthAtCall`; the adapter must populate it to support rewinds.",
1186
- nonRetryable: true
1187
- });
1188
- }
1189
- await truncateThread(threadId, preAssistantLength, threadKey);
1190
1267
  continue;
1191
1268
  }
1269
+ assistantId = void 0;
1192
1270
  if (stateManager.getStatus() === "WAITING_FOR_INPUT") {
1193
1271
  const conditionMet = await workflow.condition(
1194
1272
  () => stateManager.getStatus() === "RUNNING",
@@ -1221,6 +1299,19 @@ async function createSession({
1221
1299
  });
1222
1300
  throw workflow.ApplicationFailure.fromError(error);
1223
1301
  } finally {
1302
+ try {
1303
+ await saveThreadState(
1304
+ threadId,
1305
+ stateManager.getPersistedSlice(),
1306
+ threadKey
1307
+ );
1308
+ } catch (persistError) {
1309
+ workflow.log.warn("failed to persist thread state", {
1310
+ agentName,
1311
+ threadId,
1312
+ error: persistError instanceof Error ? persistError.message : String(persistError)
1313
+ });
1314
+ }
1224
1315
  await callSessionEnd(exitReason, stateManager.getTurns());
1225
1316
  if (sandboxOwned && sandboxId && sandboxOps) {
1226
1317
  switch (sandboxShutdown) {
@@ -1257,6 +1348,13 @@ async function createSession({
1257
1348
  ...baseSnapshot && { hasBaseSnapshot: true },
1258
1349
  ...exitSnapshot && { hasExitSnapshot: true }
1259
1350
  });
1351
+ if (onSessionExit) {
1352
+ onSessionExit({
1353
+ ...sandboxId && { sandboxId },
1354
+ ...exitSnapshot && { snapshot: exitSnapshot },
1355
+ threadId
1356
+ });
1357
+ }
1260
1358
  return {
1261
1359
  threadId,
1262
1360
  finalMessage,
@@ -1285,6 +1383,15 @@ function defineWorkflow(config, fn) {
1285
1383
  return workflow;
1286
1384
  }
1287
1385
 
1386
+ // src/lib/thread/keys.ts
1387
+ var THREAD_TTL_SECONDS = 60 * 60 * 24 * 90;
1388
+ function getThreadListKey(threadKey, threadId) {
1389
+ return `${threadKey}:thread:${threadId}`;
1390
+ }
1391
+ function getThreadMetaKey(threadKey, threadId) {
1392
+ return `${threadKey}:meta:thread:${threadId}`;
1393
+ }
1394
+
1288
1395
  // src/lib/types.ts
1289
1396
  function isTerminalStatus(status) {
1290
1397
  return status === "COMPLETED" || status === "FAILED" || status === "CANCELLED";
@@ -1304,11 +1411,19 @@ function createAgentStateManager({
1304
1411
  let systemPrompt = initialState?.systemPrompt;
1305
1412
  const tasks = new Map(initialState?.tasks);
1306
1413
  const {
1307
- status: _,
1308
- version: __,
1309
- turns: ___,
1310
- tasks: ____,
1311
- tools: _____,
1414
+ status: _status,
1415
+ version: _version,
1416
+ turns: _turns,
1417
+ tasks: _tasks,
1418
+ tools: _tools,
1419
+ systemPrompt: _systemPrompt,
1420
+ fileTree: _fileTree,
1421
+ inlineFiles: _inlineFiles,
1422
+ virtualFsCtx: _virtualFsCtx,
1423
+ totalInputTokens: _totalInputTokens,
1424
+ totalOutputTokens: _totalOutputTokens,
1425
+ cachedWriteTokens: _cachedWriteTokens,
1426
+ cachedReadTokens: _cachedReadTokens,
1312
1427
  ...custom
1313
1428
  } = initialState ?? {};
1314
1429
  const customState = custom;
@@ -1388,7 +1503,14 @@ function createAgentStateManager({
1388
1503
  version++;
1389
1504
  },
1390
1505
  mergeUpdate(update) {
1391
- Object.assign(customState, update);
1506
+ const { tasks: nextTasks, ...rest } = update;
1507
+ if (nextTasks) {
1508
+ tasks.clear();
1509
+ for (const [id, task] of nextTasks) {
1510
+ tasks.set(id, task);
1511
+ }
1512
+ }
1513
+ Object.assign(customState, rest);
1392
1514
  version++;
1393
1515
  },
1394
1516
  getCurrentState() {
@@ -1426,6 +1548,12 @@ function createAgentStateManager({
1426
1548
  }
1427
1549
  return deleted;
1428
1550
  },
1551
+ getPersistedSlice() {
1552
+ return {
1553
+ tasks: Array.from(tasks.entries()),
1554
+ custom: { ...customState }
1555
+ };
1556
+ },
1429
1557
  updateUsage(usage) {
1430
1558
  totalInputTokens += usage.inputTokens ?? 0;
1431
1559
  totalOutputTokens += usage.outputTokens ?? 0;
@@ -1469,22 +1597,42 @@ function defineSubagentWorkflow(config, fn) {
1469
1597
  });
1470
1598
  }
1471
1599
  const parentHandle = workflow.getExternalWorkflowHandle(parent.workflowId);
1600
+ let capturedSandboxId;
1601
+ let capturedSnapshot;
1602
+ let capturedBaseSnapshot;
1603
+ let capturedThreadId;
1472
1604
  const sessionInput = {
1473
1605
  agentName: config.name,
1474
1606
  sandboxShutdown: effectiveShutdown,
1475
1607
  ...workflowInput.thread && { thread: workflowInput.thread },
1476
1608
  ...workflowInput.sandbox && { sandbox: workflowInput.sandbox },
1477
- onSandboxReady: (sandboxId) => {
1609
+ onSandboxReady: ({ sandboxId, baseSnapshot }) => {
1610
+ capturedBaseSnapshot = baseSnapshot;
1478
1611
  const isReuse = workflowInput.sandbox?.mode === "continue";
1479
1612
  if (!isReuse) {
1480
1613
  void parentHandle.signal(childSandboxReadySignal, {
1481
1614
  childWorkflowId: workflow.workflowInfo().workflowId,
1482
- sandboxId
1615
+ sandboxId,
1616
+ ...baseSnapshot && { baseSnapshot }
1483
1617
  });
1484
1618
  }
1619
+ },
1620
+ onSessionExit: ({ sandboxId, snapshot, threadId }) => {
1621
+ capturedSandboxId = sandboxId;
1622
+ capturedSnapshot = snapshot;
1623
+ capturedThreadId = threadId;
1624
+ }
1625
+ };
1626
+ const result = await fn(prompt, sessionInput, context ?? {});
1627
+ return {
1628
+ ...result,
1629
+ ...capturedThreadId !== void 0 && { threadId: capturedThreadId },
1630
+ ...capturedSandboxId !== void 0 && { sandboxId: capturedSandboxId },
1631
+ ...capturedSnapshot !== void 0 && { snapshot: capturedSnapshot },
1632
+ ...capturedBaseSnapshot !== void 0 && {
1633
+ baseSnapshot: capturedBaseSnapshot
1485
1634
  }
1486
1635
  };
1487
- return fn(prompt, sessionInput, context ?? {});
1488
1636
  };
1489
1637
  Object.defineProperty(workflow$1, "name", { value: config.name });
1490
1638
  return Object.assign(workflow$1, {
@@ -2143,8 +2291,10 @@ var createAskUserQuestionHandler = () => async (args) => {
2143
2291
  };
2144
2292
  };
2145
2293
 
2294
+ exports.DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT = DEFAULT_SUBAGENT_WORKFLOW_RUN_TIMEOUT;
2146
2295
  exports.SandboxNotFoundError = SandboxNotFoundError;
2147
2296
  exports.SandboxNotSupportedError = SandboxNotSupportedError;
2297
+ exports.THREAD_TTL_SECONDS = THREAD_TTL_SECONDS;
2148
2298
  exports.applyVirtualTreeMutations = applyVirtualTreeMutations;
2149
2299
  exports.askUserQuestionTool = askUserQuestionTool;
2150
2300
  exports.bashTool = bashTool;
@@ -2169,6 +2319,8 @@ exports.editTool = editTool;
2169
2319
  exports.filesWithMimeType = filesWithMimeType;
2170
2320
  exports.formatVirtualFileTree = formatVirtualFileTree;
2171
2321
  exports.getShortId = getShortId;
2322
+ exports.getThreadListKey = getThreadListKey;
2323
+ exports.getThreadMetaKey = getThreadMetaKey;
2172
2324
  exports.globTool = globTool;
2173
2325
  exports.grepTool = grepTool;
2174
2326
  exports.hasDirectory = hasDirectory;