zeitlich 0.2.37 → 0.2.38

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 (131) hide show
  1. package/dist/{activities-Bb-nAjwQ.d.ts → activities-BKhMtKDd.d.ts} +4 -2
  2. package/dist/{activities-vkI4_3CC.d.cts → activities-CDcwkRZs.d.cts} +4 -2
  3. package/dist/adapters/sandbox/bedrock/index.cjs +3 -3
  4. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
  5. package/dist/adapters/sandbox/bedrock/index.d.cts +6 -6
  6. package/dist/adapters/sandbox/bedrock/index.d.ts +6 -6
  7. package/dist/adapters/sandbox/bedrock/index.js +3 -3
  8. package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
  9. package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
  10. package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
  11. package/dist/adapters/sandbox/daytona/index.cjs +3 -3
  12. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  13. package/dist/adapters/sandbox/daytona/index.d.cts +4 -4
  14. package/dist/adapters/sandbox/daytona/index.d.ts +4 -4
  15. package/dist/adapters/sandbox/daytona/index.js +3 -3
  16. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  17. package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
  18. package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
  19. package/dist/adapters/sandbox/e2b/index.cjs +26 -14
  20. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  21. package/dist/adapters/sandbox/e2b/index.d.cts +24 -4
  22. package/dist/adapters/sandbox/e2b/index.d.ts +24 -4
  23. package/dist/adapters/sandbox/e2b/index.js +26 -14
  24. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  25. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  26. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  27. package/dist/adapters/sandbox/inmemory/index.cjs +3 -3
  28. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  29. package/dist/adapters/sandbox/inmemory/index.d.cts +4 -4
  30. package/dist/adapters/sandbox/inmemory/index.d.ts +4 -4
  31. package/dist/adapters/sandbox/inmemory/index.js +3 -3
  32. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  33. package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
  34. package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
  35. package/dist/adapters/thread/anthropic/index.cjs +23 -3
  36. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  37. package/dist/adapters/thread/anthropic/index.d.cts +5 -5
  38. package/dist/adapters/thread/anthropic/index.d.ts +5 -5
  39. package/dist/adapters/thread/anthropic/index.js +23 -3
  40. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  41. package/dist/adapters/thread/anthropic/workflow.cjs +2 -1
  42. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  43. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
  44. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
  45. package/dist/adapters/thread/anthropic/workflow.js +2 -1
  46. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  47. package/dist/adapters/thread/google-genai/index.cjs +27 -3
  48. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  49. package/dist/adapters/thread/google-genai/index.d.cts +5 -5
  50. package/dist/adapters/thread/google-genai/index.d.ts +5 -5
  51. package/dist/adapters/thread/google-genai/index.js +27 -3
  52. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  53. package/dist/adapters/thread/google-genai/workflow.cjs +2 -1
  54. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  55. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -5
  56. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -5
  57. package/dist/adapters/thread/google-genai/workflow.js +2 -1
  58. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  59. package/dist/adapters/thread/langchain/index.cjs +23 -3
  60. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  61. package/dist/adapters/thread/langchain/index.d.cts +5 -5
  62. package/dist/adapters/thread/langchain/index.d.ts +5 -5
  63. package/dist/adapters/thread/langchain/index.js +23 -3
  64. package/dist/adapters/thread/langchain/index.js.map +1 -1
  65. package/dist/adapters/thread/langchain/workflow.cjs +2 -1
  66. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  67. package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
  68. package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
  69. package/dist/adapters/thread/langchain/workflow.js +2 -1
  70. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  71. package/dist/index.cjs +120 -30
  72. package/dist/index.cjs.map +1 -1
  73. package/dist/index.d.cts +11 -11
  74. package/dist/index.d.ts +11 -11
  75. package/dist/index.js +121 -31
  76. package/dist/index.js.map +1 -1
  77. package/dist/{proxy-0smGKvx8.d.ts → proxy-CUlKSvZS.d.ts} +1 -1
  78. package/dist/{proxy-DEtowJyd.d.cts → proxy-D_3x7RN4.d.cts} +1 -1
  79. package/dist/{thread-manager-C-C4pI2z.d.ts → thread-manager-CVu7o2cs.d.ts} +4 -2
  80. package/dist/{thread-manager-D4vgzYrh.d.cts → thread-manager-HSwyh28L.d.cts} +4 -2
  81. package/dist/{thread-manager-3fszQih4.d.ts → thread-manager-c1gPopAG.d.ts} +4 -2
  82. package/dist/{thread-manager-CzYln2OC.d.cts → thread-manager-wGi-LqIP.d.cts} +4 -2
  83. package/dist/{types-B37hKoWA.d.ts → types-BH_IRryz.d.ts} +10 -1
  84. package/dist/{types-D08CXPh8.d.cts → types-BaOw4hKI.d.cts} +10 -1
  85. package/dist/{types-CPKDl-y_.d.ts → types-C06FwR96.d.cts} +59 -4
  86. package/dist/{types-CNuWnvy9.d.ts → types-DAsQ21Rt.d.ts} +1 -1
  87. package/dist/{types-BO7Yju20.d.cts → types-DNr31FzL.d.ts} +59 -4
  88. package/dist/{types-DWEUmYAJ.d.cts → types-lm8tMNJQ.d.cts} +1 -1
  89. package/dist/{types-tQL9njTu.d.cts → types-yx0LzPGn.d.cts} +21 -7
  90. package/dist/{types-tQL9njTu.d.ts → types-yx0LzPGn.d.ts} +21 -7
  91. package/dist/{workflow-CjXHbZZc.d.ts → workflow-CSCkpwAL.d.ts} +2 -2
  92. package/dist/{workflow-Do_lzJpT.d.cts → workflow-DuvMZ8Vm.d.cts} +2 -2
  93. package/dist/workflow.cjs +94 -18
  94. package/dist/workflow.cjs.map +1 -1
  95. package/dist/workflow.d.cts +3 -3
  96. package/dist/workflow.d.ts +3 -3
  97. package/dist/workflow.js +95 -19
  98. package/dist/workflow.js.map +1 -1
  99. package/package.json +2 -2
  100. package/src/adapters/sandbox/bedrock/index.ts +12 -3
  101. package/src/adapters/sandbox/daytona/index.ts +12 -3
  102. package/src/adapters/sandbox/e2b/index.ts +36 -14
  103. package/src/adapters/sandbox/e2b/types.ts +16 -0
  104. package/src/adapters/sandbox/inmemory/index.ts +12 -3
  105. package/src/adapters/thread/anthropic/activities.ts +9 -0
  106. package/src/adapters/thread/anthropic/model-invoker.ts +3 -1
  107. package/src/adapters/thread/anthropic/thread-manager.ts +3 -0
  108. package/src/adapters/thread/google-genai/activities.ts +13 -0
  109. package/src/adapters/thread/google-genai/model-invoker.ts +3 -1
  110. package/src/adapters/thread/google-genai/thread-manager.ts +3 -0
  111. package/src/adapters/thread/langchain/activities.ts +9 -0
  112. package/src/adapters/thread/langchain/model-invoker.ts +2 -1
  113. package/src/adapters/thread/langchain/thread-manager.ts +3 -0
  114. package/src/lib/lifecycle.ts +11 -4
  115. package/src/lib/model/types.ts +10 -0
  116. package/src/lib/sandbox/manager.ts +26 -18
  117. package/src/lib/sandbox/types.ts +27 -7
  118. package/src/lib/session/session-edge-cases.integration.test.ts +265 -1
  119. package/src/lib/session/session.integration.test.ts +22 -1
  120. package/src/lib/session/session.ts +61 -7
  121. package/src/lib/session/types.ts +12 -0
  122. package/src/lib/subagent/subagent.integration.test.ts +100 -104
  123. package/src/lib/thread/manager.ts +18 -0
  124. package/src/lib/thread/proxy.ts +1 -0
  125. package/src/lib/thread/types.ts +9 -0
  126. package/src/lib/tool-router/index.ts +2 -0
  127. package/src/lib/tool-router/router-edge-cases.integration.test.ts +92 -0
  128. package/src/lib/tool-router/router.integration.test.ts +12 -0
  129. package/src/lib/tool-router/router.ts +89 -16
  130. package/src/lib/tool-router/types.ts +34 -1
  131. package/src/workflow.ts +2 -0
