zeitlich 0.2.21 → 0.2.23

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 (129) hide show
  1. package/README.md +303 -105
  2. package/dist/adapters/sandbox/daytona/index.cjs +7 -1
  3. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  4. package/dist/adapters/sandbox/daytona/index.d.cts +3 -1
  5. package/dist/adapters/sandbox/daytona/index.d.ts +3 -1
  6. package/dist/adapters/sandbox/daytona/index.js +7 -1
  7. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  8. package/dist/adapters/sandbox/daytona/workflow.cjs +33 -0
  9. package/dist/adapters/sandbox/daytona/workflow.cjs.map +1 -0
  10. package/dist/adapters/sandbox/daytona/workflow.d.cts +27 -0
  11. package/dist/adapters/sandbox/daytona/workflow.d.ts +27 -0
  12. package/dist/adapters/sandbox/daytona/workflow.js +31 -0
  13. package/dist/adapters/sandbox/daytona/workflow.js.map +1 -0
  14. package/dist/adapters/sandbox/inmemory/index.cjs +18 -1
  15. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  16. package/dist/adapters/sandbox/inmemory/index.d.cts +4 -2
  17. package/dist/adapters/sandbox/inmemory/index.d.ts +4 -2
  18. package/dist/adapters/sandbox/inmemory/index.js +18 -1
  19. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  20. package/dist/adapters/sandbox/inmemory/workflow.cjs +33 -0
  21. package/dist/adapters/sandbox/inmemory/workflow.cjs.map +1 -0
  22. package/dist/adapters/sandbox/inmemory/workflow.d.cts +25 -0
  23. package/dist/adapters/sandbox/inmemory/workflow.d.ts +25 -0
  24. package/dist/adapters/sandbox/inmemory/workflow.js +31 -0
  25. package/dist/adapters/sandbox/inmemory/workflow.js.map +1 -0
  26. package/dist/adapters/sandbox/virtual/index.cjs +36 -9
  27. package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
  28. package/dist/adapters/sandbox/virtual/index.d.cts +8 -5
  29. package/dist/adapters/sandbox/virtual/index.d.ts +8 -5
  30. package/dist/adapters/sandbox/virtual/index.js +36 -9
  31. package/dist/adapters/sandbox/virtual/index.js.map +1 -1
  32. package/dist/adapters/sandbox/virtual/workflow.cjs +33 -0
  33. package/dist/adapters/sandbox/virtual/workflow.cjs.map +1 -0
  34. package/dist/adapters/sandbox/virtual/workflow.d.cts +27 -0
  35. package/dist/adapters/sandbox/virtual/workflow.d.ts +27 -0
  36. package/dist/adapters/sandbox/virtual/workflow.js +31 -0
  37. package/dist/adapters/sandbox/virtual/workflow.js.map +1 -0
  38. package/dist/adapters/thread/google-genai/index.cjs +9 -1
  39. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  40. package/dist/adapters/thread/google-genai/index.d.cts +31 -19
  41. package/dist/adapters/thread/google-genai/index.d.ts +31 -19
  42. package/dist/adapters/thread/google-genai/index.js +9 -1
  43. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  44. package/dist/adapters/thread/google-genai/workflow.cjs +33 -0
  45. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -0
  46. package/dist/adapters/thread/google-genai/workflow.d.cts +32 -0
  47. package/dist/adapters/thread/google-genai/workflow.d.ts +32 -0
  48. package/dist/adapters/thread/google-genai/workflow.js +31 -0
  49. package/dist/adapters/thread/google-genai/workflow.js.map +1 -0
  50. package/dist/adapters/thread/langchain/index.cjs +9 -1
  51. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  52. package/dist/adapters/thread/langchain/index.d.cts +27 -16
  53. package/dist/adapters/thread/langchain/index.d.ts +27 -16
  54. package/dist/adapters/thread/langchain/index.js +9 -1
  55. package/dist/adapters/thread/langchain/index.js.map +1 -1
  56. package/dist/adapters/thread/langchain/workflow.cjs +33 -0
  57. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -0
  58. package/dist/adapters/thread/langchain/workflow.d.cts +32 -0
  59. package/dist/adapters/thread/langchain/workflow.d.ts +32 -0
  60. package/dist/adapters/thread/langchain/workflow.js +31 -0
  61. package/dist/adapters/thread/langchain/workflow.js.map +1 -0
  62. package/dist/index.cjs +282 -90
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +38 -16
  65. package/dist/index.d.ts +38 -16
  66. package/dist/index.js +281 -87
  67. package/dist/index.js.map +1 -1
  68. package/dist/queries-DModcWRy.d.cts +44 -0
  69. package/dist/queries-byD0jr1Y.d.ts +44 -0
  70. package/dist/{types-BkAYmc96.d.ts → types-B50pBPEV.d.ts} +190 -38
  71. package/dist/{types-YbL7JpEA.d.cts → types-Bll19FZJ.d.cts} +7 -0
  72. package/dist/{types-YbL7JpEA.d.ts → types-Bll19FZJ.d.ts} +7 -0
  73. package/dist/{queries-6Avfh74U.d.ts → types-BuXdFhaZ.d.cts} +7 -48
  74. package/dist/{types-BMRzfELQ.d.cts → types-ChAMwU3q.d.cts} +17 -1
  75. package/dist/{types-BMRzfELQ.d.ts → types-ChAMwU3q.d.ts} +17 -1
  76. package/dist/{types-CES_30qx.d.cts → types-DQW8l7pY.d.cts} +190 -38
  77. package/dist/{queries-CHa2iv_I.d.cts → types-GZ76HZSj.d.ts} +7 -48
  78. package/dist/workflow.cjs +244 -86
  79. package/dist/workflow.cjs.map +1 -1
  80. package/dist/workflow.d.cts +54 -65
  81. package/dist/workflow.d.ts +54 -65
  82. package/dist/workflow.js +243 -83
  83. package/dist/workflow.js.map +1 -1
  84. package/package.json +54 -2
  85. package/src/adapters/sandbox/daytona/filesystem.ts +1 -1
  86. package/src/adapters/sandbox/daytona/index.ts +8 -0
  87. package/src/adapters/sandbox/daytona/proxy.ts +56 -0
  88. package/src/adapters/sandbox/e2b/filesystem.ts +147 -0
  89. package/src/adapters/sandbox/e2b/index.ts +164 -0
  90. package/src/adapters/sandbox/e2b/types.ts +23 -0
  91. package/src/adapters/sandbox/inmemory/index.ts +27 -3
  92. package/src/adapters/sandbox/inmemory/proxy.ts +53 -0
  93. package/src/adapters/sandbox/virtual/filesystem.ts +41 -17
  94. package/src/adapters/sandbox/virtual/provider.ts +9 -1
  95. package/src/adapters/sandbox/virtual/proxy.ts +53 -0
  96. package/src/adapters/sandbox/virtual/types.ts +9 -4
  97. package/src/adapters/thread/google-genai/activities.ts +51 -17
  98. package/src/adapters/thread/google-genai/index.ts +1 -0
  99. package/src/adapters/thread/google-genai/proxy.ts +61 -0
  100. package/src/adapters/thread/langchain/activities.ts +47 -14
  101. package/src/adapters/thread/langchain/index.ts +1 -0
  102. package/src/adapters/thread/langchain/proxy.ts +61 -0
  103. package/src/lib/lifecycle.ts +57 -0
  104. package/src/lib/sandbox/manager.ts +52 -6
  105. package/src/lib/sandbox/sandbox.test.ts +12 -11
  106. package/src/lib/sandbox/types.ts +31 -4
  107. package/src/lib/session/index.ts +4 -5
  108. package/src/lib/session/session-edge-cases.integration.test.ts +491 -66
  109. package/src/lib/session/session.integration.test.ts +92 -80
  110. package/src/lib/session/session.ts +108 -96
  111. package/src/lib/session/types.ts +87 -17
  112. package/src/lib/subagent/define.ts +6 -5
  113. package/src/lib/subagent/handler.ts +148 -16
  114. package/src/lib/subagent/index.ts +4 -0
  115. package/src/lib/subagent/register.ts +10 -3
  116. package/src/lib/subagent/signals.ts +8 -0
  117. package/src/lib/subagent/subagent.integration.test.ts +893 -128
  118. package/src/lib/subagent/tool.ts +2 -2
  119. package/src/lib/subagent/types.ts +84 -21
  120. package/src/lib/subagent/workflow.ts +83 -12
  121. package/src/lib/tool-router/router-edge-cases.integration.test.ts +4 -1
  122. package/src/lib/tool-router/router.integration.test.ts +141 -5
  123. package/src/lib/tool-router/router.ts +13 -3
  124. package/src/lib/tool-router/types.ts +7 -0
  125. package/src/lib/workflow.test.ts +104 -27
  126. package/src/lib/workflow.ts +37 -19
  127. package/src/tools/bash/bash.test.ts +16 -7
  128. package/src/workflow.ts +11 -14
  129. package/tsup.config.ts +6 -0
