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.js CHANGED
@@ -1,4 +1,4 @@
1
- import { uuid4, setHandler, defineUpdate, ApplicationFailure, condition, proxyActivities, defineQuery, workflowInfo, executeChild } from '@temporalio/workflow';
1
+ import { defineSignal, uuid4, setHandler, defineUpdate, ApplicationFailure, condition, defineQuery, workflowInfo, getExternalWorkflowHandle, startChild } from '@temporalio/workflow';
2
2
  import z14, { z } from 'zod';
3
3
  import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
4
4
 
@@ -79,7 +79,12 @@ function createToolRouter(options) {
79
79
  result: { error: errorStr, suppressed: true }
80
80
  };
81
81
  }
82
- throw ApplicationFailure.fromError(error, { nonRetryable: true });
82
+ return {
83
+ content: JSON.stringify({
84
+ error: "The tool encountered an error. Please try again or use a different approach."
85
+ }),
86
+ result: { error: errorStr, suppressed: true }
87
+ };
83
88
  }
84
89
  async function runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, durationMs) {
85
90
  if (tool?.hooks?.onPostToolUse) {
@@ -88,7 +93,8 @@ function createToolRouter(options) {
88
93
  result: toolResult.data,
89
94
  threadId: options.threadId,
90
95
  turn,
91
- durationMs
96
+ durationMs,
97
+ ...toolResult.metadata && { metadata: toolResult.metadata }
92
98
  });
93
99
  }