@@ -23,8 +23,20 @@ vi.mock("@temporalio/workflow", () => {
23
23
  }
24
24
  }
25
25
  const noop = () => {};
26
+ class MockCancellationScope {
27
+ cancellable: boolean;
28
+ constructor(opts?: { cancellable?: boolean }) {
29
+ this.cancellable = opts?.cancellable ?? true;
30
+ }
31
+ async run<T>(fn: () => Promise<T>): Promise<T> {
32
+ return fn();
33
+ }
34
+ cancel(): void {}
35
+ }
26
36
  return {
27
37
  ApplicationFailure: MockApplicationFailure,
38
+ CancellationScope: MockCancellationScope,
39
+ isCancellation: (_err: unknown) => false,
28
40
  uuid4: () => "00000000-0000-0000-0000-000000000000",
29
41
  log: { trace: noop, debug: noop, info: noop, warn: noop, error: noop },
30
42
  };
@@ -648,6 +660,86 @@ describe("createToolRouter edge cases", () => {
648
660
  recovered: true,
649
661
  });
650
662
  });
663
+
664
+ // --- Rewind signal -------------------------------------------------------
665
+
666
+ it("attaches a rewind signal and skips result append when handler returns rewind:true", async () => {
667
+ const rewindTool = defineTool({
668
+ name: "Rewind" as const,
669
+ description: "rewinds",
670
+ schema: z.object({}),
671
+ handler: async () => ({
672
+ toolResponse: "ignored",
673
+ data: null,
674
+ rewind: true,
675
+ }),
676
+ });
677
+
678
+ const router = createToolRouter({
679
+ tools: { Rewind: rewindTool } as const,
680
+ threadId: "t-1",
681
+ appendToolResult: appendSpy.fn,
682
+ });
683
+
684
+ const parsed = router.parseToolCall({
685
+ id: "tc-1",
686
+ name: "Rewind",
687
+ args: {},
688
+ });
689
+
690
+ const results = await router.processToolCalls([parsed]);
691
+
692
+ expect(results).toHaveLength(0);
693
+ expect(results.rewind).toEqual({
694
+ toolCallId: "tc-1",
695
+ toolName: "Rewind",
696
+ });
697
+ expect(appendSpy.calls).toHaveLength(0);
698
+ });
699
+
700
+ it("short-circuits further sequential tool calls when one requests rewind", async () => {
701
+ let laterCalled = false;
702
+ const laterTool = defineTool({
703
+ name: "Later" as const,
704
+ description: "runs after rewind",
705
+ schema: z.object({}),
706
+ handler: async () => {
707
+ laterCalled = true;
708
+ return { toolResponse: "ok", data: null };
709
+ },
710
+ });
711
+ const rewindTool = defineTool({
712
+ name: "Rewind" as const,
713
+ description: "rewinds",
714
+ schema: z.object({}),
715
+ handler: async () => ({
716
+ toolResponse: "ignored",
717
+ data: null,
718
+ rewind: true,
719
+ }),
720
+ });
721
+
722
+ const router = createToolRouter({
723
+ tools: { Rewind: rewindTool, Later: laterTool } as const,
724
+ threadId: "t-1",
725
+ appendToolResult: appendSpy.fn,
726
+ parallel: false,
727
+ });
728
+
729
+ const calls = [
730
+ router.parseToolCall({ id: "tc-1", name: "Rewind", args: {} }),
731
+ router.parseToolCall({ id: "tc-2", name: "Later", args: {} }),
732
+ ];
733
+
734
+ const results = await router.processToolCalls(calls);
735
+
736
+ expect(results).toHaveLength(0);
737
+ expect(results.rewind).toEqual({
738
+ toolCallId: "tc-1",
739
+ toolName: "Rewind",
740
+ });
741
+ expect(laterCalled).toBe(false);
742
+ });
651
743
  });
