zeitlich 0.2.38 → 0.2.39

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 (125) hide show
  1. package/README.md +18 -0
  2. package/dist/{activities-BKhMtKDd.d.ts → activities-Bmu7XnaG.d.ts} +4 -6
  3. package/dist/{activities-CDcwkRZs.d.cts → activities-ByBFLvm2.d.cts} +4 -6
  4. package/dist/adapter-id-BB-mmrts.d.cts +17 -0
  5. package/dist/adapter-id-BB-mmrts.d.ts +17 -0
  6. package/dist/adapter-id-CMwVrVqv.d.cts +17 -0
  7. package/dist/adapter-id-CMwVrVqv.d.ts +17 -0
  8. package/dist/adapter-id-CbY2zeSt.d.cts +17 -0
  9. package/dist/adapter-id-CbY2zeSt.d.ts +17 -0
  10. package/dist/adapters/thread/anthropic/index.cjs +140 -23
  11. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  12. package/dist/adapters/thread/anthropic/index.d.cts +8 -7
  13. package/dist/adapters/thread/anthropic/index.d.ts +8 -7
  14. package/dist/adapters/thread/anthropic/index.js +140 -24
  15. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  16. package/dist/adapters/thread/anthropic/workflow.cjs +8 -3
  17. package/dist/adapters/thread/anthropic/workflow.cjs.map +1 -1
  18. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -4
  19. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -4
  20. package/dist/adapters/thread/anthropic/workflow.js +8 -4
  21. package/dist/adapters/thread/anthropic/workflow.js.map +1 -1
  22. package/dist/adapters/thread/google-genai/index.cjs +140 -23
  23. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  24. package/dist/adapters/thread/google-genai/index.d.cts +5 -4
  25. package/dist/adapters/thread/google-genai/index.d.ts +5 -4
  26. package/dist/adapters/thread/google-genai/index.js +140 -24
  27. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  28. package/dist/adapters/thread/google-genai/workflow.cjs +8 -3
  29. package/dist/adapters/thread/google-genai/workflow.cjs.map +1 -1
  30. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -4
  31. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -4
  32. package/dist/adapters/thread/google-genai/workflow.js +8 -4
  33. package/dist/adapters/thread/google-genai/workflow.js.map +1 -1
  34. package/dist/adapters/thread/index.cjs +16 -0
  35. package/dist/adapters/thread/index.cjs.map +1 -0
  36. package/dist/adapters/thread/index.d.cts +34 -0
  37. package/dist/adapters/thread/index.d.ts +34 -0
  38. package/dist/adapters/thread/index.js +12 -0
  39. package/dist/adapters/thread/index.js.map +1 -0
  40. package/dist/adapters/thread/langchain/index.cjs +139 -24
  41. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  42. package/dist/adapters/thread/langchain/index.d.cts +8 -7
  43. package/dist/adapters/thread/langchain/index.d.ts +8 -7
  44. package/dist/adapters/thread/langchain/index.js +139 -25
  45. package/dist/adapters/thread/langchain/index.js.map +1 -1
  46. package/dist/adapters/thread/langchain/workflow.cjs +8 -3
  47. package/dist/adapters/thread/langchain/workflow.cjs.map +1 -1
  48. package/dist/adapters/thread/langchain/workflow.d.cts +5 -4
  49. package/dist/adapters/thread/langchain/workflow.d.ts +5 -4
  50. package/dist/adapters/thread/langchain/workflow.js +8 -4
  51. package/dist/adapters/thread/langchain/workflow.js.map +1 -1
  52. package/dist/index.cjs +266 -48
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.d.cts +6 -6
  55. package/dist/index.d.ts +6 -6
  56. package/dist/index.js +263 -49
  57. package/dist/index.js.map +1 -1
  58. package/dist/{proxy-D_3x7RN4.d.cts → proxy-BAKzNGRq.d.cts} +1 -1
  59. package/dist/{proxy-CUlKSvZS.d.ts → proxy-DO_MXbY4.d.ts} +1 -1
  60. package/dist/{thread-manager-CVu7o2cs.d.ts → thread-manager-CcRXasqs.d.ts} +2 -4
  61. package/dist/{thread-manager-HSwyh28L.d.cts → thread-manager-ClwSaUnj.d.cts} +2 -4
  62. package/dist/{thread-manager-c1gPopAG.d.ts → thread-manager-D-7lp1JK.d.ts} +2 -4
  63. package/dist/{thread-manager-wGi-LqIP.d.cts → thread-manager-Y8Ucf0Tf.d.cts} +2 -4
  64. package/dist/{types-C06FwR96.d.cts → types-Bcbiq8iv.d.cts} +162 -44
  65. package/dist/{types-BH_IRryz.d.ts → types-DpHTX-iO.d.ts} +54 -6
  66. package/dist/{types-DNr31FzL.d.ts → types-Dt8-HBBT.d.ts} +162 -44
  67. package/dist/{types-BaOw4hKI.d.cts → types-hFFi-Zd9.d.cts} +54 -6
  68. package/dist/{workflow-CSCkpwAL.d.ts → workflow-Bmf9EtDW.d.ts} +82 -2
  69. package/dist/{workflow-DuvMZ8Vm.d.cts → workflow-Bx9utBwb.d.cts} +82 -2
  70. package/dist/workflow.cjs +188 -37
  71. package/dist/workflow.cjs.map +1 -1
  72. package/dist/workflow.d.cts +2 -2
  73. package/dist/workflow.d.ts +2 -2
  74. package/dist/workflow.js +185 -38
  75. package/dist/workflow.js.map +1 -1
  76. package/package.json +11 -1
  77. package/src/adapters/thread/adapter-id.test.ts +42 -0
  78. package/src/adapters/thread/anthropic/activities.ts +33 -7
  79. package/src/adapters/thread/anthropic/adapter-id.ts +16 -0
  80. package/src/adapters/thread/anthropic/fork-transform.test.ts +291 -0
  81. package/src/adapters/thread/anthropic/index.ts +3 -0
  82. package/src/adapters/thread/anthropic/model-invoker.ts +8 -4
  83. package/src/adapters/thread/anthropic/proxy.ts +3 -2
  84. package/src/adapters/thread/anthropic/thread-manager.ts +27 -4
  85. package/src/adapters/thread/google-genai/activities.ts +33 -7
  86. package/src/adapters/thread/google-genai/adapter-id.ts +16 -0
  87. package/src/adapters/thread/google-genai/fork-transform.test.ts +149 -0
  88. package/src/adapters/thread/google-genai/index.ts +3 -0
  89. package/src/adapters/thread/google-genai/model-invoker.ts +7 -3
  90. package/src/adapters/thread/google-genai/proxy.ts +3 -2
  91. package/src/adapters/thread/google-genai/thread-manager.ts +27 -4
  92. package/src/adapters/thread/index.ts +39 -0
  93. package/src/adapters/thread/langchain/activities.ts +33 -7
  94. package/src/adapters/thread/langchain/adapter-id.ts +16 -0
  95. package/src/adapters/thread/langchain/fork-transform.test.ts +142 -0
  96. package/src/adapters/thread/langchain/index.ts +3 -0
  97. package/src/adapters/thread/langchain/model-invoker.ts +8 -3
  98. package/src/adapters/thread/langchain/proxy.ts +3 -2
  99. package/src/adapters/thread/langchain/thread-manager.ts +27 -4
  100. package/src/lib/lifecycle.ts +3 -1
  101. package/src/lib/model/types.ts +7 -10
  102. package/src/lib/session/session-edge-cases.integration.test.ts +131 -63
  103. package/src/lib/session/session.integration.test.ts +174 -5
  104. package/src/lib/session/session.ts +68 -28
  105. package/src/lib/session/types.ts +60 -9
  106. package/src/lib/state/index.ts +1 -0
  107. package/src/lib/state/manager.integration.test.ts +109 -0
  108. package/src/lib/state/manager.ts +38 -8
  109. package/src/lib/state/types.ts +25 -0
  110. package/src/lib/subagent/handler.ts +124 -11
  111. package/src/lib/subagent/index.ts +5 -1
  112. package/src/lib/subagent/subagent.integration.test.ts +528 -0
  113. package/src/lib/subagent/types.ts +63 -14
  114. package/src/lib/subagent/workflow.ts +29 -2
  115. package/src/lib/thread/index.ts +5 -0
  116. package/src/lib/thread/keys.test.ts +101 -0
  117. package/src/lib/thread/keys.ts +94 -0
  118. package/src/lib/thread/manager.test.ts +139 -0
  119. package/src/lib/thread/manager.ts +92 -14
  120. package/src/lib/thread/proxy.ts +2 -0
  121. package/src/lib/thread/types.ts +60 -6
  122. package/src/lib/tool-router/types.ts +16 -8
  123. package/src/lib/types.ts +12 -0
  124. package/src/workflow.ts +12 -1
  125. package/tsup.config.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  import { proxyActivities, ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from './types-C06FwR96.cjs';
2
+ import { T as ThreadOps } from './types-Bcbiq8iv.cjs';
3
3
 
4
4
  /**
5
5
  * Shared proxy helper for thread operations.
@@ -1,5 +1,5 @@
1
1
  import { proxyActivities, ActivityInterfaceFor } from '@temporalio/workflow';
2
- import { T as ThreadOps } from './types-DNr31FzL.js';
2
+ import { T as ThreadOps } from './types-Dt8-HBBT.js';
3
3
 
4
4
  /**
5
5
  * Shared proxy helper for thread operations.
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import Anthropic from '@anthropic-ai/sdk';
3
- import { J as JsonValue } from './types-DNr31FzL.js';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BH_IRryz.js';
3
+ import { J as JsonValue } from './types-Dt8-HBBT.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DpHTX-iO.js';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -26,8 +26,6 @@ interface AnthropicThreadManagerConfig {
26
26
  interface AnthropicInvocationPayload {
27
27
  messages: Anthropic.Messages.MessageParam[];
28
28
  system?: string | Anthropic.Messages.TextBlockParam[];
29
- /** Number of stored messages loaded from Redis before preparation. */
30
- storedLength: number;
31
29
  }