94
100
  if (options.hooks?.onPostToolUse) {
@@ -121,6 +127,7 @@ function createToolRouter(options) {
121
127
  let result;
122
128
  let content;
123
129
  let resultAppended = false;
130
+ let metadata;
124
131
  try {
125
132
  if (tool) {
126
133
  const routerContext = {
@@ -136,6 +143,7 @@ function createToolRouter(options) {
136
143
  result = response.data;
137
144
  content = response.toolResponse;
138
145
  resultAppended = response.resultAppended === true;
146
+ metadata = response.metadata;
139
147
  } else {
140
148
  result = { error: `Unknown tool: ${toolCall.name}` };
141
149
  content = JSON.stringify(result, null, 2);
@@ -168,7 +176,8 @@ function createToolRouter(options) {
168
176
  const toolResult = {
169
177
  toolCallId: toolCall.id,
170
178
  name: toolCall.name,
171
- data: result
179
+ data: result,
180
+ ...metadata && { metadata }
172
181
  };
173
182
  await runPostHooks(
174
183
  toolCall,
@@ -272,7 +281,8 @@ function createToolRouter(options) {
272
281
  return {
273
282
  toolCallId: toolCall.id,
274
283
  name: toolCall.name,
275
- data: response.data
284
+ data: response.data,
285
+ ...response.metadata && { metadata: response.metadata }
276
286
  };
277
287
  };
278
288
  if (options.parallel) {
@@ -316,7 +326,7 @@ function getShortId(length = 12) {
316
326
  var SUBAGENT_TOOL_NAME = "Subagent";
317
327
  function buildSubagentDescription(subagents) {
318
328
  const subagentList = subagents.map((s) => {
319
- const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
329
+ const continuation = s.thread && s.thread !== "new" ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
320
330
  return `## ${s.agentName}
321
331
  ${s.description}${continuation}`;
322
332
  }).join("\n\n");
@@ -332,7 +342,7 @@ function createSubagentTool(subagents) {
332
342
  }
333
343
  const names = subagents.map((s) => s.agentName);
334
344
  const hasThreadContinuation = subagents.some(
335
- (s) => s.allowThreadContinuation
345
+ (s) => s.thread && s.thread !== "new"
336
346
  );
337
347
  const baseFields = {
338
348
  subagent: z14.enum(names).describe("The type of subagent to launch"),
@@ -351,9 +361,25 @@ function createSubagentTool(subagents) {
351
361
  schema
352
362
  };
353
363
  }
364
+ var childResultSignal = defineSignal("childResult");
365
+ var destroySandboxSignal = defineSignal("destroySandbox");
366
+
367
+ // src/lib/subagent/handler.ts
368
+ function resolveSandboxConfig(config) {
369
+ if (!config || config === "none") return { source: "none" };
370
+ if (config === "inherit") return { source: "inherit" };
371
+ if (config === "own") return { source: "own" };
372
+ return { source: "own", shutdown: config.shutdown };
373
+ }
354
374
  function createSubagentHandler(subagents) {
355
375
  const { taskQueue: parentTaskQueue } = workflowInfo();
356
- return async (args, context) => {
376
+ const childResults = /* @__PURE__ */ new Map();
377
+ const pendingDestroys = /* @__PURE__ */ new Map();
378
+ const threadSandboxes = /* @__PURE__ */ new Map();
379
+ setHandler(childResultSignal, ({ childWorkflowId, result }) => {
380
+ childResults.set(childWorkflowId, result);
381
+ });
382
+ const handler = async (args, context) => {
357
383
  const config = subagents.find((s) => s.agentName === args.subagent);
358
384
  if (!config) {
359
385
  throw new Error(
@@ -362,29 +388,77 @@ function createSubagentHandler(subagents) {
362
388
  }
363
389
  const childWorkflowId = `${args.subagent}-${getShortId()}`;
364
390
  const { sandboxId: parentSandboxId } = context;
365
- const inheritSandbox = config.sandbox !== "own" && !!parentSandboxId;
391
+ const sandboxCfg = resolveSandboxConfig(config.sandbox);
392
+ if (sandboxCfg.source === "inherit" && !parentSandboxId) {
393
+ throw new Error(
394
+ `Subagent "${config.agentName}" is configured with sandbox: "inherit" but the parent has no sandbox`
395
+ );
396
+ }
397
+ const threadMode = config.thread ?? "new";
398
+ const allowsContinuation = threadMode !== "new";
399
+ const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
400
+ let thread;
401
+ if (continuationThreadId) {
402
+ thread = { mode: threadMode, threadId: continuationThreadId };
403
+ }
404
+ let sandbox;
405
+ if (sandboxCfg.source === "inherit" && parentSandboxId) {
406
+ sandbox = { mode: "inherit", sandboxId: parentSandboxId };
407
+ } else if (sandboxCfg.source === "own") {
408
+ const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
409
+ if (prevSbId) {
410
+ sandbox = { mode: "fork", sandboxId: prevSbId };
411
+ }
412
+ }
366
413
  const workflowInput = {
367
- ...args.threadId && args.threadId !== null && config.allowThreadContinuation && {
368
- previousThreadId: args.threadId
369
- },
370
- ...inheritSandbox && { sandboxId: parentSandboxId }
414
+ ...thread && { thread },
415
+ ...sandbox && { sandbox },
416
+ ...sandboxCfg.shutdown && { sandboxShutdown: sandboxCfg.shutdown }
371
417
  };
418
+ const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
372
419
  const childOpts = {
373
420
  workflowId: childWorkflowId,
374
- args: config.context === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, config.context],
421
+ args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
375
422
  taskQueue: config.taskQueue ?? parentTaskQueue
376
423
  };
424
+ const childHandle = await startChild(config.workflow, childOpts);
425
+ const usesOwnSandbox = sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit";
426
+ if (usesOwnSandbox) {
427
+ pendingDestroys.set(childWorkflowId, childHandle);
428
+ }
429
+ await Promise.race([
430
+ condition(() => childResults.has(childWorkflowId)),
431
+ childHandle.result()
432
+ ]);
433
+ if (!childResults.has(childWorkflowId)) {
434
+ await condition(() => childResults.has(childWorkflowId));
435
+ }
436
+ const childResult = childResults.get(childWorkflowId);
437
+ childResults.delete(childWorkflowId);
438
+ if (!childResult) {
439
+ return {
440
+ toolResponse: "Subagent workflow did not signal a result",
441
+ data: null
442
+ };
443
+ }
377
444
  const {
378
445
  toolResponse,
379
446
  data,
380
447
  usage,
381
- threadId: childThreadId
382
- } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
448
+ threadId: childThreadId,
449
+ sandboxId: childSandboxId,
450
+ metadata
451
+ } = childResult;
452
+ if (allowsContinuation && childSandboxId && childThreadId) {
453
+ threadSandboxes.set(childThreadId, childSandboxId);
454
+ }
383
455
  if (!toolResponse) {
384
456
  return {
385
457
  toolResponse: "Subagent workflow returned no response",
386
458
  data: null,
387
- ...usage && { usage }
459
+ ...usage && { usage },
460
+ ...childSandboxId && { sandboxId: childSandboxId },
461
+ ...metadata && { metadata }
388
462
  };
389
463
  }
390
464
  const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
@@ -392,11 +466,13 @@ function createSubagentHandler(subagents) {
392
466
  return {
393
467
  toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
394
468
  data: null,
395
- ...usage && { usage }
469
+ ...usage && { usage },
470
+ ...childSandboxId && { sandboxId: childSandboxId },
471
+ ...metadata && { metadata }
396
472
  };
397
473
  }
398
474
  let finalToolResponse = toolResponse;
399
- if (config.allowThreadContinuation && childThreadId) {
475
+ if (allowsContinuation && childThreadId) {
400
476
  finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
401
477
 
402
478
  [${config.agentName} Thread ID: ${childThreadId}]` : toolResponse;
@@ -404,9 +480,22 @@ function createSubagentHandler(subagents) {
404
480
  return {
405
481
  toolResponse: finalToolResponse,
406
482
  data: validated ? validated.data : data,
407
- ...usage && { usage }
483
+ ...usage && { usage },
484
+ ...childSandboxId && { sandboxId: childSandboxId },
485
+ ...metadata && { metadata }
408
486
  };
409
487
  };
488
+ const destroySubagentSandboxes = async () => {
489
+ const handles = [...pendingDestroys.values()];
490
+ pendingDestroys.clear();
491
+ await Promise.all(
492
+ handles.map(async (handle) => {
493
+ await handle.signal(destroySandboxSignal);
494
+ await handle.result();
495
+ })
496
+ );
497
+ };
498
+ return { handler, destroySubagentSandboxes };
410
499
  }
411
500
 
412
501
  // src/lib/subagent/register.ts
@@ -420,12 +509,13 @@ function buildSubagentRegistration(subagents) {
420
509
  if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
421
510
  }
422
511
  const resolveSubagentName = (args) => args.subagent;
423
- return {
512
+ const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
513
+ const registration = {
424
514
  name: SUBAGENT_TOOL_NAME,
425
515
  enabled: () => getEnabled().length > 0,
426
516
  description: () => createSubagentTool(getEnabled()).description,
427
517
  schema: () => createSubagentTool(getEnabled()).schema,
428
- handler: createSubagentHandler(subagents),
518
+ handler,
429
519
  ...subagentHooksMap.size > 0 && {
430
520
  hooks: {
431
521
  onPreToolUse: async (ctx) => {
@@ -443,6 +533,7 @@ function buildSubagentRegistration(subagents) {
443
533
  }
444
534
  }
445
535
  };
536
+ return { registration, destroySubagentSandboxes };
446
537
  }
447
538
  var READ_SKILL_TOOL_NAME = "ReadSkill";
448
539
  function buildReadSkillDescription(skills) {
@@ -495,8 +586,7 @@ function buildSkillRegistration(skills) {
495
586
  handler: createReadSkillHandler(skills)
496
587
  };
497
588
  }
498
- var createSession = async ({
499
- threadId: providedThreadId,
589
+ async function createSession({
500
590
  agentName,
501
591
  maxTurns = 50,
502
592
  metadata = {},
@@ -509,24 +599,42 @@ var createSession = async ({
509
599
  processToolsInParallel = true,
510
600
  hooks = {},
511
601
  appendSystemPrompt = true,
512
- continueThread = false,
513
602
  waitForInputTimeout = "48h",
514
- sandbox: sandboxOps,
515
- sandboxId: inheritedSandboxId
516
- }) => {
517
- const sourceThreadId = continueThread ? providedThreadId : void 0;
518
- const threadId = continueThread && providedThreadId ? getShortId() : providedThreadId ?? getShortId();
603
+ sandboxOps,
604
+ thread: threadInit,
605
+ sandbox: sandboxInit,
606
+ sandboxShutdown = "destroy"
607
+ }) {
608
+ const threadMode = threadInit?.mode ?? "new";
609
+ let threadId;
610
+ let sourceThreadId;
611
+ switch (threadMode) {
612
+ case "new":
613
+ threadId = threadInit?.mode === "new" && threadInit.threadId ? threadInit.threadId : getShortId();
614
+ break;
615
+ case "continue":
616
+ threadId = threadInit.threadId;
617
+ break;
618
+ case "fork":
619
+ sourceThreadId = threadInit.threadId;
620
+ threadId = getShortId();
621
+ break;
622
+ }
519
623
  const {
520
624
  appendToolResult,
521
625
  appendHumanMessage,
522
626
  initializeThread,
523
627
  appendSystemMessage,
524
628
  forkThread
525
- } = threadOps ?? proxyDefaultThreadOps();
629
+ } = threadOps;
526
630
  const plugins = [];
631
+ let destroySubagentSandboxes;
527
632
  if (subagents) {
528
- const reg = buildSubagentRegistration(subagents);
529
- if (reg) plugins.push(reg);
633
+ const result = buildSubagentRegistration(subagents);
634
+ if (result) {
635
+ plugins.push(result.registration);
636
+ destroySubagentSandboxes = result.destroySubagentSandboxes;
637
+ }
530
638
  }
531
639
  if (skills) {
532
640
  const reg = buildSkillRegistration(skills);
@@ -574,11 +682,41 @@ var createSession = async ({
574
682
  stateManager.run();
575
683
  }
576
684
  );
577
- let sandboxId = inheritedSandboxId;
578
- const ownsSandbox = !sandboxId && !!sandboxOps;
579
- if (ownsSandbox) {
580
- const result = await sandboxOps.createSandbox({ id: threadId });
685
+ const sandboxMode = sandboxInit?.mode;
686
+ let sandboxId;
687
+ let sandboxOwned = false;
688
+ if (sandboxMode === "inherit") {
689
+ sandboxId = sandboxInit.sandboxId;
690
+ if (!sandboxOps) {
691
+ throw ApplicationFailure.create({
692
+ message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
693
+ nonRetryable: true
694
+ });
695
+ }
696
+ } else if (sandboxMode === "continue") {
697
+ if (!sandboxOps) {
698
+ throw ApplicationFailure.create({
699
+ message: "No sandboxOps provided \u2014 cannot continue sandbox",
700
+ nonRetryable: true
701
+ });
702
+ }
703
+ sandboxId = sandboxInit.sandboxId;
704
+ sandboxOwned = true;
705
+ } else if (sandboxMode === "fork") {
706
+ if (!sandboxOps) {
707
+ throw ApplicationFailure.create({
708
+ message: "No sandboxOps provided \u2014 cannot fork sandbox",
709
+ nonRetryable: true
710
+ });
711
+ }
712
+ sandboxId = await sandboxOps.forkSandbox(
713
+ sandboxInit.sandboxId
714
+ );
715
+ sandboxOwned = true;
716
+ } else if (sandboxOps) {
717
+ const result = await sandboxOps.createSandbox();
581
718
  sandboxId = result.sandboxId;
719
+ sandboxOwned = true;
582
720
  if (result.stateUpdate) {
583
721
  stateManager.mergeUpdate(result.stateUpdate);
584
722
  }
@@ -591,9 +729,9 @@ var createSession = async ({
591
729
  });
592
730
  }
593
731
  const systemPrompt = stateManager.getSystemPrompt();
594
- if (continueThread && sourceThreadId) {
732
+ if (threadMode === "fork" && sourceThreadId) {
595
733
  await forkThread(sourceThreadId, threadId);
596
- } else {
734
+ } else if (threadMode === "continue") ; else {
597
735
  if (appendSystemPrompt) {
598
736
  if (!systemPrompt || systemPrompt.trim() === "") {
599
737
  throw ApplicationFailure.create({
@@ -628,7 +766,8 @@ var createSession = async ({
628
766
  threadId,
629
767
  finalMessage: message,
630
768
  exitReason,
631
- usage: stateManager.getTotalUsage()
769
+ usage: stateManager.getTotalUsage(),
770
+ sandboxId
632
771
  };
633
772
  }
634
773
  const parsedToolCalls = [];
@@ -679,55 +818,40 @@ var createSession = async ({
679
818
  throw ApplicationFailure.fromError(error);
680
819
  } finally {
681
820
  await callSessionEnd(exitReason, stateManager.getTurns());
682
- if (ownsSandbox && sandboxId && sandboxOps) {
683
- await sandboxOps.destroySandbox(sandboxId);
821
+ if (sandboxOwned && sandboxId && sandboxOps) {
822
+ switch (sandboxShutdown) {
823
+ case "destroy":
824
+ await sandboxOps.destroySandbox(sandboxId);
825
+ break;
826
+ case "pause":
827
+ case "pause-until-parent-close":
828
+ await sandboxOps.pauseSandbox(sandboxId);
829
+ break;
830
+ }
831
+ }
832
+ if (destroySubagentSandboxes) {
833
+ await destroySubagentSandboxes();
684
834
  }
685
835
  }
686
836
  return {
687
837
  threadId,
688
838
  finalMessage: null,
689
839
  exitReason,
690
- usage: stateManager.getTotalUsage()
840
+ usage: stateManager.getTotalUsage(),
841
+ sandboxId
691
842
  };
692
843
  }
693
844
  };
694
- };
695
- function proxyDefaultThreadOps(options) {
696
- return proxyActivities(
697
- options ?? {
698
- startToCloseTimeout: "10s",
699
- retry: {
700
- maximumAttempts: 6,
701
- initialInterval: "5s",
702
- maximumInterval: "15m",
703
- backoffCoefficient: 4
704
- }
705
- }
706
- );
707
- }
708
- function proxySandboxOps(options) {
709
- return proxyActivities(
710
- options ?? {
711
- startToCloseTimeout: "30s",
712
- retry: {
713
- maximumAttempts: 3,
714
- initialInterval: "2s",
715
- maximumInterval: "30s",
716
- backoffCoefficient: 2
717
- }
718
- }
719
- );
720
845
  }
721
846
 
722
847
  // src/lib/workflow.ts
723
848
  function defineWorkflow(config, fn) {
724
849
  const workflow = async (input, workflowInput = {}) => {
725
850
  const sessionInput = {
726
- ...workflowInput.previousThreadId && {
727
- threadId: workflowInput.previousThreadId,
728
- continueThread: true
729
- },
730
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
851
+ agentName: config.name,
852
+ sandboxShutdown: config.sandboxShutdown ?? "destroy",
853
+ ...workflowInput.thread && { thread: workflowInput.thread },
854
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
731
855
  };
732
856
  return fn(input, sessionInput);
733
857
  };
@@ -908,19 +1032,55 @@ function defineSubagent(definition, overrides) {
908
1032
  ...overrides
909
1033
  };
910
1034
  }
911
-
912
- // src/lib/subagent/workflow.ts
913
1035
  function defineSubagentWorkflow(config, fn) {
914
1036
  const workflow = async (prompt, workflowInput, context) => {
1037
+ const effectiveShutdown = workflowInput.sandboxShutdown ?? config.sandboxShutdown ?? "destroy";
915
1038
  const sessionInput = {
916
1039
  agentName: config.name,
917
- ...workflowInput.previousThreadId && {
918
- threadId: workflowInput.previousThreadId,
919
- continueThread: true
920
- },
921
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
1040
+ sandboxShutdown: effectiveShutdown,
1041
+ ...workflowInput.thread && { thread: workflowInput.thread },
1042
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
922
1043
  };
923
- return fn(prompt, sessionInput, context ?? {});
1044
+ const { destroySandbox, ...result } = await fn(
1045
+ prompt,
1046
+ sessionInput,
1047
+ context ?? {}
1048
+ );
1049
+ if (effectiveShutdown === "pause-until-parent-close") {
1050
+ if (!destroySandbox) {
1051
+ throw ApplicationFailure.create({
1052
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a destroySandbox callback`,
1053
+ nonRetryable: true
1054
+ });
1055
+ }
1056
+ if (!result.sandboxId) {
1057
+ throw ApplicationFailure.create({
1058
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a sandboxId`,
1059
+ nonRetryable: true
1060
+ });
1061
+ }
1062
+ }
1063
+ const { parent } = workflowInfo();
1064
+ if (!parent) {
1065
+ throw ApplicationFailure.create({
1066
+ message: "Subagent workflow called without a parent workflow",
1067
+ nonRetryable: true
1068
+ });
1069
+ }
1070
+ const parentHandle = getExternalWorkflowHandle(parent.workflowId);
1071
+ await parentHandle.signal(childResultSignal, {
1072
+ childWorkflowId: workflowInfo().workflowId,
1073
+ result
1074
+ });
1075
+ if (destroySandbox) {
1076
+ let destroyRequested = false;
1077
+ setHandler(destroySandboxSignal, () => {
1078
+ destroyRequested = true;
1079
+ });
1080
+ await condition(() => destroyRequested);
1081
+ await destroySandbox();
1082
+ }
1083
+ return result;
924
1084
  };
925
1085
  Object.defineProperty(workflow, "name", { value: config.name });
926
1086
  return Object.assign(workflow, {
@@ -1483,6 +1643,6 @@ var createAskUserQuestionHandler = () => async (args) => {
1483
1643
  };
1484
1644
  };
1485
1645
 
1486
- export { SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyDefaultThreadOps, proxySandboxOps, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
1646
+ export { SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
1487
1647
  //# sourceMappingURL=workflow.js.map
1488
1648
  //# sourceMappingURL=workflow.js.map