652
744
 
653
745
  describe("hasNoOtherToolCalls", () => {
@@ -23,8 +23,20 @@ vi.mock("@temporalio/workflow", () => {
23
23
  }
24
24
  }
25
25
  const noop = () => {};
26
+ class MockCancellationScope {
27
+ cancellable: boolean;
28
+ constructor(opts?: { cancellable?: boolean }) {
29
+ this.cancellable = opts?.cancellable ?? true;
30
+ }
31
+ async run<T>(fn: () => Promise<T>): Promise<T> {
32
+ return fn();
33
+ }
34
+ cancel(): void {}
35
+ }
26
36
  return {
27
37
  ApplicationFailure: MockApplicationFailure,
38
+ CancellationScope: MockCancellationScope,
39
+ isCancellation: (_err: unknown) => false,
28
40
  uuid4: () => "00000000-0000-0000-0000-000000000000",
29
41
  log: { trace: noop, debug: noop, info: noop, warn: noop, error: noop },
30
42
  };
@@ -15,12 +15,19 @@ import type {
15
15
  ToolArgs,
16
16
  ToolResult,
17
17
  ProcessToolCallsContext,
18
+ ProcessToolCallsResult,
19
+ RewindSignal,
18
20
  ToolWithHandler,
19
21
  } from "./types";
20
22
 
21
23
  import type { JsonValue } from "../state/types";
22
24
  import type { z } from "zod";
23
- import { uuid4, log } from "@temporalio/workflow";
25
+ import {
26
+ uuid4,
27
+ log,
28
+ CancellationScope,
29
+ isCancellation,
30
+ } from "@temporalio/workflow";
24
31
 
25
32
  /**
26
33
  * Creates a tool router for declarative tool call processing.
@@ -199,11 +206,22 @@ export function createToolRouter<T extends ToolMap>(
199
206
  }
200
207
  }
201
208
 
209
+ /**
210
+ * Internal per-tool-call outcome. `rewind` signals the caller that the
211
+ * handler requested a session-level rewind; when present, the result is
212
+ * not appended to the thread and siblings should be cancelled.
213
+ */
214
+ type ProcessedToolCall =
215
+ | { kind: "result"; value: ToolCallResultUnion<TResults> }
216
+ | { kind: "rewind"; signal: RewindSignal }
217
+ | { kind: "skipped" };
218
+
202
219
  async function processToolCall(
203
220
  toolCall: ParsedToolCallUnion<T>,
204
221
  turn: number,
205
- sandboxId?: string
206
- ): Promise<ToolCallResultUnion<TResults> | null> {
222
+ sandboxId?: string,
223
+ onRewindRequested?: (signal: RewindSignal) => void
224
+ ): Promise<ProcessedToolCall> {
207
225
  const startTime = Date.now();
208
226
  const tool = toolMap.get(toolCall.name);
209
227
 
@@ -220,7 +238,7 @@ export function createToolRouter<T extends ToolMap>(
220
238
  reason: "Skipped by PreToolUse hook",
221
239
  }),
222
240
  });
