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
@@ -38,8 +38,13 @@ vi.mock("@temporalio/workflow", () => {
38
38
  condition: async (fn: () => boolean) => fn(),
39
39
  defineUpdate: (name: string) => ({ __type: "update", name }),
40
40
  defineQuery: (name: string) => ({ __type: "query", name }),
41
+ defineSignal: (name: string) => ({ __type: "signal", name }),
41
42
  setHandler: (_def: unknown, _handler: unknown) => {},
42
- uuid4: () => `00000000-0000-0000-0000-${String(++idCounter).padStart(12, "0")}`,
43
+ startChild: async () => ({ result: () => Promise.resolve(null) }),
44
+ workflowInfo: () => ({ taskQueue: "default-queue" }),
45
+ getExternalWorkflowHandle: () => ({ signal: async () => {} }),
46
+ uuid4: () =>
47
+ `00000000-0000-0000-0000-${String(++idCounter).padStart(12, "0")}`,
43
48
  ApplicationFailure: MockApplicationFailure,
44
49
  };
45
50
  });
@@ -59,12 +64,11 @@ function at<T>(arr: T[], index: number): T {
59
64
  return val;
60
65
  }
61
66
 
62
- function toActivityInterface(
63
- raw: ThreadOps,
64
- ): ActivityInterfaceFor<ThreadOps> {
67
+ function toActivityInterface(raw: ThreadOps): ActivityInterfaceFor<ThreadOps> {
65
68
  const result = {} as Record<string, unknown>;
66
69
  for (const [key, fn] of Object.entries(raw)) {
67
- const wrapped = (...args: unknown[]) => (fn as (...a: unknown[]) => unknown)(...args);
70
+ const wrapped = (...args: unknown[]) =>
71
+ (fn as (...a: unknown[]) => unknown)(...args);
68
72
  wrapped.executeWithOptions = (_opts: unknown, args: unknown[]) =>
69
73
  (fn as (...a: unknown[]) => unknown)(...args);
70
74
  result[key] = wrapped;
@@ -79,14 +83,14 @@ function createMockThreadOps() {
79
83
  initializeThread: async (threadId) => {
80
84
  log.push({ op: "initializeThread", args: [threadId] });
81
85
  },
82
- appendHumanMessage: async (threadId, content) => {
83
- log.push({ op: "appendHumanMessage", args: [threadId, content] });
86
+ appendHumanMessage: async (threadId, id, content) => {
87
+ log.push({ op: "appendHumanMessage", args: [threadId, id, content] });
84
88
  },
85
- appendToolResult: async (config) => {
86
- log.push({ op: "appendToolResult", args: [config] });
89
+ appendToolResult: async (id, config) => {
90
+ log.push({ op: "appendToolResult", args: [id, config] });
87
91
  },
88
- appendSystemMessage: async (threadId, content) => {
89
- log.push({ op: "appendSystemMessage", args: [threadId, content] });
92
+ appendSystemMessage: async (threadId, id, content) => {
93
+ log.push({ op: "appendSystemMessage", args: [threadId, id, content] });
90
94
  },
91
95
  forkThread: async (source, target) => {
92
96
  log.push({ op: "forkThread", args: [source, target] });
@@ -102,7 +106,9 @@ type TurnScript = {
102
106
  usage?: TokenUsage;
103
107
  };
104
108
 
105
- function createScriptedRunAgent(turns: TurnScript[]): RunAgentActivity<unknown> {
109
+ function createScriptedRunAgent(
110
+ turns: TurnScript[]
111
+ ): RunAgentActivity<unknown> {
106
112
  let call = 0;
107
113
  return async () => {
108
114
  const turn = turns[call++];
@@ -124,7 +130,7 @@ function createEchoTool() {
124
130
  schema: z.object({ text: z.string() }),
125
131
  handler: async (
126
132
  args: { text: string },
127
- _ctx: RouterContext,
133
+ _ctx: RouterContext
128
134
  ): Promise<ToolHandlerResponse<{ echoed: string }>> => ({
129
135
  toolResponse: `Echo: ${args.text}`,
130
136
  data: { echoed: args.text },
@@ -148,10 +154,8 @@ describe("createSession integration", () => {
148
154
 
149
155
  const session = await createSession({
150
156
  agentName: "TestAgent",
151
- threadId: "thread-1",
152
- runAgent: createScriptedRunAgent([
153
- { message: "Hello!", toolCalls: [] },
154
- ]),
157
+ thread: { mode: "new", threadId: "thread-1" },
158
+ runAgent: createScriptedRunAgent([{ message: "Hello!", toolCalls: [] }]),
155
159
  threadOps: ops,
156
160
  buildContextMessage: () => "What is 2+2?",
157
161
  });
@@ -168,11 +172,11 @@ describe("createSession integration", () => {
168
172
 
169
173
  const systemOps = log.filter((l) => l.op === "appendSystemMessage");
170
174
  expect(systemOps).toHaveLength(1);
171
- expect(at(systemOps, 0).args[1]).toBe("You are a test assistant.");
175
+ expect(at(systemOps, 0).args[2]).toBe("You are a test assistant.");
172
176
 
173
177
  const humanOps = log.filter((l) => l.op === "appendHumanMessage");
174
178
  expect(humanOps).toHaveLength(1);
175
- expect(at(humanOps, 0).args[1]).toBe("What is 2+2?");
179
+ expect(at(humanOps, 0).args[2]).toBe("What is 2+2?");
176
180
  });
177
181
 
178
182
  // --- Tool execution ---
@@ -182,7 +186,7 @@ describe("createSession integration", () => {
182
186
 
183
187
  const session = await createSession({
184
188
  agentName: "TestAgent",
185
- threadId: "thread-1",
189
+ thread: { mode: "new", threadId: "thread-1" },
186
190
  runAgent: createScriptedRunAgent([
187
191
  {
188
192
  message: "Let me echo that.",
@@ -209,7 +213,7 @@ describe("createSession integration", () => {
209
213
 
210
214
  const toolResults = log.filter((l) => l.op === "appendToolResult");
211
215
  expect(toolResults).toHaveLength(1);
212
- const resultConfig = at(toolResults, 0).args[0] as ToolResultConfig;
216
+ const resultConfig = at(toolResults, 0).args[1] as ToolResultConfig;
213
217
  expect(resultConfig.toolName).toBe("Echo");
214
218
  expect(resultConfig.content).toBe("Echo: hello");
215
219
  });
@@ -221,7 +225,7 @@ describe("createSession integration", () => {
221
225
 
222
226
  const session = await createSession({
223
227
  agentName: "TestAgent",
224
- threadId: "thread-1",
228
+ thread: { mode: "new", threadId: "thread-1" },
225
229
  runAgent: createScriptedRunAgent([
226
230
  {
227
231
  message: "turn 1",
@@ -265,12 +269,12 @@ describe("createSession integration", () => {
265
269
  Array.from({ length: 10 }, (_, i) => ({
266
270
  message: `turn ${i + 1}`,
267
271
  toolCalls: [{ id: `tc-${i}`, name: "Echo", args: { text: `${i}` } }],
268
- })),
272
+ }))
269
273
  );
270
274
 
271
275
  const session = await createSession({
272
276
  agentName: "TestAgent",
273
- threadId: "thread-1",
277
+ thread: { mode: "new", threadId: "thread-1" },
274
278
  maxTurns: 3,
275
279
  runAgent: infiniteAgent,
276
280
  threadOps: ops,
@@ -297,10 +301,8 @@ describe("createSession integration", () => {
297
301
 
298
302
  const session = await createSession({
299
303
  agentName: "TestAgent",
300
- threadId: "thread-1",
301
- runAgent: createScriptedRunAgent([
302
- { message: "done", toolCalls: [] },
303
- ]),
304
+ thread: { mode: "new", threadId: "thread-1" },
305
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
304
306
  threadOps: ops,
305
307
  buildContextMessage: () => "hi",
306
308
  hooks: {
@@ -332,7 +334,7 @@ describe("createSession integration", () => {
332
334
 
333
335
  const session = await createSession({
334
336
  agentName: "TestAgent",
335
- threadId: "thread-1",
337
+ thread: { mode: "new", threadId: "thread-1" },
336
338
  runAgent: createScriptedRunAgent([]),
337
339
  threadOps: ops,
338
340
  buildContextMessage: () => "hi",
@@ -343,7 +345,7 @@ describe("createSession integration", () => {
343
345
  });
344
346
 
345
347
  await expect(session.runSession({ stateManager })).rejects.toThrow(
346
- "No system prompt in state",
348
+ "No system prompt in state"
347
349
  );
348
350
  });
349
351
 
@@ -352,11 +354,9 @@ describe("createSession integration", () => {
352
354
 
353
355
  const session = await createSession({
354
356
  agentName: "TestAgent",
355
- threadId: "thread-1",
357
+ thread: { mode: "new", threadId: "thread-1" },
356
358
  appendSystemPrompt: false,
357
- runAgent: createScriptedRunAgent([
358
- { message: "ok", toolCalls: [] },
359
- ]),
359
+ runAgent: createScriptedRunAgent([{ message: "ok", toolCalls: [] }]),
360
360
  threadOps: ops,
361
361
  buildContextMessage: () => "hi",
362
362
  });
@@ -381,7 +381,7 @@ describe("createSession integration", () => {
381
381
 
382
382
  const session = await createSession({
383
383
  agentName: "TestAgent",
384
- threadId: "thread-1",
384
+ thread: { mode: "new", threadId: "thread-1" },
385
385
  runAgent: createScriptedRunAgent([
386
386
  {
387
387
  message: "turn 1",
@@ -417,7 +417,7 @@ describe("createSession integration", () => {
417
417
 
418
418
  const session = await createSession({
419
419
  agentName: "TestAgent",
420
- threadId: "thread-1",
420
+ thread: { mode: "new", threadId: "thread-1" },
421
421
  runAgent: createScriptedRunAgent([
422
422
  {
423
423
  message: "bad call",
@@ -447,23 +447,22 @@ describe("createSession integration", () => {
447
447
  // One error result for bad call + one success result for good call
448
448
  expect(toolResults.length).toBeGreaterThanOrEqual(2);
449
449
  const errorResult = toolResults.find((l) => {
450
- const config = l.args[0] as ToolResultConfig;
450
+ const config = l.args[1] as ToolResultConfig;
451
451
  return config.toolCallId === "tc-bad";
452
452
  });
453
453
  expect(errorResult).toBeDefined();
454
- const errorConfig = errorResult?.args[0] as ToolResultConfig | undefined;
454
+ const errorConfig = errorResult?.args[1] as ToolResultConfig | undefined;
455
455
  expect(errorConfig?.content).toContain("Invalid tool call");
456
456
  });
457
457
 
458
- // --- continueThread ---
458
+ // --- Thread fork mode ---
459
459
 
460
- it("forks thread when continueThread is set", async () => {
460
+ it("forks thread when thread mode is fork", async () => {
461
461
  const { ops, log } = createMockThreadOps();
462
462
 
463
463
  const session = await createSession({
464
464
  agentName: "TestAgent",
465
- threadId: "source-thread",
466
- continueThread: true,
465
+ thread: { mode: "fork", threadId: "source-thread" },
467
466
  runAgent: createScriptedRunAgent([
468
467
  { message: "continued", toolCalls: [] },
469
468
  ]),
@@ -494,9 +493,9 @@ describe("createSession integration", () => {
494
493
  const sandboxLog: string[] = [];
495
494
 
496
495
  const sandboxOps: SandboxOps = {
497
- createSandbox: async (options) => {
498
- sandboxLog.push(`create:${options?.id ?? "unknown"}`);
499
- return { sandboxId: `sb-${options?.id ?? "unknown"}` };
496
+ createSandbox: async () => {
497
+ sandboxLog.push("create");
498
+ return { sandboxId: "sb-1" };
500
499
  },
501
500
  destroySandbox: async (sandboxId: string) => {
502
501
  sandboxLog.push(`destroy:${sandboxId}`);
@@ -507,17 +506,17 @@ describe("createSession integration", () => {
507
506
  data: null,
508
507
  createdAt: new Date().toISOString(),
509
508
  }),
509
+ forkSandbox: async () => "forked-sandbox-id",
510
+ pauseSandbox: async () => {},
510
511
  };
511
512
 
512
513
  const session = await createSession({
513
514
  agentName: "TestAgent",
514
- threadId: "thread-1",
515
- runAgent: createScriptedRunAgent([
516
- { message: "done", toolCalls: [] },
517
- ]),
515
+ thread: { mode: "new", threadId: "thread-1" },
516
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
518
517
  threadOps: ops,
519
518
  buildContextMessage: () => "go",
520
- sandbox: sandboxOps,
519
+ sandboxOps,
521
520
  });
522
521
 
523
522
  const stateManager = createAgentStateManager({
@@ -526,8 +525,8 @@ describe("createSession integration", () => {
526
525
 
527
526
  await session.runSession({ stateManager });
528
527
 
529
- expect(sandboxLog).toContain("create:thread-1");
530
- expect(sandboxLog).toContain("destroy:sb-thread-1");
528
+ expect(sandboxLog).toContain("create");
529
+ expect(sandboxLog).toContain("destroy:sb-1");
531
530
  });
532
531
 
533
532
  it("does not create or destroy sandbox when sandboxId is inherited", async () => {
@@ -548,18 +547,18 @@ describe("createSession integration", () => {
548
547
  data: null,
549
548
  createdAt: new Date().toISOString(),
550
549
  }),
550
+ forkSandbox: async () => "forked-sandbox-id",
551
+ pauseSandbox: async () => {},
551
552
  };
552
553
 
553
554
  const session = await createSession({
554
555
  agentName: "TestAgent",
555
- threadId: "thread-1",
556
- runAgent: createScriptedRunAgent([
557
- { message: "done", toolCalls: [] },
558
- ]),
556
+ thread: { mode: "new", threadId: "thread-1" },
557
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
559
558
  threadOps: ops,
560
559
  buildContextMessage: () => "go",
561
- sandbox: sandboxOps,
562
- sandboxId: "inherited-sb",
560
+ sandboxOps,
561
+ sandbox: { mode: "inherit", sandboxId: "inherited-sb" },
563
562
  });
564
563
 
565
564
  const stateManager = createAgentStateManager({
@@ -587,9 +586,22 @@ describe("createSession integration", () => {
587
586
  },
588
587
  });
589
588
 
589
+ const sandboxOps: SandboxOps = {
590
+ createSandbox: async () => ({ sandboxId: "sb" }),
591
+ destroySandbox: async () => {},
592
+ pauseSandbox: async () => {},
593
+ snapshotSandbox: async () => ({
594
+ sandboxId: "sb",
595
+ providerId: "test",
596
+ data: null,
597
+ createdAt: new Date().toISOString(),
598
+ }),
599
+ forkSandbox: async () => "forked-sb",
600
+ };
601
+
590
602
  const session = await createSession({
591
603
  agentName: "TestAgent",
592
- threadId: "thread-1",
604
+ thread: { mode: "new", threadId: "thread-1" },
593
605
  runAgent: createScriptedRunAgent([
594
606
  {
595
607
  message: "spy",
@@ -600,7 +612,8 @@ describe("createSession integration", () => {
600
612
  threadOps: ops,
601
613
  tools: { Spy: spyTool },
602
614
  buildContextMessage: () => "go",
603
- sandboxId: "my-sandbox",
615
+ sandbox: { mode: "inherit", sandboxId: "my-sandbox" },
616
+ sandboxOps,
604
617
  });
605
618
 
606
619
  const stateManager = createAgentStateManager({
@@ -620,7 +633,7 @@ describe("createSession integration", () => {
620
633
 
621
634
  const session = await createSession({
622
635
  agentName: "TestAgent",
623
- threadId: "thread-1",
636
+ thread: { mode: "new", threadId: "thread-1" },
624
637
  runAgent: async () => {
625
638
  throw new Error("LLM went down");
626
639
  },
@@ -638,7 +651,7 @@ describe("createSession integration", () => {
638
651
  });
639
652
 
640
653
  await expect(session.runSession({ stateManager })).rejects.toThrow(
641
- "LLM went down",
654
+ "LLM went down"
642
655
  );
643
656
 
644
657
  expect(endReason).toBe("failed");
@@ -652,7 +665,7 @@ describe("createSession integration", () => {
652
665
 
653
666
  const session = await createSession({
654
667
  agentName: "TestAgent",
655
- threadId: "thread-1",
668
+ thread: { mode: "new", threadId: "thread-1" },
656
669
  runAgent: createScriptedRunAgent([
657
670
  {
658
671
  message: "call echo",
@@ -690,9 +703,7 @@ describe("createSession integration", () => {
690
703
 
691
704
  const session = await createSession({
692
705
  agentName: "TestAgent",
693
- runAgent: createScriptedRunAgent([
694
- { message: "done", toolCalls: [] },
695
- ]),
706
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
696
707
  threadOps: ops,
697
708
  buildContextMessage: () => "go",
698
709
  });
@@ -724,7 +735,7 @@ describe("createSession integration", () => {
724
735
 
725
736
  const session = await createSession({
726
737
  agentName: "TestAgent",
727
- threadId: "thread-1",
738
+ thread: { mode: "new", threadId: "thread-1" },
728
739
  runAgent: createScriptedRunAgent([
729
740
  {
730
741
  message: "computing",
@@ -760,10 +771,8 @@ describe("createSession integration", () => {
760
771
 
761
772
  const session = await createSession({
762
773
  agentName: "TestAgent",
763
- threadId: "thread-1",
764
- runAgent: createScriptedRunAgent([
765
- { message: "done", toolCalls: [] },
766
- ]),
774
+ thread: { mode: "new", threadId: "thread-1" },
775
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
767
776
  threadOps: ops,
768
777
  buildContextMessage: async () => {
769
778
  await new Promise((r) => setTimeout(r, 5));
@@ -778,7 +787,7 @@ describe("createSession integration", () => {
778
787
  await session.runSession({ stateManager });
779
788
 
780
789
  const humanOps = log.filter((l) => l.op === "appendHumanMessage");
781
- expect(at(humanOps, 0).args[1]).toBe("async context");
790
+ expect(at(humanOps, 0).args[2]).toBe("async context");
782
791
  });
783
792
 
784
793
  // --- Sandbox stateUpdate merge ---
@@ -798,17 +807,17 @@ describe("createSession integration", () => {
798
807
  data: null,
799
808
  createdAt: new Date().toISOString(),
800
809
  }),
810
+ forkSandbox: async () => "forked-sandbox-id",
811
+ pauseSandbox: async () => {},
801
812
  };
802
813
 
803
814
  const session = await createSession({
804
815
  agentName: "TestAgent",
805
- threadId: "thread-1",
806
- runAgent: createScriptedRunAgent([
807
- { message: "done", toolCalls: [] },
808
- ]),
816
+ thread: { mode: "new", threadId: "thread-1" },
817
+ runAgent: createScriptedRunAgent([{ message: "done", toolCalls: [] }]),
809
818
  threadOps: ops,
810
819
  buildContextMessage: () => "go",
811
- sandbox: sandboxOps,
820
+ sandboxOps,
812
821
  });
813
822
 
814
823
  const stateManager = createAgentStateManager<{ customField: string }>({
@@ -838,14 +847,18 @@ describe("createSession integration", () => {
838
847
 
839
848
  const session = await createSession({
840
849
  agentName: "TestAgent",
841
- threadId: "thread-1",
850
+ thread: { mode: "new", threadId: "thread-1" },
842
851
  runAgent: createScriptedRunAgent([
843
852
  {
844
853
  message: "t1",
845
854
  toolCalls: [{ id: "tc-1", name: "UsageTool", args: {} }],
846
855
  usage: { inputTokens: 100, outputTokens: 50 },
847
856
  },
848
- { message: "done", toolCalls: [], usage: { inputTokens: 80, outputTokens: 40 } },
857
+ {
858
+ message: "done",
859
+ toolCalls: [],
860
+ usage: { inputTokens: 80, outputTokens: 40 },
861
+ },
849
862
  ]),
850
863
  threadOps: ops,
851
864
  tools: { UsageTool: usageTool },
@@ -864,4 +877,3 @@ describe("createSession integration", () => {
864
877
  expect(result.usage.totalOutputTokens).toBe(90);
865
878
  });
866
879
  });
867
-