32
30
  /** Thread manager with Anthropic MessageParam convenience helpers */
33
31
  interface AnthropicThreadManager extends ProviderThreadManager<StoredMessage, AnthropicContent, JsonValue, AnthropicSystemContent> {
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
2
  import Anthropic from '@anthropic-ai/sdk';
3
- import { J as JsonValue } from './types-C06FwR96.cjs';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BaOw4hKI.cjs';
3
+ import { J as JsonValue } from './types-Bcbiq8iv.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-hFFi-Zd9.cjs';
5
5
 
6
6
  /** SDK-native content type for Anthropic human messages */
7
7
  type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
@@ -26,8 +26,6 @@ interface AnthropicThreadManagerConfig {
26
26
  interface AnthropicInvocationPayload {
27
27
  messages: Anthropic.Messages.MessageParam[];
28
28
  system?: string | Anthropic.Messages.TextBlockParam[];
29
- /** Number of stored messages loaded from Redis before preparation. */
30
- storedLength: number;
31
29
  }
32
30
  /** Thread manager with Anthropic MessageParam convenience helpers */
33
31
  interface AnthropicThreadManager extends ProviderThreadManager<StoredMessage, AnthropicContent, JsonValue, AnthropicSystemContent> {
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-DNr31FzL.js';
2
+ import { J as JsonValue } from './types-Dt8-HBBT.js';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BH_IRryz.js';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DpHTX-iO.js';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -18,8 +18,6 @@ interface LangChainThreadManagerConfig {
18
18
  /** Prepared payload ready to send to a LangChain chat model */
19
19
  interface LangChainInvocationPayload {
20
20
  messages: BaseMessage[];
21
- /** Number of stored messages loaded from Redis before preparation. */
22
- storedLength: number;
23
21
  }
24
22
  /** Thread manager with LangChain StoredMessage convenience helpers */
25
23
  interface LangChainThreadManager extends ProviderThreadManager<StoredMessage, LangChainContent, JsonValue, LangChainSystemContent> {
@@ -1,7 +1,7 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-C06FwR96.cjs';
2
+ import { J as JsonValue } from './types-Bcbiq8iv.cjs';
3
3
  import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
4
- import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BaOw4hKI.cjs';
4
+ import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-hFFi-Zd9.cjs';
5
5
 
6
6
  /** SDK-native content type for LangChain human messages */
7
7
  type LangChainContent = string | MessageContent;
@@ -18,8 +18,6 @@ interface LangChainThreadManagerConfig {
18
18
  /** Prepared payload ready to send to a LangChain chat model */
19
19
  interface LangChainInvocationPayload {
20
20
  messages: BaseMessage[];
21
- /** Number of stored messages loaded from Redis before preparation. */
22
- storedLength: number;
23
21
  }
24
22
  /** Thread manager with LangChain StoredMessage convenience helpers */
25
23
  interface LangChainThreadManager extends ProviderThreadManager<StoredMessage, LangChainContent, JsonValue, LangChainSystemContent> {
@@ -1,8 +1,8 @@
1
1
  import { Duration } from '@temporalio/common';
2
- import { ActivityFunctionWithOptions, QueryDefinition, ActivityInterfaceFor } from '@temporalio/workflow';
2
+ import { ActivityFunctionWithOptions, QueryDefinition, ChildWorkflowOptions, ActivityInterfaceFor } from '@temporalio/workflow';
3
3
  import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
4
4
  import { z } from 'zod';
5
- import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, d as SandboxCreateOptions, f as SandboxSnapshot, g as SandboxOps } from './types-yx0LzPGn.cjs';
5
+ import { f as SandboxSnapshot, a as SandboxFileSystem, F as FileStat, D as DirentEntry, d as SandboxCreateOptions, g as SandboxOps } from './types-yx0LzPGn.cjs';
6
6
 
7
7
  /**
8
8
  * A tool definition with a name, description, and Zod schema for arguments.
@@ -99,14 +99,16 @@ interface ToolHandlerResponse<TResult = null, TToolResponse = JsonValue> {
99
99
  */
100
100
  resultAppended?: boolean;
101
101
  /**
102
- * When true, the session will rewind: any in-flight parallel tool calls
103
- * are cancelled, previously appended tool results and the triggering
104
- * assistant message are removed from the thread, and the LLM call that
105
- * produced the tool calls is retried.
102
+ * When true, the session will rewind: any in-flight parallel tool
103
+ * calls are cancelled and the LLM call is retried. The session reuses
104
+ * the same `assistantMessageId` for the retry; the next `runAgent`
105
+ * activity truncates the thread from that id on entry, wiping the
106
+ * triggering assistant message and any tool results already appended
107
+ * before re-invoking the LLM.
106
108
  *
107
109
  * The `toolResponse` for a rewinding tool call is ignored (never
108
- * appended) since the session truncates the thread back to the
109
- * pre-invocation state.
110
+ * appended) since the thread is rewound back to the pre-assistant
111
+ * state on the next invocation.
110
112
  */
111
113
  rewind?: boolean;
112
114
  /** Token usage from the tool execution (e.g. child agent invocations) */
@@ -115,6 +117,10 @@ interface ToolHandlerResponse<TResult = null, TToolResponse = JsonValue> {
115
117
  threadId?: string;
116
118
  /** Sandbox ID created or used by the handler (e.g. child agent sandbox) */
117
119
  sandboxId?: string;
120
+ /** Snapshot captured on exit when `sandboxShutdown === "snapshot"`. */
121
+ snapshot?: SandboxSnapshot;
122
+ /** Snapshot captured immediately after sandbox seeding (before the agent loop starts) when `sandbox.mode === "new"` and `sandboxShutdown === "snapshot"`. Intended as a reusable "base" for new threads that want to skip re-seeding. */
123
+ baseSnapshot?: SandboxSnapshot;
118
124
  /** Unvalidated metadata passthrough from handler to hooks (e.g. infrastructure state) */
119
125
  metadata?: Record<string, unknown>;
120
126
  }
@@ -199,8 +205,9 @@ interface ProcessToolCallsContext {
199
205
  }
200
206
  /**
201
207
  * Signal that a tool handler requested a rewind. Attached to the
202
- * {@link ProcessToolCallsResult} so the session can roll the thread
203
- * back to the pre-invocation snapshot and retry the LLM call.
208
+ * {@link ProcessToolCallsResult} so the session can reuse the same
209
+ * `assistantMessageId` for the retry; the next `runAgent` activity
210
+ * then truncates the thread from that id on entry.
204
211
  */
205
212
  interface RewindSignal {
206
213
  toolCallId: string;
@@ -420,6 +427,22 @@ type JsonSerializable<T> = {
420
427
  * Full state type combining base state with custom state
421
428
  */
422
429
  type AgentState<TCustom extends JsonSerializable<TCustom>> = BaseAgentState & TCustom;
430
+ /**
431
+ * The slice of agent state that is persisted alongside the thread in the
432
+ * thread store (e.g. Redis) so that a workflow can terminate, store its
433
+ * state, and be continued or forked later with that state rehydrated.
434
+ *
435
+ * Only fields that make sense to carry across workflow runs belong here.
436
+ * Runtime bookkeeping like status, version, turns, tools, fileTree, token
437
+ * counters, and the system prompt is intentionally NOT persisted — each run
438
+ * rebuilds those from scratch.
439
+ */
440
+ interface PersistedThreadState {
441
+ /** Task map serialized as entries so it round-trips through JSON. */
442
+ tasks: [string, WorkflowTask][];
443
+ /** All custom state fields declared by the caller. */
444
+ custom: Record<string, JsonValue>;
445
+ }
423
446
  /**
424
447
  * Agent state manager interface
425
448
  * Note: Temporal handlers must be set up in the workflow file due to
@@ -479,6 +502,13 @@ interface AgentStateManager<TCustom extends JsonSerializable<TCustom>> {
479
502
  deleteTask(id: string): boolean;
480
503
  /** Set the tools (converts Zod schemas to JSON Schema for serialization) */
481
504
  setTools(newTools: ToolDefinition[]): void;
505
+ /**
506
+ * Snapshot the fields that should survive across workflow runs
507
+ * (tasks + all custom state). Safe to pass directly to
508
+ * {@link ThreadOps.saveThreadState}. Rehydrate on the next run with
509
+ * `mergeUpdate({ tasks: new Map(slice.tasks), ...slice.custom })`.
510
+ */
511
+ getPersistedSlice(): PersistedThreadState;
482
512
  /** Update the usage */
483
513
  updateUsage(usage: TokenUsage): void;
484
514
  /** Get the total usage */
@@ -699,6 +729,18 @@ interface RunAgentConfig extends AgentConfig {
699
729
  threadKey?: string;
700
730
  /** Metadata for the session */
701
731
  metadata?: Record<string, unknown>;
732
+ /**
733
+ * The id under which the assistant message produced by this call will
734
+ * be appended. The activity truncates the thread from this id on
735
+ * entry (no-op on the first attempt) so that:
736
+ *
737
+ * - Rewind retries can reuse the same id and the previous (bad)
738
+ * assistant + its tool results are wiped before the retry LLM call.
739
+ * - Resetting the Temporal workflow to this activity restores the
740
+ * pre-call thread state: replay re-truncates, re-invokes, and
741
+ * appends under the same id.
742
+ */
743
+ assistantMessageId: string;
702
744
  }
703
745
  /**
704
746
  * Configuration for appending a tool result
@@ -817,7 +859,9 @@ interface Hooks<T extends ToolMap, TResult = unknown, TContent = unknown> extend
817
859
  * - `"new"` — start a fresh thread (optionally specify its ID).
818
860
  * - `"continue"` — append directly to an existing thread in-place.
819
861
  * - `"fork"` — copy all messages from an existing thread into a new one and
820
- * continue there.
862
+ * continue there. When the adapter has `onForkPrepareThread` and/or
863
+ * `onForkTransform` hooks configured, they are applied once to the forked
864
+ * thread before the session starts.
821
865
  */
822
866
  type ThreadInit = {
823
867
  mode: "new";
@@ -889,19 +933,20 @@ type SandboxShutdown = "destroy" | "pause" | "keep" | "snapshot";
889
933
  */
890
934
  type SubagentSandboxShutdown = SandboxShutdown | "pause-until-parent-close" | "keep-until-parent-close";
891
935
 
936
+ /**
937
+ * Subset of {@link ChildWorkflowOptions} that callers may override when a
938
+ * subagent is invoked. `workflowId`, `taskQueue`, and `args` are managed by
939
+ * the subagent handler itself and therefore cannot be set here.
940
+ *
941
+ * Configuring `workflowRunTimeout` (or `workflowExecutionTimeout`) is strongly
942
+ * recommended: it is the only reliable way to guarantee that a child workflow
943
+ * which fails during initialization or repeatedly fails workflow tasks will
944
+ * eventually be terminated, allowing the parent's `Subagent` tool call to fail
945
+ * deterministically instead of hanging forever waiting for a result.
946
+ */
947
+ type SubagentChildWorkflowOptions = Omit<ChildWorkflowOptions, "workflowId" | "taskQueue" | "args">;
892
948
  /** ToolHandlerResponse with threadId required (subagents must always surface their thread) */
893
- type SubagentHandlerResponse<TResult = null, TToolResponse = JsonValue> = ToolHandlerResponse<TResult, TToolResponse> & {
894
- threadId: string;
895
- sandboxId?: string;
896
- /** Snapshot captured on session exit when `sandboxShutdown === "snapshot"`. */
897
- snapshot?: SandboxSnapshot;
898
- /**
899
- * Snapshot captured immediately after the sandbox was seeded (before the
900
- * first agent turn) when `continuation === "snapshot"`. Only set on the
901
- * first call that actually created the sandbox.
902
- */
903
- baseSnapshot?: SandboxSnapshot;
904
- };
949
+ type SubagentHandlerResponse<TResult = null, TToolResponse = JsonValue> = ToolHandlerResponse<TResult, TToolResponse>;
905
950
  /**
906
951
  * Raw workflow input fields passed from parent to child workflow.
907
952
  * `defineSubagentWorkflow` maps this into `SubagentSessionInput`.
@@ -972,6 +1017,24 @@ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
972
1017
  workflow: SubagentWorkflow<TResult>;
973
1018
  /** Optional task queue - defaults to parent's queue if not specified */
974
1019
  taskQueue?: string;
1020
+ /**
1021
+ * Optional child workflow options forwarded to `executeChild` when the
1022
+ * subagent is spawned. Use this to configure timeouts, retry policies, or
1023
+ * parent-close behavior for the child workflow.
1024
+ *
1025
+ * **Recommended:** configure a `workflowRunTimeout` (or
1026
+ * `workflowExecutionTimeout`) so that a child workflow that fails to
1027
+ * initialize — or repeatedly fails workflow tasks without ever reaching a
1028
+ * terminal state — is eventually terminated by the Temporal server. Without
1029
+ * such a timeout, the parent's `Subagent` tool call can hang indefinitely
1030
+ * waiting for the child to finish. When Temporal terminates the child, the
1031
+ * tool call fails with a structured `ChildWorkflowFailure` that the router's
1032
+ * failure hooks can handle just like any other tool error.
1033
+ *
1034
+ * `workflowId`, `taskQueue`, and `args` are managed by the subagent handler
1035
+ * and cannot be overridden here.
1036
+ */
1037
+ workflowOptions?: SubagentChildWorkflowOptions;
975
1038
  /** Optional Zod schema to validate the child workflow's result. If omitted, result is passed through as-is. */
976
1039
  resultSchema?: TResult;
977
1040
  /** Optional context passed to the subagent — a static object or a function evaluated at invocation time */
@@ -1063,8 +1126,26 @@ interface SubagentSessionInput {
1063
1126
  sandbox?: SandboxInit;
1064
1127
  /** Sandbox shutdown policy (default: "destroy") */
1065
1128
  sandboxShutdown?: SubagentSandboxShutdown;
1066
- /** Called by the session as soon as the sandbox is created, before the agent loop starts. */
1067
- onSandboxReady?: (sandboxId: string) => void;
1129
+ /**
1130
+ * Called by the session as soon as the sandbox is created, before the
1131
+ * agent loop starts. `baseSnapshot` is populated only when the session
1132
+ * captured a seed snapshot (fresh creation + `sandboxShutdown === "snapshot"`).
1133
+ */
1134
+ onSandboxReady?: (args: {
1135
+ sandboxId: string;
1136
+ baseSnapshot?: SandboxSnapshot;
1137
+ }) => void;
1138
+ /**
1139
+ * Called by the session right before `runSession` returns. Installed by
1140
+ * `defineSubagentWorkflow` to capture sandbox outputs and auto-forward
1141
+ * them to the subagent's final result so user code never has to thread
1142
+ * `sandboxId` / `snapshot` manually.
1143
+ */
1144
+ onSessionExit?: (result: {
1145
+ sandboxId?: string;
1146
+ snapshot?: SandboxSnapshot;
1147
+ threadId: string;
1148
+ }) => void;
1068
1149
  }
1069
1150
 
1070
1151
  /**
@@ -1120,16 +1201,6 @@ interface AgentResponse<M = unknown> {
1120
1201
  message: M;
1121
1202
  rawToolCalls: RawToolCall[];
1122
1203
  usage?: TokenUsage;
1123
- /**
1124
- * Number of stored messages in the thread at the moment the LLM was
1125
- * invoked — i.e. *before* the assistant message is appended. The
1126
- * session uses this as a rewind snapshot so it can roll the thread
1127
- * back to this exact state if a tool requests a rewind.
1128
- *
1129
- * Adapters compute this for free from the array of stored messages
1130
- * they load when preparing the payload.
1131
- */
1132
- threadLengthAtCall?: number;
1133
1204
  }
1134
1205
  /**
1135
1206
  * Type signature for workflow-specific runAgent activity
@@ -1147,6 +1218,13 @@ interface ModelInvokerConfig {
1147
1218
  agentName: string;
1148
1219
  state: BaseAgentState;
1149
1220
  metadata?: Record<string, unknown>;
1221
+ /**
1222
+ * The id the assistant message produced by this call will be stored
1223
+ * under. Invokers truncate the thread from this id on entry so that
1224
+ * rewind retries and Temporal workflow resets restore the pre-call
1225
+ * state before re-invoking the LLM. See {@link RunAgentConfig}.
1226
+ */
1227
+ assistantMessageId: string;
1150
1228
  }
1151
1229
  /**
1152
1230
  * Generic model invocation contract.
@@ -1178,16 +1256,39 @@ interface ThreadOps<TContent = string> {
1178
1256
  appendAgentMessage(threadId: string, id: string, message: unknown, threadKey?: string): Promise<void>;
1179
1257
  /** Append a system message to the thread */
1180
1258
  appendSystemMessage(threadId: string, id: string, content: unknown, threadKey?: string): Promise<void>;
1181
- /** Copy all messages from sourceThreadId into a new thread at targetThreadId */
1259
+ /**
1260
+ * Copy all messages AND the persisted state slice (tasks + custom
1261
+ * state) from `sourceThreadId` into a new thread at `targetThreadId`.
1262
+ * Adapters that have `onForkPrepareThread` and/or `onForkTransform`
1263
+ * hooks configured apply them once to the new thread's messages
1264
+ * before returning.
1265
+ */
1182
1266
  forkThread(sourceThreadId: string, targetThreadId: string, threadKey?: string): Promise<void>;
1183
1267
  /**
1184
- * Truncate the thread back to `length` messages. Used by the session's
1185
- * rewind flow to roll the thread back before retrying a turn. The
1186
- * session obtains `length` from `AgentResponse.threadLengthAtCall`,
1187
- * which the model invoker computes for free from the messages it
1188
- * loaded before invoking the LLM.
1268
+ * Truncate the thread starting at `messageId`: that message and every
1269
+ * message after it are removed. If `messageId` is not present the call
1270
+ * is a no-op.
1271
+ *
1272
+ * The `runAgent` activity invokes this on entry with the pre-generated
1273
+ * `assistantMessageId`. On the happy path the id is not yet in the
1274
+ * thread and the call is a no-op. On a rewind retry (same assistant
1275
+ * id reused) or a Temporal workflow reset-to-this-activity the id is
1276
+ * present, so the bad assistant + any tool results it produced are
1277
+ * wiped and the call is then replayable.
1278
+ */
1279
+ truncateThread(threadId: string, messageId: string, threadKey?: string): Promise<void>;
1280
+ /**
1281
+ * Load the persisted state slice (tasks + custom state) associated with
1282
+ * the thread, or `null` if none has been saved yet. Called on session
1283
+ * start for `continue`/`fork` threads to rehydrate {@link AgentStateManager}.
1189
1284
  */
1190
- truncateThread(threadId: string, length: number, threadKey?: string): Promise<void>;
1285
+ loadThreadState(threadId: string, threadKey?: string): Promise<PersistedThreadState | null>;
1286
+ /**
1287
+ * Overwrite the persisted state slice for the thread. Called once from
1288
+ * the session's `finally` block on every exit path so that "finish,
1289
+ * store, continue later" works regardless of exit reason.
1290
+ */
1291
+ saveThreadState(threadId: string, state: PersistedThreadState, threadKey?: string): Promise<void>;
1191
1292
  }
1192
1293
  /**
1193
1294
  * Composes an adapter prefix + workflow scope for activity naming.
@@ -1292,8 +1393,25 @@ interface SessionConfig<T extends ToolMap, M = unknown, TContent = string> {
1292
1393
  /**
1293
1394
  * Called as soon as the sandbox is created (or resumed/forked), before the
1294
1395
  * agent loop starts. Useful for signalling sandbox readiness to a parent.
1396
+ *
1397
+ * `baseSnapshot` is only populated when the sandbox was freshly created
1398
+ * this run and `sandboxShutdown === "snapshot"` — i.e. when the session
1399
+ * captured a seed snapshot intended for reuse.
1400
+ */
1401
+ onSandboxReady?: (args: {
1402
+ sandboxId: string;
1403
+ baseSnapshot?: SandboxSnapshot;
1404
+ }) => void;
1405
+ /**
1406
+ * Called right before `runSession` returns, with the session's sandbox
1407
+ * outputs. Useful for callers (e.g. `defineSubagentWorkflow`) that want to
1408
+ * forward these fields to their own return value without requiring user
1409
+ * code to manually thread them through.
1295
1410
  */
1296
- onSandboxReady?: (sandboxId: string) => void;
1411
+ onSessionExit?: (result: {
1412
+ sandboxId?: string;
1413
+ snapshot?: SandboxSnapshot;
1414
+ }) => void;
1297
1415
  virtualFsOps?: VirtualFsOps;
1298
1416
  /**
1299
1417
  * Virtual filesystem configuration (optional — independent of sandbox).
@@ -1336,4 +1454,4 @@ interface ZeitlichSession<M = unknown, HasSandbox extends boolean = boolean> {
1336
1454
  }): Promise<SessionResult<M, T, HasSandbox>>;
1337
1455
  }
1338
1456
 
1339
- export { type SerializableToolDefinition as $, type AgentResponse as A, type BaseAgentState as B, type PostToolUseFailureHookResult as C, type PostToolUseHook as D, type PostToolUseHookContext as E, type FileEntryMetadata as F, type PreHumanMessageAppendHook as G, type Hooks as H, type InferToolResults as I, type JsonValue as J, type PreHumanMessageAppendHookContext as K, type PreToolUseHook as L, type ModelInvokerConfig as M, type PreToolUseHookContext as N, type PreToolUseHookResult as O, type PrefixedThreadOps as P, type ProcessToolCallsContext as Q, type RouterContext as R, type ScopedPrefix as S, type ThreadOps as T, type ProcessToolCallsResult as U, type VirtualFsContext as V, type RawToolCall as W, type RewindSignal as X, type RunAgentActivity as Y, type SandboxInit as Z, type SandboxShutdown as _, type ModelInvoker as a, type SessionConfig as a0, type SessionEndHook as a1, type SessionEndHookContext as a2, type SessionExitReason as a3, type SessionResult as a4, type SessionStartHook as a5, type SessionStartHookContext as a6, type SubagentConfig as a7, type SubagentDefinition as a8, type SubagentFnResult as a9, type WorkflowTask as aA, type ZeitlichSession as aB, isTerminalStatus as aC, type ToolRouterOptions as aD, type SubagentHandlerResponse as aa, type SubagentHooks as ab, type SubagentSandboxConfig as ac, type SubagentSandboxShutdown as ad, type SubagentSessionInput as ae, type SubagentWorkflow as af, type SubagentWorkflowInput as ag, type TaskStatus as ah, type ThreadInit as ai, type TokenUsage as aj, type ToolArgs as ak, type ToolCallResult as al, type ToolCallResultUnion as am, type ToolDefinition as an, type ToolHandler as ao, type ToolHooks as ap, type ToolMap as aq, type ToolNames as ar, type ToolResult as as, type ToolRouter as at, type ToolRouterHooks as au, type ToolWithHandler as av, VirtualFileSystem as aw, type VirtualFileTree as ax, type VirtualFsOps as ay, type VirtualFsState as az, type ToolHandlerResponse as b, type ActivityToolHandler as c, type ToolResultConfig as d, type RunAgentConfig as e, type SkillProvider as f, type SkillMetadata as g, type Skill as h, type FileResolver as i, type TreeMutation as j, type PrefixedVirtualFsOps as k, type AgentConfig as l, type AgentFile as m, type AgentState as n, type AgentStateManager as o, type AgentStatus as p, type AppendToolResultFn as q, type FileEntry as r, type JsonPrimitive as s, type JsonSerializable as t, type ParsedToolCall as u, type ParsedToolCallUnion as v, type PostHumanMessageAppendHook as w, type PostHumanMessageAppendHookContext as x, type PostToolUseFailureHook as y, type PostToolUseFailureHookContext as z };
1457
+ export { type SandboxShutdown as $, type AgentResponse as A, type BaseAgentState as B, type PostToolUseFailureHookContext as C, type PostToolUseFailureHookResult as D, type PostToolUseHook as E, type FileEntryMetadata as F, type PostToolUseHookContext as G, type Hooks as H, type InferToolResults as I, type JsonValue as J, type PreHumanMessageAppendHook as K, type PreHumanMessageAppendHookContext as L, type ModelInvokerConfig as M, type PreToolUseHook as N, type PreToolUseHookContext as O, type PersistedThreadState as P, type PreToolUseHookResult as Q, type RouterContext as R, type ScopedPrefix as S, type ThreadOps as T, type ProcessToolCallsContext as U, type VirtualFsContext as V, type ProcessToolCallsResult as W, type RawToolCall as X, type RewindSignal as Y, type RunAgentActivity as Z, type SandboxInit as _, type ModelInvoker as a, type SerializableToolDefinition as a0, type SessionConfig as a1, type SessionEndHook as a2, type SessionEndHookContext as a3, type SessionExitReason as a4, type SessionResult as a5, type SessionStartHook as a6, type SessionStartHookContext as a7, type SubagentChildWorkflowOptions as a8, type SubagentConfig as a9, type VirtualFsOps as aA, type VirtualFsState as aB, type WorkflowTask as aC, type ZeitlichSession as aD, isTerminalStatus as aE, type ToolRouterOptions as aF, type SubagentDefinition as aa, type SubagentFnResult as ab, type SubagentHandlerResponse as ac, type SubagentHooks as ad, type SubagentSandboxConfig as ae, type SubagentSandboxShutdown as af, type SubagentSessionInput as ag, type SubagentWorkflow as ah, type SubagentWorkflowInput as ai, type TaskStatus as aj, type ThreadInit as ak, type TokenUsage as al, type ToolArgs as am, type ToolCallResult as an, type ToolCallResultUnion as ao, type ToolDefinition as ap, type ToolHandler as aq, type ToolHooks as ar, type ToolMap as as, type ToolNames as at, type ToolResult as au, type ToolRouter as av, type ToolRouterHooks as aw, type ToolWithHandler as ax, VirtualFileSystem as ay, type VirtualFileTree as az, type PrefixedThreadOps as b, type ToolHandlerResponse as c, type ActivityToolHandler as d, type ToolResultConfig as e, type RunAgentConfig as f, type SkillProvider as g, type SkillMetadata as h, type Skill as i, type FileResolver as j, type TreeMutation as k, type PrefixedVirtualFsOps as l, type AgentConfig as m, type AgentFile as n, type AgentState as o, type AgentStateManager as p, type AgentStatus as q, type AppendToolResultFn as r, type FileEntry as s, type JsonPrimitive as t, type JsonSerializable as u, type ParsedToolCall as v, type ParsedToolCallUnion as w, type PostHumanMessageAppendHook as x, type PostHumanMessageAppendHookContext as y, type PostToolUseFailureHook as z };
@@ -1,5 +1,5 @@
1
1
  import Redis from 'ioredis';
2
- import { J as JsonValue } from './types-DNr31FzL.js';
2
+ import { P as PersistedThreadState, J as JsonValue } from './types-Dt8-HBBT.js';
3
3
 
4
4
  interface ThreadManagerConfig<T> {
5
5
  redis: Redis;
@@ -34,17 +34,50 @@ interface BaseThreadManager<T> {
34
34
  * forks — each call creates an independent copy.
35
35
  */
36
36
  fork(newThreadId: string): Promise<BaseThreadManager<T>>;
37
+ /**
38
+ * Atomically replace the entire contents of the thread with `messages`.
39
+ * The existing list is cleared, the new messages are appended in order,
40
+ * and dedup markers from prior appends are cleared so future idempotent
41
+ * appends with ids that were removed aren't silently skipped.
42
+ *
43
+ * Requires the thread manager to be configured with `idOf`.
44
+ */
45
+ replaceAll(messages: T[]): Promise<void>;
37
46
  /** Delete the thread */
38
47
  delete(): Promise<void>;
39
48
  /** Get the number of stored messages currently in the thread */
40
49
  length(): Promise<number>;
41
50
  /**
42
- * Truncate the thread to the given length (inclusive). Any messages
43
- * beyond `length` are removed. When `length` is 0 the thread ends up
44
- * empty (but still exists). Also clears any dedup markers so that
45
- * subsequent appends with the same ids replay correctly.
51
+ * Truncate the thread starting at the message with id `messageId`.
52
+ * That message and every message after it are removed. If `messageId`
53
+ * is not present in the thread this is a no-op — useful as the
54
+ * "truncate on entry" step of the `runAgent` activity, which becomes a
55
+ * no-op on the first attempt and a cleanup on Temporal workflow reset
56
+ * or in-workflow rewind retries.
57
+ *
58
+ * Dedup markers for removed single-message appends are also cleared so
59
+ * that appending the same id again (e.g. the same assistant message id
60
+ * on a rewind retry) is not silently skipped.
61
+ *
62
+ * Requires the thread manager to be configured with `idOf`.
63
+ */
64
+ truncateFromId(messageId: string): Promise<void>;
65
+ /**
66
+ * Load the persisted state slice associated with this thread, or
67
+ * `null` if none has been saved yet. Safe to call on any thread —
68
+ * treats a missing slice as a non-error.
69
+ */
70
+ loadState(): Promise<PersistedThreadState | null>;
71
+ /**
72
+ * Overwrite the persisted state slice for this thread. The thread
73
+ * itself must already exist (same TTL as the message list).
74
+ *
75
+ * Note: {@link BaseThreadManager.fork} already copies the slice to
76
+ * the new thread, so there's no separate `forkState` method.
46
77
  */
47
- truncate(length: number): Promise<void>;
78
+ saveState(state: PersistedThreadState): Promise<void>;
79
+ /** Delete just the persisted state slice, leaving messages intact. */
80
+ deleteState(): Promise<void>;
48
81
  }
49
82
  /**
50
83
  * Shared contract for provider-specific thread managers.
@@ -72,6 +105,21 @@ interface ThreadManagerHooks<TStored, TPrepared = TStored> {
72
105
  onPrepareMessage?: (message: TStored, index: number, thread: readonly TStored[]) => TStored;
73
106
  /** Called for each SDK-native message after all processing, right before the payload is returned */
74
107
  onPreparedMessage?: (message: TPrepared, index: number, messages: readonly TPrepared[]) => TPrepared;
108
+ /**
109
+ * One-shot list-level pre-pass applied once when a thread is forked with
110
+ * `transform: true`. Runs before {@link onForkTransform}. May filter,
111
+ * compact, prepend, or otherwise rewrite the whole forked thread — so the
112
+ * returned length need not match the input length. Async, so implementations
113
+ * may call an LLM or other I/O.
114
+ */
115
+ onForkPrepareThread?: (messages: readonly TStored[]) => TStored[] | Promise<TStored[]>;
116
+ /**
117
+ * Per-message final pass applied once when a thread is forked with
118
+ * `transform: true`. Runs after {@link onForkPrepareThread}. Pure 1:1 map —
119
+ * must return a value for every input message; length cannot change. Same
120
+ * shape as {@link onPreparedMessage}.
121
+ */
122
+ onForkTransform?: (message: TStored, index: number, messages: readonly TStored[]) => TStored;
75
123
  }
76
124
  interface ProviderThreadManager<TStored, TContent = string, TToolContent = JsonValue, TSystemContent = string> extends BaseThreadManager<TStored> {
77
125
  appendUserMessage(id: string, content: TContent): Promise<void>;