223
- return null;
241
+ return { kind: "skipped" };
224
242
  }
225
243
  const effectiveArgs = preResult.args;
226
244
 
@@ -235,6 +253,7 @@ export function createToolRouter<T extends ToolMap>(
235
253
  let content!: JsonValue;
236
254
  let resultAppended = false;
237
255
  let metadata: Record<string, unknown> | undefined;
256
+ let rewindRequested = false;
238
257
 
239
258
  try {
240
259
  if (tool) {
@@ -253,11 +272,15 @@ export function createToolRouter<T extends ToolMap>(
253
272
  content = response.toolResponse as JsonValue;
254
273
  resultAppended = response.resultAppended === true;
255
274
  metadata = response.metadata;
275
+ rewindRequested = response.rewind === true;
256
276
  } else {
257
277
  result = { error: `Unknown tool: ${toolCall.name}` };
258
278
  content = JSON.stringify(result, null, 2);
259
279
  }
260
280
  } catch (error) {
281
+ if (isCancellation(error)) {
282
+ throw error;
283
+ }
261
284
  log.warn("tool call failed", {
262
285
  toolName: toolCall.name,
263
286
  toolCallId: toolCall.id,
@@ -276,6 +299,16 @@ export function createToolRouter<T extends ToolMap>(
276
299
  content = recovery.content;
277
300
  }
278
301
 
302
+ if (rewindRequested) {
303
+ const signal: RewindSignal = {
304
+ toolCallId: toolCall.id,
305
+ toolName: toolCall.name,
306
+ };
307
+ log.info("tool requested rewind", { ...signal });
308
+ onRewindRequested?.(signal);
309
+ return { kind: "rewind", signal };
310
+ }
311
+
279
312
  // --- Append result to thread (unless handler already did) ---
280
313
  if (!resultAppended) {
281
314
  const config = {
@@ -319,7 +352,7 @@ export function createToolRouter<T extends ToolMap>(
319
352
  durationMs
320
353
  );
321
354
 
322
- return toolResult;
355
+ return { kind: "result", value: toolResult };
323
356
  }
324
357
 
325
358
  return {
@@ -369,31 +402,71 @@ export function createToolRouter<T extends ToolMap>(
369
402
  async processToolCalls(
370
403
  toolCalls: ParsedToolCallUnion<T>[],
371
404
  context?: ProcessToolCallsContext
372
- ): Promise<ToolCallResultUnion<TResults>[]> {
405
+ ): Promise<ProcessToolCallsResult<TResults>> {
406
+ const attachRewind = (
407
+ arr: ToolCallResultUnion<TResults>[],
408
+ rewind: RewindSignal | undefined,
409
+ ): ProcessToolCallsResult<TResults> => {
410
+ if (rewind) {
411
+ (arr as ProcessToolCallsResult<TResults>).rewind = rewind;
412
+ }
413
+ return arr as ProcessToolCallsResult<TResults>;
414
+ };
415
+
373
416
  if (toolCalls.length === 0) {
374
- return [];
417
+ return attachRewind([], undefined);
375
418
  }
376
419
 
377
420
  const turn = context?.turn ?? 0;
378
421
  const sandboxId = context?.sandboxId;
379
422
 
423
+ let rewindSignal: RewindSignal | undefined;
424
+
380
425
  if (options.parallel) {
381
- const results = await Promise.all(
382
- toolCalls.map((tc) => processToolCall(tc, turn, sandboxId))
426
+ const scope = new CancellationScope({ cancellable: true });
427
+ const onRewindRequested = (signal: RewindSignal): void => {
428
+ if (!rewindSignal) {
429
+ rewindSignal = signal;
430
+ // Cancel all other in-flight tool calls in this batch.
431
+ scope.cancel();
432
+ }
433
+ };
434
+
435
+ const outcomes = await scope.run(async () =>
436
+ Promise.allSettled(
437
+ toolCalls.map((tc) =>
438
+ processToolCall(tc, turn, sandboxId, onRewindRequested)
439
+ )
440
+ )
383
441
  );
384
- return results.filter(
385
- (r): r is NonNullable<typeof r> => r !== null
386
- ) as ToolCallResultUnion<TResults>[];
442
+
443
+ const results: ToolCallResultUnion<TResults>[] = [];
444
+ for (const outcome of outcomes) {
445
+ if (outcome.status === "rejected") {
446
+ if (isCancellation(outcome.reason)) {
447
+ continue;
448
+ }
449
+ throw outcome.reason;
450
+ }
451
+ if (outcome.value.kind === "result") {
452
+ results.push(outcome.value.value);
453
+ }
454
+ }
455
+ return attachRewind(results, rewindSignal);
387
456
  }
388
457
 
389
458
  const results: ToolCallResultUnion<TResults>[] = [];
390
459
  for (const toolCall of toolCalls) {
391
- const result = await processToolCall(toolCall, turn, sandboxId);
392
- if (result !== null) {
393
- results.push(result);
460
+ const outcome = await processToolCall(toolCall, turn, sandboxId);
461
+ if (outcome.kind === "rewind") {
462
+ rewindSignal = outcome.signal;
463
+ break;
464
+ }
465
+ if (outcome.kind === "result") {
466
+ results.push(outcome.value);
394
467
  }
395
468
  }
396
- return results;
469
+ return attachRewind(results, rewindSignal);
397
470
  },
398
471
 
399
472
  async processToolCallsByName<TName extends ToolNames<T>, TResult>(
@@ -139,6 +139,17 @@ export interface ToolHandlerResponse<
139
139
  * payloads through Temporal's activity payload limit.
140
140
  */
141
141
  resultAppended?: boolean;
142
+ /**
143
+ * When true, the session will rewind: any in-flight parallel tool calls
144
+ * are cancelled, previously appended tool results and the triggering
145
+ * assistant message are removed from the thread, and the LLM call that
146
+ * produced the tool calls is retried.
147
+ *
148
+ * The `toolResponse` for a rewinding tool call is ignored (never
149
+ * appended) since the session truncates the thread back to the
150
+ * pre-invocation state.
151
+ */
152
+ rewind?: boolean;
142
153
  /** Token usage from the tool execution (e.g. child agent invocations) */
143
154
  usage?: TokenUsage;
144
155
  /** Thread ID used by the handler (surfaced to the LLM for subagent thread continuation) */
@@ -278,6 +289,28 @@ export interface ProcessToolCallsContext {
278
289
  sandboxId?: string;
279
290
  }
280
291
 
292
+ /**
293
+ * Signal that a tool handler requested a rewind. Attached to the
294
+ * {@link ProcessToolCallsResult} so the session can roll the thread
295
+ * back to the pre-invocation snapshot and retry the LLM call.
296
+ */
297
+ export interface RewindSignal {
298
+ toolCallId: string;
299
+ toolName: string;
300
+ }
301
+
302
+ /**
303
+ * Result returned by {@link ToolRouter.processToolCalls}.
304
+ *
305
+ * The object is a standard array of tool call results for successful
306
+ * tool calls (cancelled or rewinding siblings are omitted), extended
307
+ * with a `rewind` property when any tool in the batch requested a
308
+ * rewind. Using an array-with-property lets existing code that treats
309
+ * the return value as `ToolCallResultUnion[]` continue to work.
310
+ */
311
+ export type ProcessToolCallsResult<TResults extends Record<string, unknown>> =
312
+ ToolCallResultUnion<TResults>[] & { rewind?: RewindSignal };
313
+
281
314
  // ============================================================================
282
315
  // Hook Types
283
316
  // ============================================================================
@@ -469,7 +502,7 @@ export interface ToolRouter<T extends ToolMap> {
469
502
  processToolCalls(
470
503
  toolCalls: ParsedToolCallUnion<T>[],
471
504
  context?: ProcessToolCallsContext
472
- ): Promise<ToolCallResultUnion<InferToolResults<T>>[]>;
505
+ ): Promise<ProcessToolCallsResult<InferToolResults<T>>>;
473
506
 
474
507
  /**
475
508
  * Process tool calls matching a specific name with a custom handler.
package/src/workflow.ts CHANGED
@@ -94,6 +94,8 @@ export type {
94
94
  // Other
95
95
  AppendToolResultFn,
96
96
  ProcessToolCallsContext,
97
+ ProcessToolCallsResult,
98
+ RewindSignal,
97
99
  } from "./lib/tool-router";
98
100
 
99
101
  // Session & message lifecycle hooks