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/index.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 { randomUUID, randomFillSync } from 'crypto';
4
4
  import { ApplicationFailure as ApplicationFailure$1 } from '@temporalio/common';
@@ -82,7 +82,12 @@ function createToolRouter(options) {
82
82
  result: { error: errorStr, suppressed: true }
83
83
  };
84
84
  }
85
- throw ApplicationFailure.fromError(error, { nonRetryable: true });
85
+ return {
86
+ content: JSON.stringify({
87
+ error: "The tool encountered an error. Please try again or use a different approach."
88
+ }),
89
+ result: { error: errorStr, suppressed: true }
90
+ };
86
91
  }
87
92
  async function runPostHooks(toolCall, tool, toolResult, effectiveArgs, turn, durationMs) {
88
93
  if (tool?.hooks?.onPostToolUse) {
@@ -91,7 +96,8 @@ function createToolRouter(options) {
91
96
  result: toolResult.data,
92
97
  threadId: options.threadId,
93
98
  turn,
94
- durationMs
99
+ durationMs,
100
+ ...toolResult.metadata && { metadata: toolResult.metadata }
95
101
  });
96
102
  }
97
103
  if (options.hooks?.onPostToolUse) {
@@ -124,6 +130,7 @@ function createToolRouter(options) {
124
130
  let result;
125
131
  let content;
126
132
  let resultAppended = false;
133
+ let metadata;
127
134
  try {
128
135
  if (tool) {
129
136
  const routerContext = {
@@ -139,6 +146,7 @@ function createToolRouter(options) {
139
146
  result = response.data;
140
147
  content = response.toolResponse;
141
148
  resultAppended = response.resultAppended === true;
149
+ metadata = response.metadata;
142
150
  } else {
143
151
  result = { error: `Unknown tool: ${toolCall.name}` };
144
152
  content = JSON.stringify(result, null, 2);
@@ -171,7 +179,8 @@ function createToolRouter(options) {
171
179
  const toolResult = {
172
180
  toolCallId: toolCall.id,
173
181
  name: toolCall.name,
174
- data: result
182
+ data: result,
183
+ ...metadata && { metadata }
175
184
  };
176
185
  await runPostHooks(
177
186
  toolCall,
@@ -275,7 +284,8 @@ function createToolRouter(options) {
275
284
  return {
276
285
  toolCallId: toolCall.id,
277
286
  name: toolCall.name,
278
- data: response.data
287
+ data: response.data,
288
+ ...response.metadata && { metadata: response.metadata }
279
289
  };
280
290
  };
281
291
  if (options.parallel) {
@@ -319,7 +329,7 @@ function getShortId(length = 12) {
319
329
  var SUBAGENT_TOOL_NAME = "Subagent";
320
330
  function buildSubagentDescription(subagents) {
321
331
  const subagentList = subagents.map((s) => {
322
- const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
332
+ const continuation = s.thread && s.thread !== "new" ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
323
333
  return `## ${s.agentName}
324
334
  ${s.description}${continuation}`;
325
335
  }).join("\n\n");
@@ -335,7 +345,7 @@ function createSubagentTool(subagents) {
335
345
  }
336
346
  const names = subagents.map((s) => s.agentName);
337
347
  const hasThreadContinuation = subagents.some(
338
- (s) => s.allowThreadContinuation
348
+ (s) => s.thread && s.thread !== "new"
339
349
  );
340
350
  const baseFields = {
341
351
  subagent: z14.enum(names).describe("The type of subagent to launch"),
@@ -354,9 +364,25 @@ function createSubagentTool(subagents) {
354
364
  schema
355
365
  };
356
366
  }
367
+ var childResultSignal = defineSignal("childResult");
368
+ var destroySandboxSignal = defineSignal("destroySandbox");
369
+
370
+ // src/lib/subagent/handler.ts
371
+ function resolveSandboxConfig(config) {
372
+ if (!config || config === "none") return { source: "none" };
373
+ if (config === "inherit") return { source: "inherit" };
374
+ if (config === "own") return { source: "own" };
375
+ return { source: "own", shutdown: config.shutdown };
376
+ }
357
377
  function createSubagentHandler(subagents) {
358
378
  const { taskQueue: parentTaskQueue } = workflowInfo();
359
- return async (args, context) => {
379
+ const childResults = /* @__PURE__ */ new Map();
380
+ const pendingDestroys = /* @__PURE__ */ new Map();
381
+ const threadSandboxes = /* @__PURE__ */ new Map();
382
+ setHandler(childResultSignal, ({ childWorkflowId, result }) => {
383
+ childResults.set(childWorkflowId, result);
384
+ });
385
+ const handler = async (args, context) => {
360
386
  const config = subagents.find((s) => s.agentName === args.subagent);
361
387
  if (!config) {
362
388
  throw new Error(
@@ -365,29 +391,77 @@ function createSubagentHandler(subagents) {
365
391
  }
366
392
  const childWorkflowId = `${args.subagent}-${getShortId()}`;
367
393
  const { sandboxId: parentSandboxId } = context;
368
- const inheritSandbox = config.sandbox !== "own" && !!parentSandboxId;
394
+ const sandboxCfg = resolveSandboxConfig(config.sandbox);
395
+ if (sandboxCfg.source === "inherit" && !parentSandboxId) {
396
+ throw new Error(
397
+ `Subagent "${config.agentName}" is configured with sandbox: "inherit" but the parent has no sandbox`
398
+ );
399
+ }
400
+ const threadMode = config.thread ?? "new";
401
+ const allowsContinuation = threadMode !== "new";
402
+ const continuationThreadId = args.threadId && allowsContinuation ? args.threadId : void 0;
403
+ let thread;
404
+ if (continuationThreadId) {
405
+ thread = { mode: threadMode, threadId: continuationThreadId };
406
+ }
407
+ let sandbox;
408
+ if (sandboxCfg.source === "inherit" && parentSandboxId) {
409
+ sandbox = { mode: "inherit", sandboxId: parentSandboxId };
410
+ } else if (sandboxCfg.source === "own") {
411
+ const prevSbId = continuationThreadId ? threadSandboxes.get(continuationThreadId) : void 0;
412
+ if (prevSbId) {
413
+ sandbox = { mode: "fork", sandboxId: prevSbId };
414
+ }
415
+ }
369
416
  const workflowInput = {
370
- ...args.threadId && args.threadId !== null && config.allowThreadContinuation && {
371
- previousThreadId: args.threadId
372
- },
373
- ...inheritSandbox && { sandboxId: parentSandboxId }
417
+ ...thread && { thread },
418
+ ...sandbox && { sandbox },
419
+ ...sandboxCfg.shutdown && { sandboxShutdown: sandboxCfg.shutdown }
374
420
  };
421
+ const resolvedContext = config.context === void 0 ? void 0 : typeof config.context === "function" ? config.context() : config.context;
375
422
  const childOpts = {
376
423
  workflowId: childWorkflowId,
377
- args: config.context === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, config.context],
424
+ args: resolvedContext === void 0 ? [args.prompt, workflowInput] : [args.prompt, workflowInput, resolvedContext],
378
425
  taskQueue: config.taskQueue ?? parentTaskQueue
379
426
  };
427
+ const childHandle = await startChild(config.workflow, childOpts);
428
+ const usesOwnSandbox = sandboxCfg.source === "own" || allowsContinuation && sandboxCfg.source !== "inherit";
429
+ if (usesOwnSandbox) {
430
+ pendingDestroys.set(childWorkflowId, childHandle);
431
+ }
432
+ await Promise.race([
433
+ condition(() => childResults.has(childWorkflowId)),
434
+ childHandle.result()
435
+ ]);
436
+ if (!childResults.has(childWorkflowId)) {
437
+ await condition(() => childResults.has(childWorkflowId));
438
+ }
439
+ const childResult = childResults.get(childWorkflowId);
440
+ childResults.delete(childWorkflowId);
441
+ if (!childResult) {
442
+ return {
443
+ toolResponse: "Subagent workflow did not signal a result",
444
+ data: null
445
+ };
446
+ }
380
447
  const {
381
448
  toolResponse,
382
449
  data,
383
450
  usage,
384
- threadId: childThreadId
385
- } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
451
+ threadId: childThreadId,
452
+ sandboxId: childSandboxId,
453
+ metadata
454
+ } = childResult;
455
+ if (allowsContinuation && childSandboxId && childThreadId) {
456
+ threadSandboxes.set(childThreadId, childSandboxId);
457
+ }
386
458
  if (!toolResponse) {
387
459
  return {
388
460
  toolResponse: "Subagent workflow returned no response",
389
461
  data: null,
390
- ...usage && { usage }
462
+ ...usage && { usage },
463
+ ...childSandboxId && { sandboxId: childSandboxId },
464
+ ...metadata && { metadata }
391
465
  };
392
466
  }
393
467
  const validated = config.resultSchema ? config.resultSchema.safeParse(data) : null;
@@ -395,11 +469,13 @@ function createSubagentHandler(subagents) {
395
469
  return {
396
470
  toolResponse: `Subagent workflow returned invalid data: ${validated.error.message}`,
397
471
  data: null,
398
- ...usage && { usage }
472
+ ...usage && { usage },
473
+ ...childSandboxId && { sandboxId: childSandboxId },
474
+ ...metadata && { metadata }
399
475
  };
400
476
  }
401
477
  let finalToolResponse = toolResponse;
402
- if (config.allowThreadContinuation && childThreadId) {
478
+ if (allowsContinuation && childThreadId) {
403
479
  finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
404
480
 
405
481
  [${config.agentName} Thread ID: ${childThreadId}]` : toolResponse;
@@ -407,9 +483,22 @@ function createSubagentHandler(subagents) {
407
483
  return {
408
484
  toolResponse: finalToolResponse,
409
485
  data: validated ? validated.data : data,
410
- ...usage && { usage }
486
+ ...usage && { usage },
487
+ ...childSandboxId && { sandboxId: childSandboxId },
488
+ ...metadata && { metadata }
411
489
  };
412
490
  };
491
+ const destroySubagentSandboxes = async () => {
492
+ const handles = [...pendingDestroys.values()];
493
+ pendingDestroys.clear();
494
+ await Promise.all(
495
+ handles.map(async (handle) => {
496
+ await handle.signal(destroySandboxSignal);
497
+ await handle.result();
498
+ })
499
+ );
500
+ };
501
+ return { handler, destroySubagentSandboxes };
413
502
  }
414
503
 
415
504
  // src/lib/subagent/register.ts
@@ -423,12 +512,13 @@ function buildSubagentRegistration(subagents) {
423
512
  if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
424
513
  }
425
514
  const resolveSubagentName = (args) => args.subagent;
426
- return {
515
+ const { handler, destroySubagentSandboxes } = createSubagentHandler(subagents);
516
+ const registration = {
427
517
  name: SUBAGENT_TOOL_NAME,
428
518
  enabled: () => getEnabled().length > 0,
429
519
  description: () => createSubagentTool(getEnabled()).description,
430
520
  schema: () => createSubagentTool(getEnabled()).schema,
431
- handler: createSubagentHandler(subagents),
521
+ handler,
432
522
  ...subagentHooksMap.size > 0 && {
433
523
  hooks: {
434
524
  onPreToolUse: async (ctx) => {
@@ -446,6 +536,7 @@ function buildSubagentRegistration(subagents) {
446
536
  }
447
537
  }
448
538
  };
539
+ return { registration, destroySubagentSandboxes };
449
540
  }
450
541
  var READ_SKILL_TOOL_NAME = "ReadSkill";
451
542
  function buildReadSkillDescription(skills) {
@@ -498,8 +589,7 @@ function buildSkillRegistration(skills) {
498
589
  handler: createReadSkillHandler(skills)
499
590
  };
500
591
  }
501
- var createSession = async ({
502
- threadId: providedThreadId,
592
+ async function createSession({
503
593
  agentName,
504
594
  maxTurns = 50,
505
595
  metadata = {},
@@ -512,24 +602,42 @@ var createSession = async ({
512
602
  processToolsInParallel = true,
513
603
  hooks = {},
514
604
  appendSystemPrompt = true,
515
- continueThread = false,
516
605
  waitForInputTimeout = "48h",
517
- sandbox: sandboxOps,
518
- sandboxId: inheritedSandboxId
519
- }) => {
520
- const sourceThreadId = continueThread ? providedThreadId : void 0;
521
- const threadId = continueThread && providedThreadId ? getShortId() : providedThreadId ?? getShortId();
606
+ sandboxOps,
607
+ thread: threadInit,
608
+ sandbox: sandboxInit,
609
+ sandboxShutdown = "destroy"
610
+ }) {
611
+ const threadMode = threadInit?.mode ?? "new";
612
+ let threadId;
613
+ let sourceThreadId;
614
+ switch (threadMode) {
615
+ case "new":
616
+ threadId = threadInit?.mode === "new" && threadInit.threadId ? threadInit.threadId : getShortId();
617
+ break;
618
+ case "continue":
619
+ threadId = threadInit.threadId;
620
+ break;
621
+ case "fork":
622
+ sourceThreadId = threadInit.threadId;
623
+ threadId = getShortId();
624
+ break;
625
+ }
522
626
  const {
523
627
  appendToolResult,
524
628
  appendHumanMessage,
525
629
  initializeThread,
526
630
  appendSystemMessage,
527
631
  forkThread
528
- } = threadOps ?? proxyDefaultThreadOps();
632
+ } = threadOps;
529
633
  const plugins = [];
634
+ let destroySubagentSandboxes;
530
635
  if (subagents) {
531
- const reg = buildSubagentRegistration(subagents);
532
- if (reg) plugins.push(reg);
636
+ const result = buildSubagentRegistration(subagents);
637
+ if (result) {
638
+ plugins.push(result.registration);
639
+ destroySubagentSandboxes = result.destroySubagentSandboxes;
640
+ }
533
641
  }
534
642
  if (skills) {
535
643
  const reg = buildSkillRegistration(skills);
@@ -577,11 +685,41 @@ var createSession = async ({
577
685
  stateManager.run();
578
686
  }
579
687
  );
580
- let sandboxId = inheritedSandboxId;
581
- const ownsSandbox = !sandboxId && !!sandboxOps;
582
- if (ownsSandbox) {
583
- const result = await sandboxOps.createSandbox({ id: threadId });
688
+ const sandboxMode = sandboxInit?.mode;
689
+ let sandboxId;
690
+ let sandboxOwned = false;
691
+ if (sandboxMode === "inherit") {
692
+ sandboxId = sandboxInit.sandboxId;
693
+ if (!sandboxOps) {
694
+ throw ApplicationFailure.create({
695
+ message: "sandboxId provided but no sandboxOps \u2014 cannot manage sandbox lifecycle",
696
+ nonRetryable: true
697
+ });
698
+ }
699
+ } else if (sandboxMode === "continue") {
700
+ if (!sandboxOps) {
701
+ throw ApplicationFailure.create({
702
+ message: "No sandboxOps provided \u2014 cannot continue sandbox",
703
+ nonRetryable: true
704
+ });
705
+ }
706
+ sandboxId = sandboxInit.sandboxId;
707
+ sandboxOwned = true;
708
+ } else if (sandboxMode === "fork") {
709
+ if (!sandboxOps) {
710
+ throw ApplicationFailure.create({
711
+ message: "No sandboxOps provided \u2014 cannot fork sandbox",
712
+ nonRetryable: true
713
+ });
714
+ }
715
+ sandboxId = await sandboxOps.forkSandbox(
716
+ sandboxInit.sandboxId
717
+ );
718
+ sandboxOwned = true;
719
+ } else if (sandboxOps) {
720
+ const result = await sandboxOps.createSandbox();
584
721
  sandboxId = result.sandboxId;
722
+ sandboxOwned = true;
585
723
  if (result.stateUpdate) {
586
724
  stateManager.mergeUpdate(result.stateUpdate);
587
725
  }
@@ -594,9 +732,9 @@ var createSession = async ({
594
732
  });
595
733
  }
596
734
  const systemPrompt = stateManager.getSystemPrompt();
597
- if (continueThread && sourceThreadId) {
735
+ if (threadMode === "fork" && sourceThreadId) {
598
736
  await forkThread(sourceThreadId, threadId);
599
- } else {
737
+ } else if (threadMode === "continue") ; else {
600
738
  if (appendSystemPrompt) {
601
739
  if (!systemPrompt || systemPrompt.trim() === "") {
602
740
  throw ApplicationFailure.create({
@@ -631,7 +769,8 @@ var createSession = async ({
631
769
  threadId,
632
770
  finalMessage: message,
633
771
  exitReason,
634
- usage: stateManager.getTotalUsage()
772
+ usage: stateManager.getTotalUsage(),
773
+ sandboxId
635
774
  };
636
775
  }
637
776
  const parsedToolCalls = [];
@@ -682,55 +821,40 @@ var createSession = async ({
682
821
  throw ApplicationFailure.fromError(error);
683
822
  } finally {
684
823
  await callSessionEnd(exitReason, stateManager.getTurns());
685
- if (ownsSandbox && sandboxId && sandboxOps) {
686
- await sandboxOps.destroySandbox(sandboxId);
824
+ if (sandboxOwned && sandboxId && sandboxOps) {
825
+ switch (sandboxShutdown) {
826
+ case "destroy":
827
+ await sandboxOps.destroySandbox(sandboxId);
828
+ break;
829
+ case "pause":
830
+ case "pause-until-parent-close":
831
+ await sandboxOps.pauseSandbox(sandboxId);
832
+ break;
833
+ }
834
+ }
835
+ if (destroySubagentSandboxes) {
836
+ await destroySubagentSandboxes();
687
837
  }
688
838
  }
689
839
  return {
690
840
  threadId,
691
841
  finalMessage: null,
692
842
  exitReason,
693
- usage: stateManager.getTotalUsage()
843
+ usage: stateManager.getTotalUsage(),
844
+ sandboxId
694
845
  };
695
846
  }
696
847
  };
697
- };
698
- function proxyDefaultThreadOps(options) {
699
- return proxyActivities(
700
- options ?? {
701
- startToCloseTimeout: "10s",
702
- retry: {
703
- maximumAttempts: 6,
704
- initialInterval: "5s",
705
- maximumInterval: "15m",
706
- backoffCoefficient: 4
707
- }
708
- }
709
- );
710
- }
711
- function proxySandboxOps(options) {
712
- return proxyActivities(
713
- options ?? {
714
- startToCloseTimeout: "30s",
715
- retry: {
716
- maximumAttempts: 3,
717
- initialInterval: "2s",
718
- maximumInterval: "30s",
719
- backoffCoefficient: 2
720
- }
721
- }
722
- );
723
848
  }
724
849
 
725
850
  // src/lib/workflow.ts
726
851
  function defineWorkflow(config, fn) {
727
852
  const workflow = async (input, workflowInput = {}) => {
728
853
  const sessionInput = {
729
- ...workflowInput.previousThreadId && {
730
- threadId: workflowInput.previousThreadId,
731
- continueThread: true
732
- },
733
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
854
+ agentName: config.name,
855
+ sandboxShutdown: config.sandboxShutdown ?? "destroy",
856
+ ...workflowInput.thread && { thread: workflowInput.thread },
857
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
734
858
  };
735
859
  return fn(input, sessionInput);
736
860
  };
@@ -988,19 +1112,55 @@ function defineSubagent(definition, overrides) {
988
1112
  ...overrides
989
1113
  };
990
1114
  }
991
-
992
- // src/lib/subagent/workflow.ts
993
1115
  function defineSubagentWorkflow(config, fn) {
994
1116
  const workflow = async (prompt, workflowInput, context) => {
1117
+ const effectiveShutdown = workflowInput.sandboxShutdown ?? config.sandboxShutdown ?? "destroy";
995
1118
  const sessionInput = {
996
1119
  agentName: config.name,
997
- ...workflowInput.previousThreadId && {
998
- threadId: workflowInput.previousThreadId,
999
- continueThread: true
1000
- },
1001
- ...workflowInput.sandboxId && { sandboxId: workflowInput.sandboxId }
1120
+ sandboxShutdown: effectiveShutdown,
1121
+ ...workflowInput.thread && { thread: workflowInput.thread },
1122
+ ...workflowInput.sandbox && { sandbox: workflowInput.sandbox }
1002
1123
  };
1003
- return fn(prompt, sessionInput, context ?? {});
1124
+ const { destroySandbox, ...result } = await fn(
1125
+ prompt,
1126
+ sessionInput,
1127
+ context ?? {}
1128
+ );
1129
+ if (effectiveShutdown === "pause-until-parent-close") {
1130
+ if (!destroySandbox) {
1131
+ throw ApplicationFailure.create({
1132
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a destroySandbox callback`,
1133
+ nonRetryable: true
1134
+ });
1135
+ }
1136
+ if (!result.sandboxId) {
1137
+ throw ApplicationFailure.create({
1138
+ message: `Subagent "${config.name}" has sandboxShutdown="pause-until-parent-close" but fn did not return a sandboxId`,
1139
+ nonRetryable: true
1140
+ });
1141
+ }
1142
+ }
1143
+ const { parent } = workflowInfo();
1144
+ if (!parent) {
1145
+ throw ApplicationFailure.create({
1146
+ message: "Subagent workflow called without a parent workflow",
1147
+ nonRetryable: true
1148
+ });
1149
+ }
1150
+ const parentHandle = getExternalWorkflowHandle(parent.workflowId);
1151
+ await parentHandle.signal(childResultSignal, {
1152
+ childWorkflowId: workflowInfo().workflowId,
1153
+ result
1154
+ });
1155
+ if (destroySandbox) {
1156
+ let destroyRequested = false;
1157
+ setHandler(destroySandboxSignal, () => {
1158
+ destroyRequested = true;
1159
+ });
1160
+ await condition(() => destroyRequested);
1161
+ await destroySandbox();
1162
+ }
1163
+ return result;
1004
1164
  };
1005
1165
  Object.defineProperty(workflow, "name", { value: config.name });
1006
1166
  return Object.assign(workflow, {
@@ -1735,6 +1895,9 @@ var SandboxManager = class {
1735
1895
  async destroy(id) {
1736
1896
  await this.provider.destroy(id);
1737
1897
  }
1898
+ async pause(id, ttlSeconds) {
1899
+ await this.provider.pause(id, ttlSeconds);
1900
+ }
1738
1901
  async snapshot(id) {
1739
1902
  return this.provider.snapshot(id);
1740
1903
  }
@@ -1742,22 +1905,53 @@ var SandboxManager = class {
1742
1905
  const sandbox = await this.provider.restore(snapshot);
1743
1906
  return sandbox.id;
1744
1907
  }
1908
+ async fork(sandboxId) {
1909
+ const sandbox = await this.provider.fork(sandboxId);
1910
+ return sandbox.id;
1911
+ }
1745
1912
  /**
1746
- * Returns Temporal activity functions matching {@link SandboxOps}.
1747
- * Spread these into your worker's activity map.
1913
+ * Returns Temporal activity functions with prefixed names.
1914
+ *
1915
+ * The provider's `id` is automatically prepended, so you only need
1916
+ * to pass the workflow/scope name. Use the matching `proxy*SandboxOps()`
1917
+ * helper from the adapter's `/workflow` entrypoint on the workflow side.
1918
+ *
1919
+ * @param scope - Workflow name (appended to the provider id)
1920
+ *
1921
+ * @example
1922
+ * ```typescript
1923
+ * const manager = new SandboxManager(new InMemorySandboxProvider());
1924
+ * manager.createActivities("CodingAgent");
1925
+ * // registers: inMemoryCodingAgentCreateSandbox, inMemoryCodingAgentDestroySandbox, …
1926
+ *
1927
+ * const vmgr = new SandboxManager(new VirtualSandboxProvider(resolver));
1928
+ * vmgr.createActivities("CodingAgent");
1929
+ * // registers: virtualCodingAgentCreateSandbox, …
1930
+ * ```
1748
1931
  */
1749
- createActivities() {
1750
- return {
1932
+ createActivities(scope) {
1933
+ const prefix = `${this.provider.id}${scope.charAt(0).toUpperCase()}${scope.slice(1)}`;
1934
+ const ops = {
1751
1935
  createSandbox: async (options) => {
1752
1936
  return this.create(options);
1753
1937
  },
1754
1938
  destroySandbox: async (sandboxId) => {
1755
1939
  await this.destroy(sandboxId);
1756
1940
  },
1941
+ pauseSandbox: async (sandboxId, ttlSeconds) => {
1942
+ await this.pause(sandboxId, ttlSeconds);
1943
+ },
1757
1944
  snapshotSandbox: async (sandboxId) => {
1758
1945
  return this.snapshot(sandboxId);
1946
+ },
1947
+ forkSandbox: async (sandboxId) => {
1948
+ return this.fork(sandboxId);
1759
1949
  }
1760
1950
  };
1951
+ const cap = (s) => s.charAt(0).toUpperCase() + s.slice(1);
1952
+ return Object.fromEntries(
1953
+ Object.entries(ops).map(([k, v]) => [`${prefix}${cap(k)}`, v])
1954
+ );
1761
1955
  }
1762
1956
  };
1763
1957
 
@@ -2015,6 +2209,6 @@ var toTree = async (fs, opts = {}) => {
2015
2209
  return base + subtree;
2016
2210
  };
2017
2211
 
2018
- export { FileSystemSkillProvider, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyDefaultThreadOps, proxySandboxOps, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, writeFileHandler, writeFileTool };
2212
+ export { FileSystemSkillProvider, SandboxManager, SandboxNotFoundError, SandboxNotSupportedError, applyVirtualTreeMutations, askUserQuestionTool, bashHandler, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createRunAgentActivity, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createThreadManager, createToolRouter, defineSubagent, defineSubagentWorkflow, defineTool, defineWorkflow, editHandler, editTool, filesWithMimeType, formatVirtualFileTree, getShortId, globHandler, globTool, grepTool, hasDirectory, hasFileWithMimeType, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, queryParentWorkflowState, readFileHandler, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, toTree, withAutoAppend, withParentWorkflowState, withSandbox, writeFileHandler, writeFileTool };
2019
2213
  //# sourceMappingURL=index.js.map
2020
2214
  //# sourceMappingURL=index.js.map