package/dist/workflow.cjs CHANGED
@@ -85,7 +85,12 @@ function createToolRouter(options) {
85
85
  result: { error: errorStr, suppressed: true }
86
86
  };
87
87
  }
88
- throw workflow.ApplicationFailure.fromError(error, { nonRetryable: true });
88
+ return {
89
+ content: JSON.stringify({
90
+ error: "The tool encountered an error. Please try again or use a different approach."
91
+ }),
92
+ result: { error: errorStr, suppressed: true }
93
+ };
89
94
  }
90
95
  async function runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, durationMs) {
91
96
  if (tool?.hooks?.onPostToolUse) {
@@ -94,7 +99,8 @@ function createToolRouter(options) {
94
99
  result: toolResult.data,
95
100
  threadId: options.threadId,
96
101
  turn,
97
- durationMs
102
+ durationMs,
103
+ ...toolResult.metadata && { metadata: toolResult.metadata }
98
104
  });
99
105
  }
100
106
  if (options.hooks?.onPostToolUse) {
@@ -127,6 +133,7 @@ function createToolRouter(options) {
127
133
  let result;
128
134
  let content;
129
135
  let resultAppended = false;
136
+ let metadata;
130
137
  try {
131
138
  if (tool) {
132
139
  const routerContext = {
@@ -142,6 +149,7 @@ function createToolRouter(options) {
142
149
  result = response.data;
143
150
  content = response.toolResponse;
144
151
  resultAppended = response.resultAppended === true;
152
+ metadata = response.metadata;
145
153
  } else {
146
154
  result = { error: `Unknown tool: ${toolCall.name}` };
147
155
  content = JSON.stringify(result, null, 2);
@@ -174,7 +182,8 @@ function createToolRouter(options) {
174
182
  const toolResult = {
175
183
  toolCallId: toolCall.id,
176
184
  name: toolCall.name,
177
- data: result
185
+ data: result,
186
+ ...metadata && { metadata }
178
187
  };
179
188
  await runPostHooks(
180
189
  toolCall,
@@ -278,7 +287,8 @@ function createToolRouter(options) {
278
287
  return {
279
288
  toolCallId: toolCall.id,
280
289
  name: toolCall.name,
281
- data: response.data
290
+ data: response.data,
291
+ ...response.metadata && { metadata: response.metadata }
282
292
  };
283
293
  };
284
294
  if (options.parallel) {
@@ -322,7 +332,7 @@ function getShortId(length = 12) {
322
332
  var SUBAGENT_TOOL_NAME = "Subagent";
323
333
  function buildSubagentDescription(subagents) {
324
334
  const subagentList = subagents.map((s) => {
325
- const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
335
+ const continuation = s.thread && s.thread !== "new" ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
326
336
  return `## ${s.agentName}
327
337
  ${s.description}${continuation}`;
328
338
  }).join("\n\n");
@@ -338,7 +348,7 @@ function createSubagentTool(subagents) {
338
348
  }
339
349
  const names = subagents.map((s) => s.agentName);
340
350
  const hasThreadContinuation = subagents.some(
341
- (s) => s.allowThreadContinuation
351
+ (s) => s.thread && s.thread !== "new"
342
352
  );
343
353
  const baseFields = {
344
354
  subagent: z14__default.default.enum(names).describe("The type of subagent to launch"),
@@ -357,9 +367,25 @@ function createSubagentTool(subagents) {
357
367
  schema
358
368
  };
359
369
  }
370
+ var childResultSignal = workflow.defineSignal("childResult");
371
+ var destroySandboxSignal = workflow.defineSignal("destroySandbox");
372
+
373
+ // src/lib/subagent/handler.ts
374
+ function resolveSandboxConfig(config) {
375
+ if (!config || config === "none") return { source: "none" };
376
+ if (config === "inherit") return { source: "inherit" };
377
+ if (config === "own") return { source: "own" };
378
+ return { source: "own", shutdown: config.shutdown };
379
+ }
360
380
  function createSubagentHandler(subagents) {
361
381
  const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
362
- return async (args, context) => {
382
+ const childResults = /* @__PURE__ */ new Map();
383
+ const pendingDestroys = /* @__PURE__ */ new Map();
384
+ const threadSandboxes = /* @__PURE__ */ new Map();
385
+ workflow.setHandler(childResultSignal, ({ childWorkflowId, result }) => {
386
+ childResults.set(childWorkflowId, result);
387
+ });
388
+ const handler = async (args, context) => {
363
389
  const config = subagents.find((s) => s.agentName === args.subagent);
364
390
  if (!config) {
365
391
  throw new Error(
@@ -368,29 +394,77 @@ function createSubagentHandler(subagents) {
368
394
  }
369
395
  const childWorkflowId = `${args.subagent}-${getShortId()}`;
370
396
  const { sandboxId: parentSandboxId } = context;
371
- const inheritSandbox = config.sandbox !== "own" && !!parentSandboxId;
397
+ const sandboxCfg = resolveSandboxConfig(config.sandbox);
398
+ if (sandboxCfg.source === "inherit" && !parentSandboxId) {
399
+ throw new Error(
400
+ `Subagent "${config.agentName}" is configured with sandbox: "inherit" but the parent has no sandbox`
401
+ );
402
+ }
403
+ const threadMode = config.thread ?? "new";
404
+ const allowsContinuation = threadMode !== "new";
405
+ const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
406
+ let thread;
407
+ if (continuationThreadId) {
408
+ thread = { mode: threadMode, threadId: continuationThreadId };
409
+ }
410
+ let sandbox;
411
+ if (sandboxCfg.source === "inherit" && parentSandboxId) {
412
+ sandbox = { mode: "inherit", sandboxId: parentSandboxId };
413
+ } else if (sandboxCfg.source === "own") {
414
+ const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
415
+ if (prevSbId) {
416
+ sandbox = { mode: "fork", sandboxId: prevSbId };
417
+ }
418
+ }
372
419
  const workflowInput = {
373
- ...args.threadId && args.threadId !== null && config.allowThreadContinuation && {
374
- previousThreadId: args.threadId
375
- },
376
- ...inheritSandbox && { sandboxId: parentSandboxId }
420
+ ...thread && { thread },
421
+ ...sandbox && { sandbox },
422
+ ...sandboxCfg.shutdown && { sandboxShutdown: sandboxCfg.shutdown }
377
423
  };
424
+ const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
378
425
  const childOpts = {
379
426
  workflowId: childWorkflowId,
380
- args: config.context === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, config.context],
427
+ args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
381
428
  taskQueue: config.taskQueue ?? parentTaskQueue
382
429
  };
430
+ const childHandle = await workflow.startChild(config.workflow, childOpts);
431
+ const usesOwnSandbox = sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit";
432
+ if (usesOwnSandbox) {
433
+ pendingDestroys.set(childWorkflowId, childHandle);
434
+ }
435
+ await Promise.race([
436
+ workflow.condition(() => childResults.has(childWorkflowId)),
437
+ childHandle.result()
438
+ ]);
439
+ if (!childResults.has(childWorkflowId)) {
440
+ await workflow.condition(() => childResults.has(childWorkflowId));
441
+ }
442
+ const childResult = childResults.get(childWorkflowId);
443
+ childResults.delete(childWorkflowId);
444
+ if (!childResult) {
445
+ return {
446
+ toolResponse: "Subagent workflow did not signal a result",
447
+ data: null
448
+ };
449
+ }
383
450
  const {
384
451
  toolResponse,
385
452
  data,
386
453
  usage,
387
- threadId: childThreadId
388
- } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
454
+ threadId: childThreadId,
455
+ sandboxId: childSandboxId,
456
+ metadata
457
+ } = childResult;
458
+ if (allowsContinuation && childSandboxId && childThreadId) {
459
+ threadSandboxes.set(childThreadId, childSandboxId);
460
+ }
389
461
  if (!toolResponse) {
390
462
  return {
391
463
  toolResponse: "Subagent workflow returned no response",
392
464
  data: null,
393
- ...usage && { usage }
465
+ ...usage && { usage },
466
+ ...childSandboxId && { sandboxId: childSandboxId },
467
+ ...metadata && { metadata }
394
468
  };
395
469
  }
396
470
  const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
@@ -398,11 +472,13 @@ function createSubagentHandler(subagents) {
398
472
  return {
399
473
  toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
400
474
  data: null,
401
- ...usage && { usage }
475
+ ...usage && { usage },
476
+ ...childSandboxId && { sandboxId: childSandboxId },
477
+ ...metadata && { metadata }
402
478
  };
403
479
  }
404
480
  let finalToolResponse = toolResponse;
405
- if (config.allowThreadContinuation && childThreadId) {
481
+ if (allowsContinuation && childThreadId) {
406
482
  finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
407
483
 
408
484
  [${config.agentName} Thread ID: ${childThreadId}]` : toolResponse;
@@ -410,9 +486,22 @@ function createSubagentHandler(subagents) {
410
486
  return {
411
487
  toolResponse: finalToolResponse,
412
488
  data: validated ? validated.data : data,
413
- ...usage && { usage }
489
+ ...usage && { usage },
490
+ ...childSandboxId && { sandboxId: childSandboxId },
491
+ ...metadata && { metadata }
414
492
  };
415
493
  };
494
+ const destroySubagentSandboxes = async () => {
495
+ const handles = [...pendingDestroys.values()];
496
+ pendingDestroys.clear();
497
+ await Promise.all(
498
+ handles.map(async (handle) => {
499
+ await handle.signal(destroySandboxSignal);
500
+ await handle.result();
501
+ })
502
+ );
503
+ };
504
+ return { handler, destroySubagentSandboxes };
416
505
  }
417
506
 
418
507
  // src/lib/subagent/register.ts
@@ -426,12 +515,13 @@ function buildSubagentRegistration(subagents) {
426
515
  if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
427
516
  }
428
517
  const resolveSubagentName = (args) => args.subagent;
429
- return {
518
+ const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
519
+ const registration = {
430
520
  name: SUBAGENT_TOOL_NAME,
431
521
  enabled: () => getEnabled().length > 0,
432
522
  description: () => createSubagentTool(getEnabled()).description,
433
523
  schema: () => createSubagentTool(getEnabled()).schema,
434
- handler: createSubagentHandler(subagents),
524
+ handler,
435
525
  ...subagentHooksMap.size > 0 && {
436
526
  hooks: {
437
527
  onPreToolUse: async (ctx) => {
@@ -449,6 +539,7 @@ function buildSubagentRegistration(subagents) {
449
539
  }
450
540
  }
451
541
  };
542
+ return { registration, destroySubagentSandboxes };
452
543
  }
453
544
  var READ_SKILL_TOOL_NAME = "ReadSkill";
454
545
  function buildReadSkillDescription(skills) {
@@ -501,8 +592,7 @@ function buildSkillRegistration(skills) {
501
592
  handler: createReadSkillHandler(skills)
502
593
  };
503
594
  }
504
- var createSession = async ({
505
- threadId: providedThreadId,
595
+ async function createSession({
506
596
  agentName,
507
597
  maxTurns = 50,
508
598
  metadata = {},
@@ -515,24 +605,42 @@ var createSession = async ({
515
605
  processToolsInParallel = true,
516
606
  hooks = {},
517
607
  appendSystemPrompt = true,
518
- continueThread = false,
519
608
  waitForInputTimeout = "48h",
520
- sandbox: sandboxOps,
521
- sandboxId: inheritedSandboxId
522
- }) => {
523
- const sourceThreadId = continueThread ? providedThreadId : void 0;
524
- const threadId = continueThread && providedThreadId ? getShortId() : providedThreadId ?? getShortId();
609
+ sandboxOps,
610
+ thread: threadInit,
611
+ sandbox: sandboxInit,
612
+ sandboxShutdown = "destroy"
613
+ }) {
614
+ const threadMode = threadInit?.mode ?? "new";
615
+ let threadId;
616
+ let sourceThreadId;
617
+ switch (threadMode) {
618
+ case "new":
619
+ threadId = threadInit?.mode === "new" && threadInit.threadId ? threadInit.threadId : getShortId();
620
+ break;
621
+ case "continue":
622
+ threadId = threadInit.threadId;
623
+ break;
624
+ case "fork":
625
+ sourceThreadId = threadInit.threadId;
626
+ threadId = getShortId();
627
+ break;
628
+ }
525
629
  const {
526
630
  appendToolResult,
527
631
  appendHumanMessage,
528
632
  initializeThread,
529
633
  appendSystemMessage,
530
634
  forkThread
531
- } = threadOps ?? proxyDefaultThreadOps();
635
+ } = threadOps;
532
636
  const plugins = [];
637
+ let destroySubagentSandboxes;
533
638
  if (subagents) {
534
- const reg = buildSubagentRegistration(subagents);
535
- if (reg) plugins.push(reg);
639
+ const result = buildSubagentRegistration(subagents);
640
+ if (result) {
641
+ plugins.push(result.registration);
642
+ destroySubagentSandboxes = result.destroySubagentSandboxes;
643
+ }
536
644
  }
537
645
  if (skills) {
538
646
  const reg = buildSkillRegistration(skills);
@@ -580,11 +688,41 @@ var createSession = async ({
580
688
  stateManager.run();
581
689
  }
582
690
  );
583
- let sandboxId = inheritedSandboxId;
584
- const ownsSandbox = !sandboxId && !!sandboxOps;
585
- if (ownsSandbox) {
586
- const result = await sandboxOps.createSandbox({ id: threadId });
691
+ const sandboxMode = sandboxInit?.mode;
692
+ let sandboxId;
693
+ let sandboxOwned = false;
694
+ if (sandboxMode === "inherit") {
695
+ sandboxId = sandboxInit.sandboxId;
696
+ if (!sandboxOps) {
697
+ throw workflow.ApplicationFailure.create({
698
+ message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
699
+ nonRetryable: true
700
+ });
701
+ }
702
+ } else if (sandboxMode === "continue") {
703
+ if (!sandboxOps) {
704
+ throw workflow.ApplicationFailure.create({
705
+ message: "No sandboxOps provided \u2014 cannot continue sandbox",
706
+ nonRetryable: true
707
+ });
708
+ }
709
+ sandboxId = sandboxInit.sandboxId;
710
+ sandboxOwned = true;
711
+ } else if (sandboxMode === "fork") {
712
+ if (!sandboxOps) {
713
+ throw workflow.ApplicationFailure.create({
714
+ message: "No sandboxOps provided \u2014 cannot fork sandbox",
715
+ nonRetryable: true
716
+ });
717
+ }
718
+ sandboxId = await sandboxOps.forkSandbox(
719
+ sandboxInit.sandboxId
720
+ );
721
+ sandboxOwned = true;
722
+ } else if (sandboxOps) {
723
+ const result = await sandboxOps.createSandbox();
587
724
  sandboxId = result.sandboxId;
725
+ sandboxOwned = true;
588
726
  if (result.stateUpdate) {
589
727
  stateManager.mergeUpdate(result.stateUpdate);
590
728
  }
@@ -597,9 +735,9 @@ var createSession = async ({
597
735
  });
598
736
  }
599
737
  const systemPrompt = stateManager.getSystemPrompt();
600
- if (continueThread && sourceThreadId) {
738
+ if (threadMode === "fork" && sourceThreadId) {
601
739
  await forkThread(sourceThreadId, threadId);
602
- } else {
740
+ } else if (threadMode === "continue") ; else {
603
741
  if (appendSystemPrompt) {
604
742
  if (!systemPrompt || systemPrompt.trim() === "") {
605
743
  throw workflow.ApplicationFailure.create({
@@ -634,7 +772,8 @@ var createSession = async ({
634
772
  threadId,
635
773
  finalMessage: message,
636
774
  exitReason,
637
- usage: stateManager.getTotalUsage()
775
+ usage: stateManager.getTotalUsage(),
776
+ sandboxId
638
777
  };
639
778
  }
640
779
  const parsedToolCalls = [];
@@ -685,55 +824,40 @@ var createSession = async ({
685
824
  throw workflow.ApplicationFailure.fromError(error);
686
825
  } finally {
687
826
  await callSessionEnd(exitReason, stateManager.getTurns());
688
- if (ownsSandbox && sandboxId && sandboxOps) {
689
- await sandboxOps.destroySandbox(sandboxId);
827
+ if (sandboxOwned && sandboxId && sandboxOps) {
828
+ switch (sandboxShutdown) {
829
+ case "destroy":
830
+ await sandboxOps.destroySandbox(sandboxId);
831
+ break;
832
+ case "pause":
833
+ case "pause-until-parent-close":
834
+ await sandboxOps.pauseSandbox(sandboxId);
835
+ break;
836
+ }
837
+ }
838
+ if (destroySubagentSandboxes) {
839
+ await destroySubagentSandboxes();
690
840
  }
691
841
  }
692
842
  return {
693
843
  threadId,
694
844
  finalMessage: null,
695
845
  exitReason,
696
- usage: stateManager.getTotalUsage()
846
+ usage: stateManager.getTotalUsage(),
847
+ sandboxId
697
848
  };
698
849
  }
699
850
  };
700
- };
701
- function proxyDefaultThreadOps(options) {
702
- return workflow.proxyActivities(
703
- options ?? {
704
- startToCloseTimeout: "10s",
705
- retry: {
706
- maximumAttempts: 6,
707
- initialInterval: "5s",
708
- maximumInterval: "15m",
709
- backoffCoefficient: 4
710
- }
711
- }
712
- );
713
- }
714
- function proxySandboxOps(options) {
715
- return workflow.proxyActivities(
716
- options ?? {
717
- startToCloseTimeout: "30s",
718
- retry: {
719
- maximumAttempts: 3,
720
- initialInterval: "2s",
721
- maximumInterval: "30s",
722
- backoffCoefficient: 2
723
- }
724
- }
725
- );
726
851
  }
727
852
 
728
853
  // src/lib/workflow.ts
729
854
  function defineWorkflow(config, fn) {
730
855
  const workflow = async (input, workflowInput = {}) => {
731
856
  const sessionInput = {
732
- ...workflowInput.previousThreadId && {
733
- threadId: workflowInput.previousThreadId,
734
- continueThread: true
735
- },
736
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
857
+ agentName: config.name,
858
+ sandboxShutdown: config.sandboxShutdown ?? "destroy",
859
+ ...workflowInput.thread && { thread: workflowInput.thread },
860
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
737
861
  };
738
862
  return fn(input, sessionInput);
739
863
  };
@@ -914,22 +1038,58 @@ function defineSubagent(definition, overrides) {
914
1038
  ...overrides
915
1039
  };
916
1040
  }
917
-
918
- // src/lib/subagent/workflow.ts
919
1041
  function defineSubagentWorkflow(config, fn) {
920
- const workflow = async (prompt, workflowInput, context) => {
1042
+ const workflow$1 = async (prompt, workflowInput, context) => {
1043
+ const effectiveShutdown = workflowInput.sandboxShutdown ?? config.sandboxShutdown ?? "destroy";
921
1044
  const sessionInput = {
922
1045
  agentName: config.name,
923
- ...workflowInput.previousThreadId && {
924
- threadId: workflowInput.previousThreadId,
925
- continueThread: true
926
- },
927
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
1046
+ sandboxShutdown: effectiveShutdown,
1047
+ ...workflowInput.thread && { thread: workflowInput.thread },
1048
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
928
1049
  };
929
- return fn(prompt, sessionInput, context ?? {});
1050
+ const { destroySandbox, ...result } = await fn(
1051
+ prompt,
1052
+ sessionInput,
1053
+ context ?? {}
1054
+ );
1055
+ if (effectiveShutdown === "pause-until-parent-close") {
1056
+ if (!destroySandbox) {
1057
+ throw workflow.ApplicationFailure.create({
1058
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a destroySandbox callback`,
1059
+ nonRetryable: true
1060
+ });
1061
+ }
1062
+ if (!result.sandboxId) {
1063
+ throw workflow.ApplicationFailure.create({
1064
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a sandboxId`,
1065
+ nonRetryable: true
1066
+ });
1067
+ }
1068
+ }
1069
+ const { parent } = workflow.workflowInfo();
1070
+ if (!parent) {
1071
+ throw workflow.ApplicationFailure.create({
1072
+ message: "Subagent workflow called without a parent workflow",
1073
+ nonRetryable: true
1074
+ });
1075
+ }
1076
+ const parentHandle = workflow.getExternalWorkflowHandle(parent.workflowId);
1077
+ await parentHandle.signal(childResultSignal, {
1078
+ childWorkflowId: workflow.workflowInfo().workflowId,
1079
+ result
1080
+ });
1081
+ if (destroySandbox) {
1082
+ let destroyRequested = false;
1083
+ workflow.setHandler(destroySandboxSignal, () => {
1084
+ destroyRequested = true;
1085
+ });
1086
+ await workflow.condition(() => destroyRequested);
1087
+ await destroySandbox();
1088
+ }
1089
+ return result;
930
1090
  };
931
- Object.defineProperty(workflow, "name", { value: config.name });
932
- return Object.assign(workflow, {
1091
+ Object.defineProperty(workflow$1, "name", { value: config.name });
1092
+ return Object.assign(workflow$1, {
933
1093
  agentName: config.name,
934
1094
  description: config.description,
935
1095
  ...config.resultSchema !== void 0 && {
@@ -1520,8 +1680,6 @@ exports.hasFileWithMimeType = hasFileWithMimeType;
1520
1680
  exports.hasNoOtherToolCalls = hasNoOtherToolCalls;
1521
1681
  exports.isTerminalStatus = isTerminalStatus;
1522
1682
  exports.parseSkillFile = parseSkillFile;
1523
- exports.proxyDefaultThreadOps = proxyDefaultThreadOps;
1524
- exports.proxySandboxOps = proxySandboxOps;
1525
1683
  exports.readFileTool = readFileTool;
1526
1684
  exports.taskCreateTool = taskCreateTool;
1527
1685
  exports.taskGetTool = taskGetTool;