zeitlich 0.2.28 → 0.2.30

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 (144) hide show
  1. package/README.md +121 -13
  2. package/dist/{activities-3xj_fEJK.d.ts → activities-BeveyY9b.d.cts} +2 -3
  3. package/dist/{activities-BzYq6jf7.d.cts → activities-NT3rcw66.d.ts} +2 -3
  4. package/dist/adapters/sandbox/bedrock/index.cjs.map +1 -1
  5. package/dist/adapters/sandbox/bedrock/index.d.cts +3 -3
  6. package/dist/adapters/sandbox/bedrock/index.d.ts +3 -3
  7. package/dist/adapters/sandbox/bedrock/index.js.map +1 -1
  8. package/dist/adapters/sandbox/bedrock/workflow.d.cts +2 -2
  9. package/dist/adapters/sandbox/bedrock/workflow.d.ts +2 -2
  10. package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
  11. package/dist/adapters/sandbox/daytona/index.d.cts +1 -1
  12. package/dist/adapters/sandbox/daytona/index.d.ts +1 -1
  13. package/dist/adapters/sandbox/daytona/index.js.map +1 -1
  14. package/dist/adapters/sandbox/daytona/workflow.d.cts +1 -1
  15. package/dist/adapters/sandbox/daytona/workflow.d.ts +1 -1
  16. package/dist/adapters/sandbox/e2b/index.cjs.map +1 -1
  17. package/dist/adapters/sandbox/e2b/index.d.cts +1 -1
  18. package/dist/adapters/sandbox/e2b/index.d.ts +1 -1
  19. package/dist/adapters/sandbox/e2b/index.js.map +1 -1
  20. package/dist/adapters/sandbox/e2b/workflow.d.cts +1 -1
  21. package/dist/adapters/sandbox/e2b/workflow.d.ts +1 -1
  22. package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
  23. package/dist/adapters/sandbox/inmemory/index.d.cts +1 -1
  24. package/dist/adapters/sandbox/inmemory/index.d.ts +1 -1
  25. package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
  26. package/dist/adapters/sandbox/inmemory/workflow.d.cts +1 -1
  27. package/dist/adapters/sandbox/inmemory/workflow.d.ts +1 -1
  28. package/dist/adapters/thread/anthropic/index.cjs +0 -1
  29. package/dist/adapters/thread/anthropic/index.cjs.map +1 -1
  30. package/dist/adapters/thread/anthropic/index.d.cts +6 -7
  31. package/dist/adapters/thread/anthropic/index.d.ts +6 -7
  32. package/dist/adapters/thread/anthropic/index.js +0 -1
  33. package/dist/adapters/thread/anthropic/index.js.map +1 -1
  34. package/dist/adapters/thread/anthropic/workflow.d.cts +5 -6
  35. package/dist/adapters/thread/anthropic/workflow.d.ts +5 -6
  36. package/dist/adapters/thread/google-genai/index.cjs +0 -1
  37. package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
  38. package/dist/adapters/thread/google-genai/index.d.cts +6 -7
  39. package/dist/adapters/thread/google-genai/index.d.ts +6 -7
  40. package/dist/adapters/thread/google-genai/index.js +0 -1
  41. package/dist/adapters/thread/google-genai/index.js.map +1 -1
  42. package/dist/adapters/thread/google-genai/workflow.d.cts +5 -6
  43. package/dist/adapters/thread/google-genai/workflow.d.ts +5 -6
  44. package/dist/adapters/thread/langchain/index.cjs +0 -1
  45. package/dist/adapters/thread/langchain/index.cjs.map +1 -1
  46. package/dist/adapters/thread/langchain/index.d.cts +6 -7
  47. package/dist/adapters/thread/langchain/index.d.ts +6 -7
  48. package/dist/adapters/thread/langchain/index.js +0 -1
  49. package/dist/adapters/thread/langchain/index.js.map +1 -1
  50. package/dist/adapters/thread/langchain/workflow.d.cts +5 -6
  51. package/dist/adapters/thread/langchain/workflow.d.ts +5 -6
  52. package/dist/index.cjs +558 -50
  53. package/dist/index.cjs.map +1 -1
  54. package/dist/index.d.cts +136 -22
  55. package/dist/index.d.ts +136 -22
  56. package/dist/index.js +554 -52
  57. package/dist/index.js.map +1 -1
  58. package/dist/{proxy-7e7v8ccg.d.ts → proxy-BgswT47M.d.ts} +1 -1
  59. package/dist/{proxy-CsB8r0RR.d.cts → proxy-OJihshQF.d.cts} +1 -1
  60. package/dist/{thread-manager-D8C5QvLi.d.ts → thread-manager-BS477gj8.d.ts} +1 -1
  61. package/dist/{thread-manager-DdVFl1IY.d.cts → thread-manager-DH0zv05W.d.cts} +1 -1
  62. package/dist/{thread-manager-B5qA4v7V.d.ts → thread-manager-iUplxEZt.d.ts} +1 -1
  63. package/dist/{thread-manager-DFJ3sKKU.d.cts → thread-manager-lfN0V-gH.d.cts} +1 -1
  64. package/dist/{types-ChAMwU3q.d.cts → types-AujBIMMn.d.cts} +5 -8
  65. package/dist/{types-ChAMwU3q.d.ts → types-AujBIMMn.d.ts} +5 -8
  66. package/dist/{types-BZ75HpYd.d.ts → types-CCIc7Eam.d.ts} +1 -1
  67. package/dist/types-D90Q5aOh.d.ts +1212 -0
  68. package/dist/{types-BdCdR41N.d.ts → types-DBk-C8zM.d.ts} +1 -1
  69. package/dist/{types-ZHs2v9Ap.d.cts → types-DUvEZSDe.d.cts} +1 -1
  70. package/dist/types-DVdT5ybA.d.cts +1212 -0
  71. package/dist/{types-HbjqzyJH.d.cts → types-DgIVPOa1.d.cts} +1 -1
  72. package/dist/workflow-Cj4DxGdM.d.cts +750 -0
  73. package/dist/workflow-CzrBdCcJ.d.ts +750 -0
  74. package/dist/workflow.cjs +194 -40
  75. package/dist/workflow.cjs.map +1 -1
  76. package/dist/workflow.d.cts +5 -579
  77. package/dist/workflow.d.ts +5 -579
  78. package/dist/workflow.js +193 -42
  79. package/dist/workflow.js.map +1 -1
  80. package/package.json +3 -23
  81. package/src/adapters/thread/anthropic/thread-manager.ts +6 -6
  82. package/src/adapters/thread/google-genai/thread-manager.ts +6 -6
  83. package/src/adapters/thread/langchain/thread-manager.ts +6 -6
  84. package/src/index.ts +8 -0
  85. package/src/lib/lifecycle.ts +8 -3
  86. package/src/lib/observability/hooks.ts +117 -0
  87. package/src/lib/observability/index.ts +13 -0
  88. package/src/lib/observability/sinks.ts +88 -0
  89. package/src/lib/sandbox/index.ts +2 -4
  90. package/src/lib/sandbox/manager.ts +131 -16
  91. package/src/lib/sandbox/sandbox.test.ts +136 -16
  92. package/src/lib/sandbox/types.ts +6 -5
  93. package/src/lib/session/session-edge-cases.integration.test.ts +1 -0
  94. package/src/lib/session/session.integration.test.ts +7 -39
  95. package/src/lib/session/session.ts +119 -42
  96. package/src/lib/session/types.ts +39 -9
  97. package/src/lib/state/manager.integration.test.ts +1 -0
  98. package/src/lib/state/types.ts +9 -6
  99. package/src/lib/subagent/handler.ts +35 -12
  100. package/src/lib/subagent/register.ts +11 -12
  101. package/src/lib/subagent/subagent.integration.test.ts +1 -0
  102. package/src/lib/tool-router/router-edge-cases.integration.test.ts +2 -0
  103. package/src/lib/tool-router/router.integration.test.ts +2 -0
  104. package/src/lib/tool-router/router.ts +24 -2
  105. package/src/lib/types.ts +2 -0
  106. package/src/{adapters/sandbox/virtual → lib/virtual-fs}/filesystem.ts +4 -4
  107. package/src/lib/virtual-fs/index.ts +18 -0
  108. package/src/lib/virtual-fs/manager.ts +48 -0
  109. package/src/lib/virtual-fs/proxy.ts +45 -0
  110. package/src/{adapters/sandbox/virtual → lib/virtual-fs}/types.ts +41 -37
  111. package/src/{adapters/sandbox/virtual/virtual-sandbox.test.ts → lib/virtual-fs/virtual-fs.test.ts} +15 -130
  112. package/src/lib/virtual-fs/with-virtual-fs.ts +94 -0
  113. package/src/tools/bash/bash.test.ts +2 -1
  114. package/src/workflow.ts +25 -8
  115. package/tsup.config.ts +0 -2
  116. package/dist/adapters/sandbox/virtual/index.cjs +0 -487
  117. package/dist/adapters/sandbox/virtual/index.cjs.map +0 -1
  118. package/dist/adapters/sandbox/virtual/index.d.cts +0 -90
  119. package/dist/adapters/sandbox/virtual/index.d.ts +0 -90
  120. package/dist/adapters/sandbox/virtual/index.js +0 -479
  121. package/dist/adapters/sandbox/virtual/index.js.map +0 -1
  122. package/dist/adapters/sandbox/virtual/workflow.cjs +0 -33
  123. package/dist/adapters/sandbox/virtual/workflow.cjs.map +0 -1
  124. package/dist/adapters/sandbox/virtual/workflow.d.cts +0 -28
  125. package/dist/adapters/sandbox/virtual/workflow.d.ts +0 -28
  126. package/dist/adapters/sandbox/virtual/workflow.js +0 -31
  127. package/dist/adapters/sandbox/virtual/workflow.js.map +0 -1
  128. package/dist/queries-DVnukByF.d.cts +0 -44
  129. package/dist/queries-kjlvsUfz.d.ts +0 -44
  130. package/dist/types-BclYm5Ic.d.cts +0 -581
  131. package/dist/types-BclYm5Ic.d.ts +0 -581
  132. package/dist/types-BgsAwN3L.d.cts +0 -125
  133. package/dist/types-BtqbM1bO.d.ts +0 -490
  134. package/dist/types-BuCEZ4dF.d.cts +0 -490
  135. package/dist/types-yU5AINiP.d.ts +0 -125
  136. package/src/adapters/sandbox/virtual/index.ts +0 -92
  137. package/src/adapters/sandbox/virtual/provider.ts +0 -121
  138. package/src/adapters/sandbox/virtual/proxy.ts +0 -53
  139. package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +0 -97
  140. package/src/lib/.env +0 -1
  141. package/src/tools/bash/.env +0 -1
  142. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/mutations.ts +0 -0
  143. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/queries.ts +0 -0
  144. /package/src/{adapters/sandbox/virtual → lib/virtual-fs}/tree.ts +0 -0
@@ -0,0 +1,1212 @@
1
+ import { Duration } from '@temporalio/common';
2
+ import { ActivityFunctionWithOptions, QueryDefinition, ActivityInterfaceFor } from '@temporalio/workflow';
3
+ import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
4
+ import { z } from 'zod';
5
+ import { a as SandboxFileSystem, F as FileStat, D as DirentEntry, g as SandboxOps } from './types-AujBIMMn.cjs';
6
+
7
+ /**
8
+ * A tool definition with a name, description, and Zod schema for arguments.
9
+ * Does not include a handler - use ToolWithHandler for tools with handlers.
10
+ */
11
+ interface ToolDefinition<TName extends string = string, TSchema extends z.ZodType = z.ZodType> {
12
+ name: TName;
13
+ description: string;
14
+ schema: TSchema;
15
+ strict?: boolean;
16
+ max_uses?: number;
17
+ }
18
+ /**
19
+ * A tool definition with an integrated handler function.
20
+ * This is the primary type for defining tools in the router.
21
+ */
22
+ interface ToolWithHandler<TName extends string = string, TSchema extends z.ZodType = z.ZodType, TResult = unknown, TContext extends RouterContext = RouterContext, TToolResponse = JsonValue> {
23
+ name: TName;
24
+ description: string;
25
+ schema: TSchema;
26
+ handler: ToolHandler<z.infer<TSchema>, TResult, TContext, TToolResponse>;
27
+ strict?: boolean;
28
+ max_uses?: number;
29
+ /** Whether this tool is available to the agent (default: true). Disabled tools are excluded from definitions and rejected at parse time. */
30
+ enabled?: boolean | (() => boolean);
31
+ /** Per-tool lifecycle hooks (run in addition to global hooks) */
32
+ hooks?: ToolHooks<z.infer<TSchema>, TResult>;
33
+ }
34
+ /**
35
+ * A map of tool keys to tool definitions with handlers.
36
+ *
37
+ * Handler uses `any` intentionally — this is a type-system boundary where heterogeneous
38
+ * tool types are stored together. Type safety for individual tools is enforced by
39
+ * `defineTool()` at the definition site and generic inference utilities like
40
+ * `InferToolResults<T>` at the consumption site.
41
+ */
42
+ type ToolMap = Record<string, {
43
+ name: string;
44
+ description: string | (() => string);
45
+ schema: z.ZodType | (() => z.ZodType);
46
+ handler: ToolHandler<any, any, any, any>;
47
+ strict?: boolean;
48
+ max_uses?: number;
49
+ enabled?: boolean | (() => boolean);
50
+ hooks?: ToolHooks<any, any>;
51
+ }>;
52
+ /**
53
+ * Extract the tool names from a tool map (uses the tool's name property, not the key).
54
+ */
55
+ type ToolNames<T extends ToolMap> = T[keyof T]["name"];
56
+ /**
57
+ * A raw tool call as received from the LLM before parsing.
58
+ */
59
+ interface RawToolCall {
60
+ id?: string;
61
+ name: string;
62
+ args: unknown;
63
+ }
64
+ /**
65
+ * A parsed tool call with validated arguments for a specific tool.
66
+ */
67
+ interface ParsedToolCall<TName extends string = string, TArgs = unknown> {
68
+ id: string;
69
+ name: TName;
70
+ args: TArgs;
71
+ }
72
+ /**
73
+ * Union type of all possible parsed tool calls from a tool map.
74
+ */
75
+ type ParsedToolCallUnion<T extends ToolMap> = {
76
+ [K in keyof T]: ParsedToolCall<T[K]["name"], z.infer<T[K]["schema"]>>;
77
+ }[keyof T];
78
+ /**
79
+ * Function signature for appending tool results to a thread.
80
+ */
81
+ type AppendToolResultFn = ActivityFunctionWithOptions<(id: string, config: ToolResultConfig) => Promise<void>>;
82
+ /**
83
+ * The response from a tool handler.
84
+ * Contains the content for the tool message and the result to return from processToolCalls.
85
+ *
86
+ * Tools that don't return additional data should use `data: null` (TResult defaults to null).
87
+ * Tools that may fail to produce data should type TResult as `SomeType | null`.
88
+ */
89
+ interface ToolHandlerResponse<TResult = null, TToolResponse = JsonValue> {
90
+ /** Content sent back to the LLM as the tool call response */
91
+ toolResponse: TToolResponse;
92
+ /** Data returned to the workflow and hooks for further processing */
93
+ data: TResult;
94
+ /**
95
+ * When true, the tool result has already been appended to the thread
96
+ * by the handler itself (e.g. via `withAutoAppend`), so the router
97
+ * will skip the `appendToolResult` call. This avoids sending large
98
+ * payloads through Temporal's activity payload limit.
99
+ */
100
+ resultAppended?: boolean;
101
+ /** Token usage from the tool execution (e.g. child agent invocations) */
102
+ usage?: TokenUsage;
103
+ /** Thread ID used by the handler (surfaced to the LLM for subagent thread continuation) */
104
+ threadId?: string;
105
+ /** Sandbox ID created or used by the handler (e.g. child agent sandbox) */
106
+ sandboxId?: string;
107
+ /** Unvalidated metadata passthrough from handler to hooks (e.g. infrastructure state) */
108
+ metadata?: Record<string, unknown>;
109
+ }
110
+ /**
111
+ * Base context the router always injects into every handler invocation.
112
+ * Handlers can rely on these fields being present without casting.
113
+ */
114
+ interface RouterContext {
115
+ threadId: string;
116
+ /** Redis key suffix for thread storage. Defaults to 'messages'. */
117
+ threadKey?: string;
118
+ toolCallId: string;
119
+ toolName: string;
120
+ sandboxId?: string;
121
+ }
122
+ /**
123
+ * A handler function for a specific tool.
124
+ * Receives the parsed args and a context that always includes {@link RouterContext}
125
+ * fields, plus any additional properties when TContext extends RouterContext.
126
+ */
127
+ type ToolHandler<TArgs, TResult, TContext extends RouterContext = RouterContext, TToolResponse = JsonValue> = (args: TArgs, context: TContext) => ToolHandlerResponse<TResult, TToolResponse> | Promise<ToolHandlerResponse<TResult, TToolResponse>>;
128
+ /**
129
+ * Activity-compatible tool handler that always returns a Promise.
130
+ * Use this for tool handlers registered as Temporal activities.
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const readHandler: ActivityToolHandler<
135
+ * FileReadArgs,
136
+ * ReadResult,
137
+ * RouterContext & { scopedNodes: FileNode[]; provider: FileSystemProvider }
138
+ * > = async (args, context) => {
139
+ * // context.threadId, context.sandboxId etc. are always available
140
+ * return readHandler(args, context.scopedNodes, context.provider);
141
+ * };
142
+ * ```
143
+ */
144
+ type ActivityToolHandler<TArgs, TResult, TContext extends RouterContext = RouterContext, TToolResponse = JsonValue> = (args: TArgs, context: TContext) => Promise<ToolHandlerResponse<TResult, TToolResponse>>;
145
+ /**
146
+ * Extract the args type for a specific tool name from a tool map.
147
+ */
148
+ type ToolArgs<T extends ToolMap, TName extends ToolNames<T>> = z.infer<Extract<T[keyof T], {
149
+ name: TName;
150
+ }>["schema"]>;
151
+ /**
152
+ * Extract the result type for a specific tool name from a tool map.
153
+ */
154
+ type ToolResult<T extends ToolMap, TName extends ToolNames<T>> = Extract<T[keyof T], {
155
+ name: TName;
156
+ }>["handler"] extends ToolHandler<unknown, infer R, RouterContext, any> ? Awaited<R> : never;
157
+ /**
158
+ * The result of processing a tool call.
159
+ */
160
+ interface ToolCallResult<TName extends string = string, TResult = unknown> {
161
+ toolCallId: string;
162
+ name: TName;
163
+ data: TResult;
164
+ usage?: TokenUsage;
165
+ /** Unvalidated metadata passthrough from handler to hooks (e.g. infrastructure state) */
166
+ metadata?: Record<string, unknown>;
167
+ }
168
+ /**
169
+ * Infer result types from a tool map based on handler return types.
170
+ */
171
+ type InferToolResults<T extends ToolMap> = {
172
+ [K in keyof T as T[K]["name"]]: T[K]["handler"] extends ToolHandler<any, infer R, any, any> ? Awaited<R> : never;
173
+ };
174
+ /**
175
+ * Union of all possible tool call results based on handler return types.
176
+ */
177
+ type ToolCallResultUnion<TResults extends Record<string, unknown>> = {
178
+ [TName in keyof TResults & string]: ToolCallResult<TName, TResults[TName]>;
179
+ }[keyof TResults & string];
180
+ /**
181
+ * Context passed to processToolCalls for hook execution and handler invocation
182
+ */
183
+ interface ProcessToolCallsContext {
184
+ /** Current turn number (for hooks) */
185
+ turn?: number;
186
+ /** Active sandbox ID (when a sandbox is configured for this session) */
187
+ sandboxId?: string;
188
+ }
189
+ /**
190
+ * Result from PreToolUse hook - can block or modify execution
191
+ */
192
+ interface PreToolUseHookResult {
193
+ /** Skip this tool call entirely */
194
+ skip?: boolean;
195
+ /** Modified args to use instead (must match schema) */
196
+ modifiedArgs?: unknown;
197
+ }
198
+ /**
199
+ * Result from PostToolUseFailure hook - can recover from errors
200
+ */
201
+ interface PostToolUseFailureHookResult {
202
+ /** Provide a fallback result instead of throwing */
203
+ fallbackContent?: JsonValue;
204
+ /** Whether to suppress the error (still logs, but continues) */
205
+ suppress?: boolean;
206
+ }
207
+ /**
208
+ * Per-tool lifecycle hooks - defined directly on a tool definition.
209
+ * Runs in addition to global hooks (global pre → tool pre → execute → tool post → global post).
210
+ */
211
+ interface ToolHooks<TArgs = unknown, TResult = unknown> {
212
+ /** Called before this tool executes - can skip or modify args */
213
+ onPreToolUse?: (ctx: {
214
+ args: TArgs;
215
+ threadId: string;
216
+ turn: number;
217
+ }) => PreToolUseHookResult | Promise<PreToolUseHookResult>;
218
+ /** Called after this tool executes successfully */
219
+ onPostToolUse?: (ctx: {
220
+ args: TArgs;
221
+ result: TResult;
222
+ threadId: string;
223
+ turn: number;
224
+ durationMs: number;
225
+ metadata?: Record<string, unknown>;
226
+ }) => void | Promise<void>;
227
+ /** Called when this tool execution fails */
228
+ onPostToolUseFailure?: (ctx: {
229
+ args: TArgs;
230
+ error: Error;
231
+ threadId: string;
232
+ turn: number;
233
+ }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
234
+ }
235
+ /**
236
+ * Context for PreToolUse hook - called before tool execution
237
+ */
238
+ interface PreToolUseHookContext<T extends ToolMap> {
239
+ /** The tool call about to be executed */
240
+ toolCall: ParsedToolCallUnion<T>;
241
+ /** Thread identifier */
242
+ threadId: string;
243
+ /** Current turn number */
244
+ turn: number;
245
+ }
246
+ /**
247
+ * PreToolUse hook - called before tool execution, can block or modify
248
+ */
249
+ type PreToolUseHook<T extends ToolMap> = (ctx: PreToolUseHookContext<T>) => PreToolUseHookResult | Promise<PreToolUseHookResult>;
250
+ /**
251
+ * Context for PostToolUse hook - called after successful tool execution
252
+ */
253
+ interface PostToolUseHookContext<T extends ToolMap, TResult = unknown> {
254
+ /** The tool call that was executed */
255
+ toolCall: ParsedToolCallUnion<T>;
256
+ /** The result from the tool handler */
257
+ result: TResult;
258
+ /** Thread identifier */
259
+ threadId: string;
260
+ /** Current turn number */
261
+ turn: number;
262
+ /** Execution duration in milliseconds */
263
+ durationMs: number;
264
+ }
265
+ /**
266
+ * PostToolUse hook - called after successful tool execution
267
+ */
268
+ type PostToolUseHook<T extends ToolMap, TResult = unknown> = (ctx: PostToolUseHookContext<T, TResult>) => void | Promise<void>;
269
+ /**
270
+ * Context for PostToolUseFailure hook - called when tool execution fails
271
+ */
272
+ interface PostToolUseFailureHookContext<T extends ToolMap> {
273
+ /** The tool call that failed */
274
+ toolCall: ParsedToolCallUnion<T>;
275
+ /** The error that occurred */
276
+ error: Error;
277
+ /** Thread identifier */
278
+ threadId: string;
279
+ /** Current turn number */
280
+ turn: number;
281
+ }
282
+ /**
283
+ * PostToolUseFailure hook - called when tool execution fails
284
+ */
285
+ type PostToolUseFailureHook<T extends ToolMap> = (ctx: PostToolUseFailureHookContext<T>) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
286
+ /**
287
+ * Tool execution hooks — the subset of hooks consumed by the tool router.
288
+ * Session/message lifecycle hooks live in lib/hooks/types.ts.
289
+ */
290
+ interface ToolRouterHooks<T extends ToolMap, TResult = unknown> {
291
+ /** Called before each tool execution - can block or modify */
292
+ onPreToolUse?: PreToolUseHook<T>;
293
+ /** Called after each successful tool execution */
294
+ onPostToolUse?: PostToolUseHook<T, TResult>;
295
+ /** Called when tool execution fails */
296
+ onPostToolUseFailure?: PostToolUseFailureHook<T>;
297
+ }
298
+ /**
299
+ * Options for creating a tool router.
300
+ */
301
+ interface ToolRouterOptions<T extends ToolMap> {
302
+ /** Map of tools with their handlers */
303
+ tools: T;
304
+ /** Thread ID for appending tool results */
305
+ threadId: string;
306
+ /** Redis key suffix for thread storage. Defaults to 'messages'. */
307
+ threadKey?: string;
308
+ /** Function to append tool results to the thread (called automatically after each handler).
309
+ * Accepts a Temporal activity proxy with {@link ActivityFunctionWithOptions}. */
310
+ appendToolResult: AppendToolResultFn;
311
+ /** Whether to process tools in parallel (default: true) */
312
+ parallel?: boolean;
313
+ /** Tool execution lifecycle hooks (pre/post tool use) */
314
+ hooks?: ToolRouterHooks<T, ToolCallResultUnion<InferToolResults<T>>>;
315
+ /** Additional tools to auto-register (e.g. subagent, skill tools built by register helpers) */
316
+ plugins?: ToolMap[string][];
317
+ }
318
+ /**
319
+ * The tool router interface with full type inference for both args and results.
320
+ */
321
+ interface ToolRouter<T extends ToolMap> {
322
+ /** Check if the router has any tools */
323
+ hasTools(): boolean;
324
+ /**
325
+ * Parse and validate a raw tool call against the router's tools.
326
+ * Returns a typed tool call with validated arguments.
327
+ */
328
+ parseToolCall(toolCall: RawToolCall): ParsedToolCallUnion<T>;
329
+ /**
330
+ * Check if a tool with the given name exists in the router.
331
+ */
332
+ hasTool(name: string): boolean;
333
+ /**
334
+ * Get all tool names in the router.
335
+ */
336
+ getToolNames(): ToolNames<T>[];
337
+ /**
338
+ * Get all tool definitions (without handlers) for passing to LLM.
339
+ */
340
+ getToolDefinitions(): ToolDefinition[];
341
+ /**
342
+ * Process all tool calls using the registered handlers.
343
+ * Returns typed results based on handler return types.
344
+ * @param toolCalls - Array of parsed tool calls to process
345
+ * @param context - Optional context including turn number for hooks
346
+ */
347
+ processToolCalls(toolCalls: ParsedToolCallUnion<T>[], context?: ProcessToolCallsContext): Promise<ToolCallResultUnion<InferToolResults<T>>[]>;
348
+ /**
349
+ * Process tool calls matching a specific name with a custom handler.
350
+ * Useful for overriding the default handler for specific cases.
351
+ */
352
+ processToolCallsByName<TName extends ToolNames<T>, TResult>(toolCalls: ParsedToolCallUnion<T>[], toolName: TName, handler: ToolHandler<ToolArgs<T, TName>, TResult>, context?: ProcessToolCallsContext): Promise<ToolCallResult<TName, TResult>[]>;
353
+ /**
354
+ * Filter tool calls by name.
355
+ */
356
+ filterByName<TName extends ToolNames<T>>(toolCalls: ParsedToolCallUnion<T>[], name: TName): ParsedToolCall<TName, ToolArgs<T, TName>>[];
357
+ /**
358
+ * Check if any tool call matches the given name.
359
+ */
360
+ hasToolCall(toolCalls: ParsedToolCallUnion<T>[], name: ToolNames<T>): boolean;
361
+ /**
362
+ * Filter results by tool name.
363
+ */
364
+ getResultsByName<TName extends ToolNames<T>>(results: ToolCallResultUnion<InferToolResults<T>>[], name: TName): ToolCallResult<TName, ToolResult<T, TName>>[];
365
+ }
366
+
367
+ /**
368
+ * JSON primitive types that Temporal can serialize
369
+ */
370
+ type JsonPrimitive = string | number | boolean | null | undefined;
371
+ /**
372
+ * JSON-serializable value (recursive type for Temporal compatibility)
373
+ */
374
+ type JsonValue = JsonPrimitive | JsonValue[] | {
375
+ [key: string]: JsonValue;
376
+ };
377
+ /**
378
+ * Type constraint ensuring T only contains JSON-serializable values.
379
+ * Use this for custom state to ensure Temporal workflow compatibility.
380
+ *
381
+ * Allows: primitives, arrays, plain objects, and JsonValue
382
+ * Rejects: functions, symbols, undefined, class instances with methods
383
+ */
384
+ type JsonSerializable<T> = {
385
+ [K in keyof T]: T[K] extends JsonValue ? T[K] : T[K] extends JsonPrimitive ? T[K] : T[K] extends (infer U)[] ? U extends JsonValue ? T[K] : JsonSerializable<U>[] : T[K] extends object ? JsonSerializable<T[K]> : never;
386
+ };
387
+ /**
388
+ * Full state type combining base state with custom state
389
+ */
390
+ type AgentState<TCustom extends JsonSerializable<TCustom>> = BaseAgentState & TCustom;
391
+ /**
392
+ * Agent state manager interface
393
+ * Note: Temporal handlers must be set up in the workflow file due to
394
+ * Temporal's workflow isolation requirements. This manager provides
395
+ * the state and helpers needed for those handlers.
396
+ */
397
+ interface AgentStateManager<TCustom extends JsonSerializable<TCustom>> {
398
+ /** Typed query definition registered for this agent's state */
399
+ readonly stateQuery: QueryDefinition<AgentState<TCustom>>;
400
+ /** Typed update definition registered for waiting on this agent's state change */
401
+ readonly stateChangeUpdate: UpdateDefinition<AgentState<TCustom>, [number]>;
402
+ /** Get current status */
403
+ getStatus(): AgentStatus;
404
+ /** Check if agent is running */
405
+ isRunning(): boolean;
406
+ /** Check if agent is in terminal state */
407
+ isTerminal(): boolean;
408
+ /** Get current state version */
409
+ getVersion(): number;
410
+ /** Set status to RUNNING */
411
+ run(): void;
412
+ /** Set status to WAITING_FOR_INPUT */
413
+ waitForInput(): void;
414
+ /** Set status to COMPLETED */
415
+ complete(): void;
416
+ /** Set status to FAILED */
417
+ fail(): void;
418
+ /** Set status to CANCELLED */
419
+ cancel(): void;
420
+ /** Increment state version (call after state changes) */
421
+ incrementVersion(): void;
422
+ /** Increment turns (call after each turn) */
423
+ incrementTurns(): void;
424
+ /** Get current turns */
425
+ getTurns(): number;
426
+ /** Get the system prompt */
427
+ getSystemPrompt(): string | undefined;
428
+ /** Set the system prompt */
429
+ setSystemPrompt(newSystemPrompt: string): void;
430
+ /** Get a custom state value by key */
431
+ get<K extends keyof TCustom>(key: K): TCustom[K];
432
+ /** Set a custom state value by key */
433
+ set<K extends keyof TCustom>(key: K, value: TCustom[K]): void;
434
+ /** Bulk-merge a partial update into custom state */
435
+ mergeUpdate(update: Partial<AgentState<TCustom>>): void;
436
+ /** Get full state for query handler */
437
+ getCurrentState(): AgentState<TCustom>;
438
+ /** Check if should return from waitForStateChange */
439
+ shouldReturnFromWait(lastKnownVersion: number): boolean;
440
+ /** Get all tasks */
441
+ getTasks(): WorkflowTask[];
442
+ /** Get a task by ID */
443
+ getTask(id: string): WorkflowTask | undefined;
444
+ /** Add or update a task */
445
+ setTask(task: WorkflowTask): void;
446
+ /** Delete a task by ID */
447
+ deleteTask(id: string): boolean;
448
+ /** Set the tools (converts Zod schemas to JSON Schema for serialization) */
449
+ setTools(newTools: ToolDefinition[]): void;
450
+ /** Update the usage */
451
+ updateUsage(usage: TokenUsage): void;
452
+ /** Get the total usage */
453
+ getTotalUsage(): {
454
+ totalInputTokens: number;
455
+ totalOutputTokens: number;
456
+ totalCachedWriteTokens: number;
457
+ totalCachedReadTokens: number;
458
+ totalReasonTokens: number;
459
+ turns: number;
460
+ };
461
+ }
462
+
463
+ /**
464
+ * Ephemeral virtual filesystem backed by a {@link FileResolver}.
465
+ *
466
+ * Created fresh for each tool invocation from the current workflow file tree.
467
+ * Directory structure is inferred from file paths. All mutations are tracked
468
+ * and can be retrieved via {@link getMutations} after the handler completes.
469
+ */
470
+ declare class VirtualFileSystem<TCtx = unknown, TMeta = FileEntryMetadata> implements SandboxFileSystem {
471
+ private resolver;
472
+ private ctx;
473
+ readonly workspaceBase: string;
474
+ private entries;
475
+ private directories;
476
+ private mutations;
477
+ constructor(tree: FileEntry<TMeta>[], resolver: FileResolver<TCtx, TMeta>, ctx: TCtx, workspaceBase?: string);
478
+ /** Return all mutations accumulated during this invocation. */
479
+ getMutations(): TreeMutation<TMeta>[];
480
+ /** Look up a file entry by virtual path. */
481
+ getEntry(path: string): FileEntry<TMeta> | undefined;
482
+ readFile(path: string): Promise<string>;
483
+ readFileBuffer(path: string): Promise<Uint8Array>;
484
+ exists(path: string): Promise<boolean>;
485
+ stat(path: string): Promise<FileStat>;
486
+ readdir(path: string): Promise<string[]>;
487
+ readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
488
+ writeFile(path: string, content: string | Uint8Array): Promise<void>;
489
+ appendFile(path: string, content: string | Uint8Array): Promise<void>;
490
+ mkdir(_path: string, _options?: {
491
+ recursive?: boolean;
492
+ }): Promise<void>;
493
+ rm(path: string, options?: {
494
+ recursive?: boolean;
495
+ force?: boolean;
496
+ }): Promise<void>;
497
+ cp(src: string, dest: string, _options?: {
498
+ recursive?: boolean;
499
+ }): Promise<void>;
500
+ mv(src: string, dest: string): Promise<void>;
501
+ readlink(_path: string): Promise<string>;
502
+ resolvePath(base: string, path: string): string;
503
+ private addParentDirectories;
504
+ }
505
+
506
+ /** Allowed value types for file-entry metadata. */
507
+ type FileEntryMetadata = Record<string, string | number | boolean | null>;
508
+ /** JSON-serializable metadata for a single file in the virtual tree. */
509
+ interface FileEntry<TMeta = FileEntryMetadata> {
510
+ id: string;
511
+ /** Virtual path, e.g. "/src/index.ts" */
512
+ path: string;
513
+ size: number;
514
+ /** ISO-8601 date string (JSON-safe) */
515
+ mtime: string;
516
+ metadata: TMeta;
517
+ }
518
+ /**
519
+ * Flat list of file entries.
520
+ * Directories are inferred from file paths at runtime.
521
+ */
522
+ type VirtualFileTree<TMeta = FileEntryMetadata> = FileEntry<TMeta>[];
523
+ type TreeMutation<TMeta = FileEntryMetadata> = {
524
+ type: "add";
525
+ entry: FileEntry<TMeta>;
526
+ } | {
527
+ type: "remove";
528
+ path: string;
529
+ } | {
530
+ type: "update";
531
+ path: string;
532
+ entry: Partial<FileEntry<TMeta>>;
533
+ };
534
+ /**
535
+ * Consumer-provided bridge to the existing DB / S3 / CRUD layer.
536
+ *
537
+ * Generic over `TCtx` so every call receives workflow-level context
538
+ * (e.g. `{ projectId: string }`) without the resolver holding state.
539
+ *
540
+ * Generic over `TMeta` so resolved entries carry typed metadata.
541
+ */
542
+ interface FileResolver<TCtx = unknown, TMeta = FileEntryMetadata> {
543
+ resolveEntries(ctx: TCtx): Promise<FileEntry<TMeta>[]>;
544
+ readFile(id: string, ctx: TCtx, metadata: TMeta): Promise<string>;
545
+ readFileBuffer(id: string, ctx: TCtx, metadata: TMeta): Promise<Uint8Array>;
546
+ writeFile(id: string, content: string | Uint8Array, ctx: TCtx, metadata: TMeta): Promise<void>;
547
+ createFile(path: string, content: string | Uint8Array, ctx: TCtx): Promise<FileEntry<TMeta>>;
548
+ deleteFile(id: string, ctx: TCtx, metadata: TMeta): Promise<void>;
549
+ }
550
+ /**
551
+ * Workflow-side operations for the virtual filesystem.
552
+ *
553
+ * Unlike {@link SandboxOps}, this only exposes what is actually needed:
554
+ * resolving the initial file tree from the consumer's data layer.
555
+ */
556
+ interface VirtualFsOps<TCtx = unknown, TMeta = FileEntryMetadata> {
557
+ resolveFileTree(ctx: TCtx): Promise<{
558
+ fileTree: FileEntry<TMeta>[];
559
+ }>;
560
+ }
561
+ /**
562
+ * Maps generic {@link VirtualFsOps} method names to scope-prefixed names.
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * type Ops = PrefixedVirtualFsOps<"codingAgent">;
567
+ * // → { codingAgentResolveFileTree: ... }
568
+ * ```
569
+ */
570
+ type PrefixedVirtualFsOps<TPrefix extends string, TCtx = unknown, TMeta = FileEntryMetadata> = {
571
+ [K in keyof VirtualFsOps<TCtx, TMeta> as `${TPrefix}${Capitalize<K & string>}`]: VirtualFsOps<TCtx, TMeta>[K];
572
+ };
573
+ /**
574
+ * The portion of workflow `AgentState` that the virtual filesystem reads via
575
+ * {@link queryParentWorkflowState}. Populated automatically by the session
576
+ * when `virtualFs` config is provided.
577
+ */
578
+ interface VirtualFsState<TCtx = unknown, TMeta = FileEntryMetadata> {
579
+ fileTree: FileEntry<TMeta>[];
580
+ ctx: TCtx;
581
+ workspaceBase?: string;
582
+ }
583
+ /**
584
+ * Extended router context injected by {@link withVirtualFs}.
585
+ * Guarantees a live (ephemeral) virtual filesystem built from the workflow
586
+ * file tree.
587
+ */
588
+ interface VirtualFsContext<TCtx = unknown, TMeta = FileEntryMetadata> extends RouterContext {
589
+ virtualFs: VirtualFileSystem<TCtx, TMeta>;
590
+ }
591
+
592
+ /**
593
+ * Agent execution status
594
+ */
595
+ type AgentStatus = "RUNNING" | "WAITING_FOR_INPUT" | "COMPLETED" | "FAILED" | "CANCELLED";
596
+ /**
597
+ * Base state that all agents must have
598
+ */
599
+ interface BaseAgentState {
600
+ tools: SerializableToolDefinition[];
601
+ status: AgentStatus;
602
+ version: number;
603
+ turns: number;
604
+ tasks: Map<string, WorkflowTask>;
605
+ fileTree: FileEntry[];
606
+ systemPrompt?: string;
607
+ totalInputTokens: number;
608
+ totalOutputTokens: number;
609
+ cachedWriteTokens: number;
610
+ cachedReadTokens: number;
611
+ }
612
+ /**
613
+ * File representation for agent workflows
614
+ */
615
+ interface AgentFile {
616
+ /** Database/S3 file ID */
617
+ id: string;
618
+ /** Virtual path for agent (e.g., "evidence/invoice.pdf") */
619
+ path: string;
620
+ /** Original filename */
621
+ filename: string;
622
+ /** Generic description for prompt */
623
+ description?: string;
624
+ /** MIME type of the file */
625
+ mimeType?: string;
626
+ }
627
+ interface TokenUsage {
628
+ inputTokens?: number;
629
+ outputTokens?: number;
630
+ cachedWriteTokens?: number;
631
+ cachedReadTokens?: number;
632
+ reasonTokens?: number;
633
+ }
634
+ /**
635
+ * Configuration for a Zeitlich agent
636
+ */
637
+ interface AgentConfig {
638
+ /** The name of the agent, should be unique within the workflows, ideally Pascal Case */
639
+ agentName: string;
640
+ /** Description, used for sub agents */
641
+ description?: string;
642
+ }
643
+ /**
644
+ * A JSON-serializable tool definition for state storage.
645
+ * Uses a plain JSON Schema object instead of a live Zod instance,
646
+ * so it survives Temporal serialization without losing constraints (min, max, etc.).
647
+ */
648
+ interface SerializableToolDefinition {
649
+ name: string;
650
+ description: string;
651
+ schema: Record<string, unknown>;
652
+ strict?: boolean;
653
+ max_uses?: number;
654
+ }
655
+ /**
656
+ * Configuration passed to runAgent activity
657
+ */
658
+ interface RunAgentConfig extends AgentConfig {
659
+ /** The thread ID to use for the session */
660
+ threadId: string;
661
+ /** Redis key suffix for thread storage. Defaults to 'messages'. */
662
+ threadKey?: string;
663
+ /** Metadata for the session */
664
+ metadata?: Record<string, unknown>;
665
+ }
666
+ /**
667
+ * Configuration for appending a tool result
668
+ */
669
+ interface ToolResultConfig {
670
+ threadId: string;
671
+ /** Redis key suffix for thread storage. Defaults to 'messages'. */
672
+ threadKey?: string;
673
+ toolCallId: string;
674
+ /** The name of the tool that produced this result */
675
+ toolName: string;
676
+ /** Content for the tool result — string, object, or array. The adapter converts to its SDK-native format. */
677
+ content: JsonValue;
678
+ }
679
+ /**
680
+ * Status of a workflow task
681
+ */
682
+ type TaskStatus = "pending" | "in_progress" | "completed";
683
+ /**
684
+ * A task managed within a workflow for tracking work items
685
+ */
686
+ interface WorkflowTask {
687
+ /** Unique task identifier */
688
+ id: string;
689
+ /** Brief, actionable title in imperative form */
690
+ subject: string;
691
+ /** Detailed description of what needs to be done */
692
+ description: string;
693
+ /** Present continuous form shown in spinner when in_progress */
694
+ activeForm: string;
695
+ /** Current status of the task */
696
+ status: TaskStatus;
697
+ /** Arbitrary key-value pairs for tracking */
698
+ metadata: Record<string, string>;
699
+ /** IDs of tasks that must complete before this one can start */
700
+ blockedBy: string[];
701
+ /** IDs of tasks that are waiting for this one to complete */
702
+ blocks: string[];
703
+ }
704
+ /**
705
+ * Exit reasons for session termination
706
+ */
707
+ type SessionExitReason = "completed" | "max_turns" | "waiting_for_input" | "failed" | "cancelled";
708
+ /**
709
+ * Helper to check if status is terminal
710
+ */
711
+ declare function isTerminalStatus(status: AgentStatus): boolean;
712
+
713
+ /**
714
+ * Context for SessionStart hook - called when session begins
715
+ */
716
+ interface SessionStartHookContext {
717
+ threadId: string;
718
+ agentName: string;
719
+ metadata: Record<string, unknown>;
720
+ }
721
+ /**
722
+ * SessionStart hook - called when session begins
723
+ */
724
+ type SessionStartHook = (ctx: SessionStartHookContext) => void | Promise<void>;
725
+ /**
726
+ * Context for SessionEnd hook - called when session ends
727
+ */
728
+ interface SessionEndHookContext {
729
+ threadId: string;
730
+ agentName: string;
731
+ exitReason: SessionExitReason;
732
+ turns: number;
733
+ metadata: Record<string, unknown>;
734
+ }
735
+ /**
736
+ * SessionEnd hook - called when session ends
737
+ */
738
+ type SessionEndHook = (ctx: SessionEndHookContext) => void | Promise<void>;
739
+ /**
740
+ * Context for PreHumanMessageAppend hook - called before each human message is appended to the thread
741
+ */
742
+ interface PreHumanMessageAppendHookContext<TContent = unknown> {
743
+ message: TContent;
744
+ threadId: string;
745
+ }
746
+ /**
747
+ * PreHumanMessageAppend hook - called before each human message is appended to the thread
748
+ */
749
+ type PreHumanMessageAppendHook<TContent = unknown> = (ctx: PreHumanMessageAppendHookContext<TContent>) => void | Promise<void>;
750
+ /**
751
+ * Context for PostHumanMessageAppend hook - called after each human message is appended to the thread
752
+ */
753
+ interface PostHumanMessageAppendHookContext<TContent = unknown> {
754
+ message: TContent;
755
+ threadId: string;
756
+ }
757
+ /**
758
+ * PostHumanMessageAppend hook - called after each human message is appended to the thread
759
+ */
760
+ type PostHumanMessageAppendHook<TContent = unknown> = (ctx: PostHumanMessageAppendHookContext<TContent>) => void | Promise<void>;
761
+ /**
762
+ * Full hooks interface for a session — combines tool execution hooks
763
+ * (consumed by the router) with session/message lifecycle hooks
764
+ * (consumed directly by the session).
765
+ */
766
+ interface Hooks<T extends ToolMap, TResult = unknown, TContent = unknown> extends ToolRouterHooks<T, TResult> {
767
+ /** Called before each human message is appended to the thread */
768
+ onPreHumanMessageAppend?: PreHumanMessageAppendHook<TContent>;
769
+ /** Called after each human message is appended to the thread */
770
+ onPostHumanMessageAppend?: PostHumanMessageAppendHook<TContent>;
771
+ /** Called when session starts */
772
+ onSessionStart?: SessionStartHook;
773
+ /** Called when session ends */
774
+ onSessionEnd?: SessionEndHook;
775
+ }
776
+
777
+ /**
778
+ * Thread initialization strategy.
779
+ *
780
+ * - `"new"` — start a fresh thread (optionally specify its ID).
781
+ * - `"continue"` — append directly to an existing thread in-place.
782
+ * - `"fork"` — copy all messages from an existing thread into a new one and
783
+ * continue there.
784
+ */
785
+ type ThreadInit = {
786
+ mode: "new";
787
+ threadId?: string;
788
+ } | {
789
+ mode: "continue";
790
+ threadId: string;
791
+ } | {
792
+ mode: "fork";
793
+ threadId: string;
794
+ };
795
+ /**
796
+ * Sandbox initialization strategy.
797
+ *
798
+ * - `"new"` — create a fresh sandbox. Optionally pass `ctx` to
799
+ * have the {@link SandboxManager}'s resolver produce creation options
800
+ * (e.g. initial files) from workflow arguments.
801
+ * - `"continue"` — resume a previously-paused sandbox (this session takes
802
+ * ownership and the shutdown policy applies on exit).
803
+ * - `"fork"` — fork from an existing (or paused) sandbox; a new sandbox is
804
+ * created and owned by this session.
805
+ * - `"inherit"` — use a sandbox owned by someone else (e.g. a parent agent).
806
+ * The session will **not** manage its lifecycle on exit.
807
+ */
808
+ type SandboxInit = {
809
+ mode: "new";
810
+ ctx?: unknown;
811
+ } | {
812
+ mode: "continue";
813
+ sandboxId: string;
814
+ } | {
815
+ mode: "fork";
816
+ sandboxId: string;
817
+ } | {
818
+ mode: "inherit";
819
+ sandboxId: string;
820
+ };
821
+ /**
822
+ * What to do with the sandbox when the session exits.
823
+ *
824
+ * - `"destroy"` — tear down the sandbox entirely.
825
+ * - `"pause"` — pause the sandbox so it can be resumed later.
826
+ * - `"keep"` — leave the sandbox running (no-op on exit).
827
+ */
828
+ type SandboxShutdown = "destroy" | "pause" | "keep";
829
+ /**
830
+ * Extended shutdown options available to subagent workflows.
831
+ *
832
+ * Includes all base {@link SandboxShutdown} values plus:
833
+ * - `"pause-until-parent-close"` — pause the sandbox on exit, then wait for
834
+ * the parent workflow to signal when to destroy it.
835
+ */
836
+ type SubagentSandboxShutdown = SandboxShutdown | "pause-until-parent-close";
837
+
838
+ /** ToolHandlerResponse with threadId required (subagents must always surface their thread) */
839
+ type SubagentHandlerResponse<TResult = null, TToolResponse = JsonValue> = ToolHandlerResponse<TResult, TToolResponse> & {
840
+ threadId: string;
841
+ sandboxId?: string;
842
+ };
843
+ /**
844
+ * Raw workflow input fields passed from parent to child workflow.
845
+ * `defineSubagentWorkflow` maps this into `SubagentSessionInput`.
846
+ */
847
+ interface SubagentWorkflowInput {
848
+ /** Thread initialization strategy forwarded from the parent */
849
+ thread?: ThreadInit;
850
+ /** Sandbox initialization strategy forwarded from the parent */
851
+ sandbox?: SandboxInit;
852
+ /** Sandbox shutdown override from the parent (takes precedence over workflow default) */
853
+ sandboxShutdown?: SubagentSandboxShutdown;
854
+ }
855
+ type SubagentWorkflow<TResult extends z.ZodType = z.ZodType> = (prompt: string, workflowInput: SubagentWorkflowInput, context?: Record<string, unknown>) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>;
856
+ /**
857
+ * A subagent workflow with embedded metadata (name, description, resultSchema).
858
+ * Created by `defineSubagentWorkflow` — pass directly to `defineSubagent`.
859
+ */
860
+ type SubagentDefinition<TResult extends z.ZodType = z.ZodType, TContext extends Record<string, unknown> = Record<string, unknown>> = ((prompt: string, workflowInput: SubagentWorkflowInput, context?: TContext) => Promise<SubagentHandlerResponse<z.infer<TResult> | null>>) & {
861
+ readonly agentName: string;
862
+ readonly description: string;
863
+ readonly resultSchema?: TResult;
864
+ };
865
+ /** Context value or factory — resolved at invocation time when a function is provided */
866
+ type SubagentContext = Record<string, unknown> | (() => Record<string, unknown>);
867
+ /**
868
+ * Sandbox configuration for a subagent.
869
+ *
870
+ * String shorthands:
871
+ * - `"none"` — no sandbox (default).
872
+ * - `"inherit"` — reuse the parent's sandbox (shared filesystem/exec).
873
+ * - `"own"` — the child creates and owns its own sandbox (shutdown defaults to `"destroy"`).
874
+ *
875
+ * Object form (only for `source: "own"`):
876
+ * - `{ source: "own", shutdown?: SubagentSandboxShutdown }` — own sandbox with explicit shutdown policy.
877
+ */
878
+ type SubagentSandboxConfig = "none" | "inherit" | "own" | {
879
+ source: "own";
880
+ shutdown?: SubagentSandboxShutdown;
881
+ };
882
+ /**
883
+ * Configuration for a subagent that can be spawned by the parent workflow.
884
+ *
885
+ * @template TResult - Zod schema type for validating the child workflow's result
886
+ */
887
+ interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
888
+ /** Identifier used in Task tool's subagent parameter */
889
+ agentName: string;
890
+ /** Description shown to the parent agent explaining what this subagent does */
891
+ description: string;
892
+ /** Whether this subagent is available (default: true). Disabled subagents are excluded from the Subagent tool. */
893
+ enabled?: boolean | (() => boolean);
894
+ /** Temporal workflow function or type name (used with executeChild) */
895
+ workflow: SubagentWorkflow<TResult>;
896
+ /** Optional task queue - defaults to parent's queue if not specified */
897
+ taskQueue?: string;
898
+ /** Optional Zod schema to validate the child workflow's result. If omitted, result is passed through as-is. */
899
+ resultSchema?: TResult;
900
+ /** Optional context passed to the subagent — a static object or a function evaluated at invocation time */
901
+ context?: SubagentContext;
902
+ /** Per-subagent lifecycle hooks */
903
+ hooks?: SubagentHooks;
904
+ /**
905
+ * Thread mode for this subagent.
906
+ *
907
+ * - `"new"` (default) — always start a fresh thread.
908
+ * - `"fork"` — the parent can pass a `threadId`; messages are copied into
909
+ * a new thread and the subagent continues there.
910
+ * - `"continue"` — the parent can pass a `threadId`; the subagent appends
911
+ * directly to the existing thread in-place.
912
+ */
913
+ thread?: "new" | "fork" | "continue";
914
+ /**
915
+ * Sandbox strategy for this subagent.
916
+ *
917
+ * String shorthands: `"none"` (default) | `"inherit"` | `"own"`.
918
+ * Object form: `{ source: "own", shutdown?: SubagentSandboxShutdown }`.
919
+ *
920
+ * @see {@link SubagentSandboxConfig}
921
+ */
922
+ sandbox?: SubagentSandboxConfig;
923
+ }
924
+ /**
925
+ * Per-subagent lifecycle hooks - defined on a SubagentConfig.
926
+ * Runs in addition to global hooks (global pre → subagent pre → execute → subagent post → global post).
927
+ */
928
+ interface SubagentHooks<TArgs = unknown, TResult = unknown> {
929
+ /** Called before this subagent executes - can skip or modify args */
930
+ onPreExecution?: (ctx: {
931
+ args: TArgs;
932
+ threadId: string;
933
+ turn: number;
934
+ }) => PreToolUseHookResult | Promise<PreToolUseHookResult>;
935
+ /** Called after this subagent executes successfully */
936
+ onPostExecution?: (ctx: {
937
+ args: TArgs;
938
+ result: TResult;
939
+ threadId: string;
940
+ turn: number;
941
+ durationMs: number;
942
+ /** Unvalidated metadata from the child workflow (e.g. infrastructure state) */
943
+ metadata?: Record<string, unknown>;
944
+ }) => void | Promise<void>;
945
+ /** Called when this subagent execution fails */
946
+ onExecutionFailure?: (ctx: {
947
+ args: TArgs;
948
+ error: Error;
949
+ threadId: string;
950
+ turn: number;
951
+ }) => PostToolUseFailureHookResult | Promise<PostToolUseFailureHookResult>;
952
+ }
953
+ /**
954
+ * Extended response from the subagent `fn` — includes optional cleanup callbacks
955
+ * stripped before signaling the parent.
956
+ *
957
+ * When `TSandboxShutdown` is `"pause-until-parent-close"`, both `destroySandbox`
958
+ * and `sandboxId` become required so the parent can coordinate cleanup.
959
+ */
960
+ type SubagentFnResult<TResult = null, TSandboxShutdown extends SubagentSandboxShutdown = SubagentSandboxShutdown> = SubagentHandlerResponse<TResult> & (TSandboxShutdown extends "pause-until-parent-close" ? {
961
+ destroySandbox: () => Promise<void>;
962
+ sandboxId: string;
963
+ } : {
964
+ destroySandbox?: () => Promise<void>;
965
+ });
966
+ /**
967
+ * Session config fields passed from parent to child workflow.
968
+ */
969
+ interface SubagentSessionInput {
970
+ /** Agent name — spread directly into `createSession` */
971
+ agentName: string;
972
+ /** Thread initialization strategy */
973
+ thread?: ThreadInit;
974
+ /** Sandbox initialization strategy */
975
+ sandbox?: SandboxInit;
976
+ /** Sandbox shutdown policy (default: "destroy") */
977
+ sandboxShutdown?: SubagentSandboxShutdown;
978
+ }
979
+
980
+ /**
981
+ * Skill metadata — the lightweight subset loaded at startup for all skills.
982
+ * Follows the agentskills.io specification frontmatter fields.
983
+ */
984
+ interface SkillMetadata {
985
+ /** Lowercase alphanumeric + hyphens, max 64 chars, must match directory name */
986
+ name: string;
987
+ /** What the skill does and when to use it (max 1024 chars) */
988
+ description: string;
989
+ /** License name or reference to a bundled license file */
990
+ license?: string;
991
+ /** Environment requirements (intended product, system packages, network access) */
992
+ compatibility?: string;
993
+ /** Arbitrary key-value pairs for additional metadata */
994
+ metadata?: Record<string, string>;
995
+ /** Space-delimited list of pre-approved tools the skill may use */
996
+ allowedTools?: string[];
997
+ /** Absolute path to the skill directory (parent of SKILL.md) */
998
+ location?: string;
999
+ }
1000
+ /**
1001
+ * A fully-loaded skill including the SKILL.md instruction body.
1002
+ * Progressive disclosure: metadata is always available, instructions
1003
+ * are loaded on-demand via the ReadSkill tool.
1004
+ */
1005
+ interface Skill extends SkillMetadata {
1006
+ /** The markdown body of SKILL.md (everything after the frontmatter) */
1007
+ instructions: string;
1008
+ /** Resource file contents keyed by relative path (e.g. `references/overview.md` → content) */
1009
+ resourceContents?: Record<string, string>;
1010
+ }
1011
+ /**
1012
+ * Abstraction for discovering and loading skills.
1013
+ *
1014
+ * Implement this interface to provide skills from any source
1015
+ * (filesystem, database, API, in-memory, etc.).
1016
+ */
1017
+ interface SkillProvider {
1018
+ /** Return lightweight metadata for all available skills */
1019
+ listSkills(): Promise<SkillMetadata[]>;
1020
+ /** Load a single skill with full instructions by name */
1021
+ getSkill(name: string): Promise<Skill>;
1022
+ /** Load all skills with full instructions */
1023
+ loadAll(): Promise<Skill[]>;
1024
+ }
1025
+
1026
+ /**
1027
+ * Agent response from LLM invocation
1028
+ */
1029
+ interface AgentResponse<M = unknown> {
1030
+ message: M;
1031
+ rawToolCalls: RawToolCall[];
1032
+ usage?: TokenUsage;
1033
+ }
1034
+ /**
1035
+ * Type signature for workflow-specific runAgent activity
1036
+ */
1037
+ type RunAgentActivity<M = unknown> = (config: RunAgentConfig) => Promise<AgentResponse<M>>;
1038
+ /**
1039
+ * Configuration passed to a ModelInvoker.
1040
+ * Includes the full agent state so adapters can read tools, system prompt,
1041
+ * token usage, or any custom state fields for model configuration.
1042
+ */
1043
+ interface ModelInvokerConfig {
1044
+ threadId: string;
1045
+ /** Redis key suffix for thread storage. Defaults to 'messages'. */
1046
+ threadKey?: string;
1047
+ agentName: string;
1048
+ state: BaseAgentState;
1049
+ metadata?: Record<string, unknown>;
1050
+ }
1051
+ /**
1052
+ * Generic model invocation contract.
1053
+ * Implementations load the thread, call the LLM, append the response,
1054
+ * and return a normalised AgentResponse.
1055
+ *
1056
+ * Framework adapters (e.g. `zeitlich/langchain`) provide concrete
1057
+ * implementations of this type.
1058
+ */
1059
+ type ModelInvoker<M = unknown> = (config: ModelInvokerConfig) => Promise<AgentResponse<M>>;
1060
+
1061
+ /**
1062
+ * Thread operations required by a session.
1063
+ * Consumers provide these — typically by wrapping Temporal activities.
1064
+ *
1065
+ * `TContent` is the SDK-native content type for human messages.
1066
+ * Each adapter supplies its own type (e.g. Anthropic ContentBlockParam[],
1067
+ * Google GenAI Part[], LangChain MessageContent). Defaults to `string`.
1068
+ */
1069
+ interface ThreadOps<TContent = string> {
1070
+ /** Initialize an empty thread */
1071
+ initializeThread(threadId: string, threadKey?: string): Promise<void>;
1072
+ /** Append a human message to the thread */
1073
+ appendHumanMessage(threadId: string, id: string, content: TContent, threadKey?: string): Promise<void>;
1074
+ /** Append a tool result to the thread */
1075
+ appendToolResult(id: string, config: ToolResultConfig): Promise<void>;
1076
+ /** Append a system message to the thread */
1077
+ appendSystemMessage(threadId: string, id: string, content: string, threadKey?: string): Promise<void>;
1078
+ /** Copy all messages from sourceThreadId into a new thread at targetThreadId */
1079
+ forkThread(sourceThreadId: string, targetThreadId: string, threadKey?: string): Promise<void>;
1080
+ }
1081
+ /**
1082
+ * Composes an adapter prefix + workflow scope for activity naming.
1083
+ *
1084
+ * The adapter prefix stays first (camelCase); the workflow scope is
1085
+ * capitalised and appended. When `TScope` is empty the adapter prefix
1086
+ * is used as-is.
1087
+ *
1088
+ * @example
1089
+ * ```typescript
1090
+ * ScopedPrefix<"codingAgent", "googleGenAI"> // "googleGenAICodingAgent"
1091
+ * ScopedPrefix<"", "googleGenAI"> // "googleGenAI"
1092
+ * ```
1093
+ */
1094
+ type ScopedPrefix<TScope extends string, TAdapter extends string> = TScope extends "" ? TAdapter : `${TAdapter}${Capitalize<TScope>}`;
1095
+ /**
1096
+ * Maps generic {@link ThreadOps} method names to adapter-prefixed names.
1097
+ *
1098
+ * @example
1099
+ * ```typescript
1100
+ * type GoogleOps = PrefixedThreadOps<"googleGenAI">;
1101
+ * // → { googleGenAIInitializeThread, googleGenAIAppendHumanMessage, … }
1102
+ * ```
1103
+ */
1104
+ type PrefixedThreadOps<TPrefix extends string, TContent = string> = {
1105
+ [K in keyof ThreadOps<TContent> as `${TPrefix}${Capitalize<K & string>}`]: ThreadOps<TContent>[K];
1106
+ };
1107
+ /**
1108
+ * Configuration for a Zeitlich agent session.
1109
+ *
1110
+ * @typeParam T - Tool map
1111
+ * @typeParam M - SDK-native message type returned by the model invoker
1112
+ * @typeParam TContent - SDK-native content type for human messages (defaults to `string`)
1113
+ */
1114
+ interface SessionConfig<T extends ToolMap, M = unknown, TContent = string> {
1115
+ /** The name of the agent, should be unique within the workflows */
1116
+ agentName: string;
1117
+ /** Metadata for the session */
1118
+ metadata?: Record<string, unknown>;
1119
+ /** Whether to append the system prompt as message to the thread */
1120
+ appendSystemPrompt?: boolean;
1121
+ /** How many turns to run the session for */
1122
+ maxTurns?: number;
1123
+ /** Workflow-specific runAgent activity (with tools pre-bound) */
1124
+ runAgent: RunAgentActivity<M>;
1125
+ /** Thread operations (initialize, append messages, parse tool calls) */
1126
+ threadOps: ActivityInterfaceFor<ThreadOps<TContent>>;
1127
+ /** Tool router for processing tool calls (optional if agent has no tools) */
1128
+ tools?: T;
1129
+ /** Subagent configurations */
1130
+ subagents?: SubagentConfig[];
1131
+ /** Skills available to this agent (metadata + instructions, loaded before session creation) */
1132
+ skills?: Skill[];
1133
+ /** Session lifecycle hooks */
1134
+ hooks?: Hooks<T, ToolCallResultUnion<InferToolResults<T>>, TContent>;
1135
+ /** Whether to process tools in parallel */
1136
+ processToolsInParallel?: boolean;
1137
+ /**
1138
+ * Build context message content from agent-specific context.
1139
+ * Returns SDK-native content for the initial human message.
1140
+ */
1141
+ buildContextMessage: () => TContent | Promise<TContent>;
1142
+ /** How long to wait for input before cancelling the workflow */
1143
+ waitForInputTimeout?: Duration;
1144
+ /**
1145
+ * Thread initialization strategy (default: `{ mode: "new" }`).
1146
+ *
1147
+ * - `{ mode: "new" }` — start a fresh thread.
1148
+ * - `{ mode: "new", threadId: "..." }` — start a fresh thread with a specific ID.
1149
+ * - `{ mode: "continue", threadId: "..." }` — append to an existing thread in-place.
1150
+ * - `{ mode: "fork", threadId: "..." }` — fork an existing thread and continue in the copy.
1151
+ */
1152
+ thread?: ThreadInit;
1153
+ /**
1154
+ * Redis key suffix for thread storage. Defaults to `"messages"`.
1155
+ *
1156
+ * Controls the Redis key layout: `thread:${threadId}:${threadKey}`.
1157
+ * Use different keys to isolate storage across sessions sharing the
1158
+ * same adapter instance.
1159
+ */
1160
+ threadKey?: string;
1161
+ /** Sandbox lifecycle operations (optional — omit for agents that don't need a sandbox) */
1162
+ sandboxOps?: SandboxOps;
1163
+ /**
1164
+ * Sandbox initialization strategy.
1165
+ *
1166
+ * - `{ mode: "new" }` — create a fresh sandbox.
1167
+ * - `{ mode: "continue", sandboxId: "..." }` — resume a paused sandbox (session owns it).
1168
+ * - `{ mode: "fork", sandboxId: "..." }` — fork from an existing sandbox.
1169
+ * - `{ mode: "inherit", sandboxId: "..." }` — use a parent's sandbox without ownership.
1170
+ *
1171
+ * When omitted and `sandboxOps` is provided, defaults to `{ mode: "new" }`.
1172
+ */
1173
+ sandbox?: SandboxInit;
1174
+ /**
1175
+ * What to do with the sandbox when this session exits.
1176
+ *
1177
+ * Defaults to `"destroy"` when omitted.
1178
+ * Has no effect when the sandbox is inherited (`sandbox.mode === "inherit"`).
1179
+ */
1180
+ sandboxShutdown?: SubagentSandboxShutdown;
1181
+ virtualFsOps?: VirtualFsOps;
1182
+ /**
1183
+ * Virtual filesystem configuration (optional — independent of sandbox).
1184
+ *
1185
+ * When provided, the session resolves the file tree on start and merges
1186
+ * `fileTree`, `ctx`, and `workspaceBase` into `AgentState`.
1187
+ * Tool handlers wrapped with `withVirtualFs` can then read this state.
1188
+ *
1189
+ * Can be used alongside `sandboxOps` for agents that need both a real
1190
+ * sandbox (e.g. for execution) and a virtual filesystem.
1191
+ */
1192
+ virtualFs?: {
1193
+ ctx: unknown;
1194
+ };
1195
+ }
1196
+ type SessionResult<M, TState extends JsonSerializable<TState>, HasSandbox extends boolean = boolean> = {
1197
+ threadId: string;
1198
+ finalMessage: M | null;
1199
+ exitReason: SessionExitReason;
1200
+ usage: ReturnType<AgentStateManager<TState>["getTotalUsage"]>;
1201
+ } & (HasSandbox extends true ? {
1202
+ sandboxId: string;
1203
+ } : {
1204
+ sandboxId?: undefined;
1205
+ });
1206
+ interface ZeitlichSession<M = unknown, HasSandbox extends boolean = boolean> {
1207
+ runSession<T extends JsonSerializable<T>>(args: {
1208
+ stateManager: AgentStateManager<T>;
1209
+ }): Promise<SessionResult<M, T, HasSandbox>>;
1210
+ }
1211
+
1212
+ export { type SessionEndHook 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 RawToolCall as U, type VirtualFsContext as V, type RunAgentActivity as W, type SandboxInit as X, type SandboxShutdown as Y, type SerializableToolDefinition as Z, type SessionConfig as _, type ModelInvoker as a, type SessionEndHookContext as a0, type SessionExitReason as a1, type SessionResult as a2, type SessionStartHook as a3, type SessionStartHookContext as a4, type SubagentConfig as a5, type SubagentDefinition as a6, type SubagentFnResult as a7, type SubagentHandlerResponse as a8, type SubagentHooks as a9, isTerminalStatus as aA, type ToolRouterOptions as aB, type SubagentSandboxConfig as aa, type SubagentSandboxShutdown as ab, type SubagentSessionInput as ac, type SubagentWorkflow as ad, type SubagentWorkflowInput as ae, type TaskStatus as af, type ThreadInit as ag, type TokenUsage as ah, type ToolArgs as ai, type ToolCallResult as aj, type ToolCallResultUnion as ak, type ToolDefinition as al, type ToolHandler as am, type ToolHooks as an, type ToolMap as ao, type ToolNames as ap, type ToolResult as aq, type ToolRouter as ar, type ToolRouterHooks as as, type ToolWithHandler as at, VirtualFileSystem as au, type VirtualFileTree as av, type VirtualFsOps as aw, type VirtualFsState as ax, type WorkflowTask as ay, type ZeitlichSession 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 };