zeitlich 0.2.11 → 0.2.13

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 (46) hide show
  1. package/README.md +313 -126
  2. package/dist/adapters/langchain/index.cjs +270 -0
  3. package/dist/adapters/langchain/index.cjs.map +1 -0
  4. package/dist/adapters/langchain/index.d.cts +132 -0
  5. package/dist/adapters/langchain/index.d.ts +132 -0
  6. package/dist/adapters/langchain/index.js +265 -0
  7. package/dist/adapters/langchain/index.js.map +1 -0
  8. package/dist/index.cjs +89 -209
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +62 -46
  11. package/dist/index.d.ts +62 -46
  12. package/dist/index.js +88 -208
  13. package/dist/index.js.map +1 -1
  14. package/dist/{workflow-BhjsEQc1.d.cts → model-invoker-y_zlyMqu.d.cts} +45 -482
  15. package/dist/{workflow-BhjsEQc1.d.ts → model-invoker-y_zlyMqu.d.ts} +45 -482
  16. package/dist/thread-manager-qc0g5Rvd.d.cts +39 -0
  17. package/dist/thread-manager-qc0g5Rvd.d.ts +39 -0
  18. package/dist/workflow.cjs +59 -27
  19. package/dist/workflow.cjs.map +1 -1
  20. package/dist/workflow.d.cts +459 -6
  21. package/dist/workflow.d.ts +459 -6
  22. package/dist/workflow.js +60 -29
  23. package/dist/workflow.js.map +1 -1
  24. package/package.json +17 -2
  25. package/src/adapters/langchain/activities.ts +120 -0
  26. package/src/adapters/langchain/index.ts +38 -0
  27. package/src/adapters/langchain/model-invoker.ts +102 -0
  28. package/src/adapters/langchain/thread-manager.ts +142 -0
  29. package/src/index.ts +24 -23
  30. package/src/lib/fs.ts +25 -0
  31. package/src/lib/model-invoker.ts +15 -75
  32. package/src/lib/session.ts +52 -21
  33. package/src/lib/state-manager.ts +23 -5
  34. package/src/lib/thread-id.ts +25 -0
  35. package/src/lib/thread-manager.ts +18 -142
  36. package/src/lib/tool-router.ts +12 -18
  37. package/src/lib/types.ts +26 -10
  38. package/src/lib/workflow-helpers.ts +50 -0
  39. package/src/tools/ask-user-question/handler.ts +25 -1
  40. package/src/tools/bash/handler.ts +13 -0
  41. package/src/tools/subagent/handler.ts +16 -5
  42. package/src/tools/subagent/tool.ts +34 -15
  43. package/src/workflow.ts +26 -7
  44. package/tsup.config.ts +1 -0
  45. package/src/activities.ts +0 -91
  46. package/src/plugin.ts +0 -28
@@ -1,7 +1,460 @@
1
- export { a as ActivityToolHandler, d as AgentConfig, e as AgentFile, A as AgentResponse, f as AgentState, g as AgentStateManager, h as AgentStatus, i as AppendToolResultFn, j as AskUserQuestionArgs, k as BaseAgentState, B as BashArgs, F as FileEditArgs, m as FileReadArgs, n as FileWriteArgs, G as GlobArgs, o as GrepArgs, I as InferToolResults, J as JsonPrimitive, p as JsonSerializable, q as JsonValue, P as ParsedToolCall, r as ParsedToolCallUnion, s as PostToolUseFailureHook, t as PostToolUseFailureHookContext, u as PostToolUseFailureHookResult, v as PostToolUseHook, w as PostToolUseHookContext, x as PreToolUseHook, y as PreToolUseHookContext, z as PreToolUseHookResult, C as ProcessToolCallsContext, R as RawToolCall, D as ReadSkillArgs, E as RunAgentActivity, H as RunAgentConfig, K as SessionEndHook, L as SessionEndHookContext, M as SessionExitReason, N as SessionLifecycleHooks, O as SessionStartHook, Q as SessionStartHookContext, c as Skill, b as SkillMetadata, S as SkillProvider, T as SubagentArgs, U as SubagentConfig, V as SubagentHooks, W as SubagentInput, X as SubagentWorkflow, Y as TaskCreateArgs, Z as TaskGetArgs, _ as TaskListArgs, $ as TaskStatus, a0 as TaskUpdateArgs, a3 as ThreadOps, a4 as ToolArgs, a5 as ToolCallResult, a6 as ToolCallResultUnion, a7 as ToolDefinition, a8 as ToolHandler, a9 as ToolHandlerContext, aa as ToolHandlerResponse, ab as ToolHooks, ac as ToolMap, ad as ToolMessageContent, ae as ToolNames, af as ToolResult, ag as ToolResultConfig, ah as ToolRouter, ai as ToolWithHandler, aj as WorkflowTask, ak as ZeitlichSession, al as ZeitlichSharedActivities, am as agentQueryName, an as agentStateChangeUpdateName, ao as askUserQuestionTool, ap as bashTool, aq as createAgentStateManager, ar as createAskUserQuestionHandler, as as createBashToolDescription, at as createReadSkillHandler, au as createReadSkillTool, av as createSession, ax as createSubagentTool, ay as createTaskCreateHandler, az as createTaskGetHandler, aA as createTaskListHandler, aB as createTaskUpdateHandler, aD as createToolRouter, aE as defineSubagent, aF as defineTool, aG as editTool, aH as globTool, aI as grepTool, aJ as hasNoOtherToolCalls, aK as isTerminalStatus, aL as parseSkillFile, aM as proxyDefaultThreadOps, aN as readFileTool, aO as taskCreateTool, aP as taskGetTool, aQ as taskListTool, aR as taskUpdateTool, aT as writeFileTool } from './workflow-BhjsEQc1.js';
2
- import '@temporalio/workflow';
3
- import 'ioredis';
4
- import '@langchain/core/messages';
5
- import 'zod';
1
+ import { QueryDefinition, proxyActivities } from '@temporalio/workflow';
2
+ import { B as BaseAgentState, g as AgentStatus, a9 as WorkflowTask, Z as ToolDefinition, G as SessionStartHook, D as SessionEndHook, F as SessionExitReason, a2 as ToolMap, z as SessionConfig, e as AgentConfig, T as ThreadOps, c as SkillMetadata, d as Skill, a0 as ToolHandlerResponse, _ as ToolHandler, b as ActivityToolHandler } from './model-invoker-y_zlyMqu.js';
3
+ export { f as AgentFile, A as AgentResponse, h as AppendToolResultFn, C as ContentPart, H as Hooks, I as InferToolResults, i as MessageContent, M as ModelInvoker, a as ModelInvokerConfig, P as ParsedToolCall, j as ParsedToolCallUnion, k as PostHumanMessageAppendHook, l as PostHumanMessageAppendHookContext, m as PostToolUseFailureHook, n as PostToolUseFailureHookContext, o as PostToolUseFailureHookResult, p as PostToolUseHook, q as PostToolUseHookContext, r as PreHumanMessageAppendHook, s as PreHumanMessageAppendHookContext, t as PreToolUseHook, u as PreToolUseHookContext, v as PreToolUseHookResult, w as ProcessToolCallsContext, x as RawToolCall, y as RunAgentActivity, R as RunAgentConfig, E as SessionEndHookContext, J as SessionStartHookContext, S as SkillProvider, K as SubagentArgs, L as SubagentConfig, N as SubagentHooks, O as SubagentInput, Q as SubagentWorkflow, U as TaskStatus, V as TokenUsage, W as ToolArgs, X as ToolCallResult, Y as ToolCallResultUnion, $ as ToolHandlerContext, a1 as ToolHooks, a3 as ToolMessageContent, a4 as ToolNames, a5 as ToolResult, a6 as ToolResultConfig, a7 as ToolRouter, a8 as ToolWithHandler, aa as agentQueryName, ab as agentStateChangeUpdateName, ac as createSubagentTool, ad as createToolRouter, ae as defineSubagent, af as defineTool, ag as hasNoOtherToolCalls, ah as isTerminalStatus } from './model-invoker-y_zlyMqu.js';
4
+ import { UpdateDefinition } from '@temporalio/common/lib/interfaces';
5
+ import z, { z as z$1 } from 'zod';
6
6
  import '@temporalio/common';
7
- import '@temporalio/common/lib/interfaces';
7
+
8
+ /**
9
+ * JSON primitive types that Temporal can serialize
10
+ */
11
+ type JsonPrimitive = string | number | boolean | null | undefined;
12
+ /**
13
+ * JSON-serializable value (recursive type for Temporal compatibility)
14
+ */
15
+ type JsonValue = JsonPrimitive | JsonValue[] | {
16
+ [key: string]: JsonValue;
17
+ };
18
+ /**
19
+ * Type constraint ensuring T only contains JSON-serializable values.
20
+ * Use this for custom state to ensure Temporal workflow compatibility.
21
+ *
22
+ * Allows: primitives, arrays, plain objects, and JsonValue
23
+ * Rejects: functions, symbols, undefined, class instances with methods
24
+ */
25
+ type JsonSerializable<T> = {
26
+ [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;
27
+ };
28
+ /**
29
+ * Full state type combining base state with custom state
30
+ */
31
+ type AgentState<TCustom extends JsonSerializable<TCustom>> = BaseAgentState & TCustom;
32
+ /**
33
+ * Agent state manager interface
34
+ * Note: Temporal handlers must be set up in the workflow file due to
35
+ * Temporal's workflow isolation requirements. This manager provides
36
+ * the state and helpers needed for those handlers.
37
+ */
38
+ interface AgentStateManager<TCustom extends JsonSerializable<TCustom>> {
39
+ /** Typed query definition registered for this agent's state */
40
+ readonly stateQuery: QueryDefinition<AgentState<TCustom>>;
41
+ /** Typed update definition registered for waiting on this agent's state change */
42
+ readonly stateChangeUpdate: UpdateDefinition<AgentState<TCustom>, [number]>;
43
+ /** Get current status */
44
+ getStatus(): AgentStatus;
45
+ /** Check if agent is running */
46
+ isRunning(): boolean;
47
+ /** Check if agent is in terminal state */
48
+ isTerminal(): boolean;
49
+ /** Get current state version */
50
+ getVersion(): number;
51
+ /** Set status to RUNNING */
52
+ run(): void;
53
+ /** Set status to WAITING_FOR_INPUT */
54
+ waitForInput(): void;
55
+ /** Set status to COMPLETED */
56
+ complete(): void;
57
+ /** Set status to FAILED */
58
+ fail(): void;
59
+ /** Set status to CANCELLED */
60
+ cancel(): void;
61
+ /** Increment state version (call after state changes) */
62
+ incrementVersion(): void;
63
+ /** Increment turns (call after each turn) */
64
+ incrementTurns(): void;
65
+ /** Get current turns */
66
+ getTurns(): number;
67
+ /** Get the system prompt */
68
+ getSystemPrompt(): string | undefined;
69
+ /** Set the system prompt */
70
+ setSystemPrompt(newSystemPrompt: string): void;
71
+ /** Get a custom state value by key */
72
+ get<K extends keyof TCustom>(key: K): TCustom[K];
73
+ /** Set a custom state value by key */
74
+ set<K extends keyof TCustom>(key: K, value: TCustom[K]): void;
75
+ /** Get full state for query handler */
76
+ getCurrentState(): AgentState<TCustom>;
77
+ /** Check if should return from waitForStateChange */
78
+ shouldReturnFromWait(lastKnownVersion: number): boolean;
79
+ /** Get all tasks */
80
+ getTasks(): WorkflowTask[];
81
+ /** Get a task by ID */
82
+ getTask(id: string): WorkflowTask | undefined;
83
+ /** Add or update a task */
84
+ setTask(task: WorkflowTask): void;
85
+ /** Delete a task by ID */
86
+ deleteTask(id: string): boolean;
87
+ /** Set the tools (converts Zod schemas to JSON Schema for serialization) */
88
+ setTools(newTools: ToolDefinition[]): void;
89
+ /** Update the usage */
90
+ updateUsage(usage: {
91
+ inputTokens?: number;
92
+ outputTokens?: number;
93
+ cachedWriteTokens?: number;
94
+ cachedReadTokens?: number;
95
+ reasonTokens?: number;
96
+ }): void;
97
+ /** Get the total usage */
98
+ getTotalUsage(): {
99
+ totalInputTokens: number;
100
+ totalOutputTokens: number;
101
+ totalCachedWriteTokens: number;
102
+ totalCachedReadTokens: number;
103
+ totalReasonTokens: number;
104
+ turns: number;
105
+ };
106
+ }
107
+ /**
108
+ * Creates an agent state manager for tracking workflow state.
109
+ * Automatically registers Temporal query and update handlers for the agent.
110
+ *
111
+ * @param options.agentName - Unique agent name, used to derive query/update handler names
112
+ * @param options.initialState - Optional initial values for base and custom state.
113
+ * Use `systemPrompt` here to set the agent's system prompt.
114
+ * Base state defaults: status="RUNNING", version=0, turns=0, tasks=empty
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const stateManager = createAgentStateManager({
119
+ * initialState: {
120
+ * systemPrompt: "You are a helpful assistant.",
121
+ * },
122
+ * agentName: "my-agent",
123
+ * });
124
+ *
125
+ * // With custom state fields
126
+ * const stateManager = createAgentStateManager({
127
+ * initialState: {
128
+ * systemPrompt: agentConfig.systemPrompt,
129
+ * customField: "value",
130
+ * },
131
+ * agentName: agentConfig.agentName,
132
+ * });
133
+ * ```
134
+ */
135
+ declare function createAgentStateManager<TCustom extends JsonSerializable<TCustom> = Record<string, never>>({ initialState, agentName, }: {
136
+ initialState?: Partial<BaseAgentState> & TCustom;
137
+ agentName: string;
138
+ }): AgentStateManager<TCustom>;
139
+
140
+ interface ZeitlichSession<M = unknown> {
141
+ runSession<T extends JsonSerializable<T>>(args: {
142
+ stateManager: AgentStateManager<T>;
143
+ }): Promise<{
144
+ finalMessage: M | null;
145
+ exitReason: SessionExitReason;
146
+ usage: ReturnType<AgentStateManager<T>["getTotalUsage"]>;
147
+ }>;
148
+ }
149
+ /**
150
+ * Session-level hooks for lifecycle events
151
+ */
152
+ interface SessionLifecycleHooks {
153
+ /** Called when session starts */
154
+ onSessionStart?: SessionStartHook;
155
+ /** Called when session ends */
156
+ onSessionEnd?: SessionEndHook;
157
+ }
158
+ /**
159
+ * Creates an agent session that manages the agent loop: LLM invocation,
160
+ * tool routing, subagent coordination, and lifecycle hooks.
161
+ *
162
+ * @param config - Session and agent configuration (merged `SessionConfig` and `AgentConfig`)
163
+ * @returns A session object with `runSession()` to start the agent loop
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * import { createSession, createAgentStateManager, defineTool, bashTool } from 'zeitlich/workflow';
168
+ *
169
+ * const stateManager = createAgentStateManager({
170
+ * initialState: { systemPrompt: "You are a helpful assistant." },
171
+ * agentName: "my-agent",
172
+ * });
173
+ *
174
+ * const session = await createSession({
175
+ * agentName: "my-agent",
176
+ * maxTurns: 20,
177
+ * threadId: runId,
178
+ * runAgent: runAgentActivity,
179
+ * buildContextMessage: () => [{ type: "text", text: prompt }],
180
+ * subagents: [researcherSubagent],
181
+ * tools: {
182
+ * Bash: defineTool({ ...bashTool, handler: bashHandlerActivity }),
183
+ * },
184
+ * });
185
+ *
186
+ * const { finalMessage, exitReason } = await session.runSession({ stateManager });
187
+ * ```
188
+ */
189
+ declare const createSession: <T extends ToolMap, M = unknown>({ threadId: providedThreadId, agentName, maxTurns, metadata, runAgent, threadOps, buildContextMessage, subagents, skills, tools, processToolsInParallel, hooks, appendSystemPrompt, continueThread, waitForInputTimeout, }: SessionConfig<T, M> & AgentConfig) => Promise<ZeitlichSession<M>>;
190
+ /**
191
+ * Proxy the adapter's thread operations as Temporal activities.
192
+ * Call this in workflow code to delegate thread operations to the
193
+ * adapter-provided activities registered on the worker.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * const session = await createSession({
198
+ * threadOps: proxyDefaultThreadOps(),
199
+ * // ...
200
+ * });
201
+ * ```
202
+ */
203
+ declare function proxyDefaultThreadOps(options?: Parameters<typeof proxyActivities>[0]): ThreadOps;
204
+
205
+ /**
206
+ * Generate a compact, workflow-deterministic identifier.
207
+ *
208
+ * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),
209
+ * then re-encodes the hex bytes into a base-62 alphabet for a shorter,
210
+ * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).
211
+ *
212
+ * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.
213
+ *
214
+ * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)
215
+ */
216
+ declare function getShortId(length?: number): string;
217
+
218
+ /**
219
+ * Parse a SKILL.md file into its frontmatter fields and markdown body.
220
+ *
221
+ * Handles the limited YAML subset used by the agentskills.io spec:
222
+ * flat key-value pairs plus one-level nested `metadata` map.
223
+ * No external YAML dependency required.
224
+ */
225
+ declare function parseSkillFile(raw: string): {
226
+ frontmatter: SkillMetadata;
227
+ body: string;
228
+ };
229
+
230
+ /**
231
+ * Creates a ReadSkill tool configured with the available skills.
232
+ * The tool description embeds skill metadata so the agent discovers
233
+ * skills purely through the tool definition.
234
+ */
235
+ declare function createReadSkillTool(skills: Skill[]): {
236
+ name: string;
237
+ description: string;
238
+ schema: z.ZodObject<{
239
+ skill_name: z.ZodEnum<Record<string, string>>;
240
+ }>;
241
+ };
242
+ type ReadSkillArgs = {
243
+ skill_name: string;
244
+ };
245
+
246
+ /**
247
+ * Creates a ReadSkill handler that looks up skills from an in-memory array.
248
+ * Runs directly in the workflow (like task tools) — no activity needed.
249
+ */
250
+ declare function createReadSkillHandler(skills: Skill[]): (args: ReadSkillArgs) => ToolHandlerResponse<null>;
251
+
252
+ declare const globTool: {
253
+ name: "Glob";
254
+ description: string;
255
+ schema: z$1.ZodObject<{
256
+ pattern: z$1.ZodString;
257
+ root: z$1.ZodOptional<z$1.ZodString>;
258
+ }, z$1.core.$strip>;
259
+ strict: true;
260
+ };
261
+ type GlobArgs = z$1.infer<typeof globTool.schema>;
262
+
263
+ declare const grepTool: {
264
+ name: "Grep";
265
+ description: string;
266
+ schema: z$1.ZodObject<{
267
+ pattern: z$1.ZodString;
268
+ ignoreCase: z$1.ZodOptional<z$1.ZodBoolean>;
269
+ maxMatches: z$1.ZodOptional<z$1.ZodNumber>;
270
+ includePatterns: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
271
+ excludePatterns: z$1.ZodOptional<z$1.ZodArray<z$1.ZodString>>;
272
+ contextLines: z$1.ZodOptional<z$1.ZodNumber>;
273
+ }, z$1.core.$strip>;
274
+ strict: true;
275
+ };
276
+ type GrepArgs = z$1.infer<typeof grepTool.schema>;
277
+
278
+ declare const readFileTool: {
279
+ name: "FileRead";
280
+ description: string;
281
+ schema: z$1.ZodObject<{
282
+ path: z$1.ZodString;
283
+ offset: z$1.ZodOptional<z$1.ZodNumber>;
284
+ limit: z$1.ZodOptional<z$1.ZodNumber>;
285
+ }, z$1.core.$strip>;
286
+ strict: true;
287
+ };
288
+ type FileReadArgs = z$1.infer<typeof readFileTool.schema>;
289
+
290
+ declare const writeFileTool: {
291
+ name: "FileWrite";
292
+ description: string;
293
+ schema: z$1.ZodObject<{
294
+ file_path: z$1.ZodString;
295
+ content: z$1.ZodString;
296
+ }, z$1.core.$strip>;
297
+ strict: true;
298
+ };
299
+ type FileWriteArgs = z$1.infer<typeof writeFileTool.schema>;
300
+
301
+ declare const editTool: {
302
+ name: "FileEdit";
303
+ description: string;
304
+ schema: z$1.ZodObject<{
305
+ file_path: z$1.ZodString;
306
+ old_string: z$1.ZodString;
307
+ new_string: z$1.ZodString;
308
+ replace_all: z$1.ZodOptional<z$1.ZodBoolean>;
309
+ }, z$1.core.$strip>;
310
+ strict: true;
311
+ };
312
+ type FileEditArgs = z$1.infer<typeof editTool.schema>;
313
+
314
+ declare const taskCreateTool: {
315
+ name: "TaskCreate";
316
+ description: string;
317
+ schema: z.ZodObject<{
318
+ subject: z.ZodString;
319
+ description: z.ZodString;
320
+ activeForm: z.ZodString;
321
+ metadata: z.ZodRecord<z.ZodString, z.ZodString>;
322
+ }, z.core.$strip>;
323
+ };
324
+ type TaskCreateArgs = z.infer<typeof taskCreateTool.schema>;
325
+
326
+ /**
327
+ * Creates a TaskCreate handler that adds tasks to the workflow state.
328
+ *
329
+ * @param stateManager - State manager containing tasks state
330
+ * @returns A ToolHandler for TaskCreate tool calls
331
+ */
332
+ declare function createTaskCreateHandler<TCustom extends JsonSerializable<TCustom>>(stateManager: AgentStateManager<TCustom>): ToolHandler<TaskCreateArgs, WorkflowTask>;
333
+
334
+ declare const taskGetTool: {
335
+ name: "TaskGet";
336
+ description: string;
337
+ schema: z.ZodObject<{
338
+ taskId: z.ZodString;
339
+ }, z.core.$strip>;
340
+ };
341
+ type TaskGetArgs = z.infer<typeof taskGetTool.schema>;
342
+
343
+ /**
344
+ * Creates a TaskGet handler that retrieves a task by ID.
345
+ *
346
+ * @param stateManager - State manager containing tasks state
347
+ * @returns A ToolHandler for TaskGet tool calls
348
+ */
349
+ declare function createTaskGetHandler<TCustom extends JsonSerializable<TCustom>>(stateManager: AgentStateManager<TCustom>): ToolHandler<TaskGetArgs, WorkflowTask | null>;
350
+
351
+ declare const taskListTool: {
352
+ name: "TaskList";
353
+ description: string;
354
+ schema: z.ZodObject<{}, z.core.$strip>;
355
+ };
356
+ type TaskListArgs = z.infer<typeof taskListTool.schema>;
357
+
358
+ /**
359
+ * Creates a TaskList handler that returns all tasks.
360
+ *
361
+ * @param stateManager - State manager containing tasks state
362
+ * @returns A ToolHandler for TaskList tool calls
363
+ */
364
+ declare function createTaskListHandler<TCustom extends JsonSerializable<TCustom>>(stateManager: AgentStateManager<TCustom>): ToolHandler<TaskListArgs, WorkflowTask[]>;
365
+
366
+ declare const taskUpdateTool: {
367
+ name: "TaskUpdate";
368
+ description: string;
369
+ schema: z.ZodObject<{
370
+ taskId: z.ZodString;
371
+ status: z.ZodEnum<{
372
+ pending: "pending";
373
+ in_progress: "in_progress";
374
+ completed: "completed";
375
+ }>;
376
+ addBlockedBy: z.ZodArray<z.ZodString>;
377
+ addBlocks: z.ZodArray<z.ZodString>;
378
+ }, z.core.$strip>;
379
+ };
380
+ type TaskUpdateArgs = z.infer<typeof taskUpdateTool.schema>;
381
+
382
+ /**
383
+ * Creates a TaskUpdate handler that modifies task status and dependencies.
384
+ *
385
+ * @param stateManager - State manager containing tasks state
386
+ * @returns A ToolHandler for TaskUpdate tool calls
387
+ */
388
+ declare function createTaskUpdateHandler<TCustom extends JsonSerializable<TCustom>>(stateManager: AgentStateManager<TCustom>): ToolHandler<TaskUpdateArgs, WorkflowTask | null>;
389
+
390
+ declare const createBashToolDescription: ({ fileTree, }: {
391
+ fileTree: string;
392
+ }) => string;
393
+ declare const bashTool: {
394
+ name: "Bash";
395
+ description: string;
396
+ schema: z.ZodObject<{
397
+ command: z.ZodString;
398
+ }, z.core.$strip>;
399
+ strict: true;
400
+ };
401
+ type BashArgs = z.infer<typeof bashTool.schema>;
402
+
403
+ declare const askUserQuestionTool: {
404
+ name: "AskUserQuestion";
405
+ description: string;
406
+ schema: z.ZodObject<{
407
+ questions: z.ZodArray<z.ZodObject<{
408
+ question: z.ZodString;
409
+ header: z.ZodString;
410
+ options: z.ZodArray<z.ZodObject<{
411
+ label: z.ZodString;
412
+ description: z.ZodString;
413
+ }, z.core.$strip>>;
414
+ multiSelect: z.ZodBoolean;
415
+ }, z.core.$strip>>;
416
+ }, z.core.$strip>;
417
+ strict: true;
418
+ };
419
+ type AskUserQuestionArgs = z.infer<typeof askUserQuestionTool.schema>;
420
+
421
+ /**
422
+ * Creates a handler for the AskUserQuestion tool.
423
+ * Returns question data for display to the user via your UI layer.
424
+ *
425
+ * Typically paired with `stateManager.waitForInput()` in a `hooks.onPostToolUse`
426
+ * callback to pause the agent loop until the user responds.
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * import { createAskUserQuestionHandler } from 'zeitlich';
431
+ * import { askUserQuestionTool, defineTool } from 'zeitlich/workflow';
432
+ *
433
+ * // In activities
434
+ * const askUserQuestionHandlerActivity = createAskUserQuestionHandler();
435
+ *
436
+ * // In workflow
437
+ * tools: {
438
+ * AskUserQuestion: defineTool({
439
+ * ...askUserQuestionTool,
440
+ * handler: askUserQuestionHandlerActivity,
441
+ * hooks: {
442
+ * onPostToolUse: () => { stateManager.waitForInput(); },
443
+ * },
444
+ * }),
445
+ * }
446
+ * ```
447
+ */
448
+ declare const createAskUserQuestionHandler: () => ActivityToolHandler<AskUserQuestionArgs, {
449
+ questions: {
450
+ question: string;
451
+ header: string;
452
+ options: {
453
+ label: string;
454
+ description: string;
455
+ }[];
456
+ multiSelect: boolean;
457
+ }[];
458
+ }>;
459
+
460
+ export { ActivityToolHandler, AgentConfig, type AgentState, type AgentStateManager, AgentStatus, type AskUserQuestionArgs, BaseAgentState, type BashArgs, type FileEditArgs, type FileReadArgs, type FileWriteArgs, type GlobArgs, type GrepArgs, type JsonPrimitive, type JsonSerializable, type JsonValue, type ReadSkillArgs, SessionConfig, SessionEndHook, SessionExitReason, type SessionLifecycleHooks, SessionStartHook, Skill, SkillMetadata, type TaskCreateArgs, type TaskGetArgs, type TaskListArgs, type TaskUpdateArgs, ThreadOps, ToolDefinition, ToolHandler, ToolHandlerResponse, ToolMap, WorkflowTask, type ZeitlichSession, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, editTool, getShortId, globTool, grepTool, parseSkillFile, proxyDefaultThreadOps, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
package/dist/workflow.js CHANGED
@@ -1,11 +1,14 @@
1
- import { setHandler, defineUpdate, ApplicationFailure, condition, proxyActivities, defineQuery, uuid4, workflowInfo, executeChild } from '@temporalio/workflow';
1
+ import { uuid4, setHandler, defineUpdate, ApplicationFailure, condition, proxyActivities, defineQuery, workflowInfo, executeChild } from '@temporalio/workflow';
2
2
  import z14, { z } from 'zod';
3
3
 
4
4
  // src/lib/session.ts
5
5
  var SUBAGENT_TOOL_NAME = "Subagent";
6
6
  function buildSubagentDescription(subagents) {
7
- const subagentList = subagents.map((s) => `## ${s.agentName}
8
- ${s.description}`).join("\n\n");
7
+ const subagentList = subagents.map((s) => {
8
+ const continuation = s.allowThreadContinuation ? "\n*(Supports thread continuation \u2014 pass a threadId to resume a previous conversation)*" : "";
9
+ return `## ${s.agentName}
10
+ ${s.description}${continuation}`;
11
+ }).join("\n\n");
9
12
  return `The ${SUBAGENT_TOOL_NAME} tool launches specialized agents (subagents) that autonomously handle complex work. Each agent type has specific capabilities and tools available to it.
10
13
 
11
14
  # Available subagents:
@@ -17,16 +20,38 @@ function createSubagentTool(subagents) {
17
20
  throw new Error("createTaskTool requires at least one subagent");
18
21
  }
19
22
  const names = subagents.map((s) => s.agentName);
23
+ const hasThreadContinuation = subagents.some(
24
+ (s) => s.allowThreadContinuation
25
+ );
26
+ const baseFields = {
27
+ subagent: z14.enum(names).describe("The type of subagent to launch"),
28
+ description: z14.string().describe("A short (3-5 word) description of the task"),
29
+ prompt: z14.string().describe("The task for the agent to perform")
30
+ };
31
+ const schema = hasThreadContinuation ? z14.object({
32
+ ...baseFields,
33
+ threadId: z14.string().nullable().describe(
34
+ "Thread ID to continue an existing conversation, or null to start a new one"
35
+ )
36
+ }) : z14.object(baseFields);
20
37
  return {
21
38
  name: SUBAGENT_TOOL_NAME,
22
39
  description: buildSubagentDescription(subagents),
23
- schema: z14.object({
24
- subagent: z14.enum(names).describe("The type of subagent to launch"),
25
- description: z14.string().describe("A short (3-5 word) description of the task"),
26
- prompt: z14.string().describe("The task for the agent to perform")
27
- })
40
+ schema
28
41
  };
29
42
  }
43
+ var BASE62 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
44
+ function getShortId(length = 12) {
45
+ const hex = uuid4().replace(/-/g, "");
46
+ let result = "";
47
+ for (let i = 0; i < length; i++) {
48
+ const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
49
+ result += BASE62[byte % BASE62.length];
50
+ }
51
+ return result;
52
+ }
53
+
54
+ // src/tools/subagent/handler.ts
30
55
  function createSubagentHandler(subagents) {
31
56
  const { taskQueue: parentTaskQueue } = workflowInfo();
32
57
  return async (args) => {
@@ -36,17 +61,18 @@ function createSubagentHandler(subagents) {
36
61
  `Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
37
62
  );
38
63
  }
39
- const childWorkflowId = `${args.subagent}-${uuid4()}`;
64
+ const childWorkflowId = `${args.subagent}-${getShortId()}`;
40
65
  const input = {
41
66
  prompt: args.prompt,
42
- ...config.context && { context: config.context }
67
+ ...config.context && { context: config.context },
68
+ ...args.threadId && config.allowThreadContinuation && { threadId: args.threadId }
43
69
  };
44
70
  const childOpts = {
45
71
  workflowId: childWorkflowId,
46
72
  args: [input],
47
73
  taskQueue: config.taskQueue ?? parentTaskQueue
48
74
  };
49
- const { toolResponse, data, usage } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
75
+ const { toolResponse, data, usage, threadId: childThreadId } = typeof config.workflow === "string" ? await executeChild(config.workflow, childOpts) : await executeChild(config.workflow, childOpts);
50
76
  if (!toolResponse) {
51
77
  return {
52
78
  toolResponse: "Subagent workflow returned no response",
@@ -62,8 +88,14 @@ function createSubagentHandler(subagents) {
62
88
  ...usage && { usage }
63
89
  };
64
90
  }
91
+ let finalToolResponse = toolResponse;
92
+ if (config.allowThreadContinuation && childThreadId) {
93
+ finalToolResponse = typeof toolResponse === "string" ? `${toolResponse}
94
+
95
+ [Thread ID: ${childThreadId}]` : toolResponse;
96
+ }
65
97
  return {
66
- toolResponse,
98
+ toolResponse: finalToolResponse,
67
99
  data: validated ? validated.data : data,
68
100
  ...usage && { usage }
69
101
  };
@@ -432,7 +464,7 @@ function hasNoOtherToolCalls(toolCalls, excludeName) {
432
464
 
433
465
  // src/lib/session.ts
434
466
  var createSession = async ({
435
- threadId,
467
+ threadId: providedThreadId,
436
468
  agentName,
437
469
  maxTurns = 50,
438
470
  metadata = {},
@@ -445,8 +477,10 @@ var createSession = async ({
445
477
  processToolsInParallel = true,
446
478
  hooks = {},
447
479
  appendSystemPrompt = true,
480
+ continueThread = false,
448
481
  waitForInputTimeout = "48h"
449
482
  }) => {
483
+ const threadId = providedThreadId ?? getShortId();
450
484
  const {
451
485
  appendToolResult,
452
486
  appendHumanMessage,
@@ -504,15 +538,18 @@ var createSession = async ({
504
538
  });
505
539
  }
506
540
  const systemPrompt = stateManager.getSystemPrompt();
507
- await initializeThread(threadId);
508
- if (appendSystemPrompt) {
509
- if (!systemPrompt || systemPrompt.trim() === "") {
510
- throw ApplicationFailure.create({
511
- message: "No system prompt in state",
512
- nonRetryable: true
513
- });
541
+ if (!continueThread) {
542
+ if (appendSystemPrompt) {
543
+ if (!systemPrompt || systemPrompt.trim() === "") {
544
+ throw ApplicationFailure.create({
545
+ message: "No system prompt in state",
546
+ nonRetryable: true
547
+ });
548
+ }
549
+ await appendSystemMessage(threadId, systemPrompt);
550
+ } else {
551
+ await initializeThread(threadId);
514
552
  }
515
- await appendSystemMessage(threadId, systemPrompt);
516
553
  }
517
554
  await appendHumanMessage(threadId, await buildContextMessage());
518
555
  let exitReason = "completed";
@@ -594,7 +631,7 @@ var createSession = async ({
594
631
  };
595
632
  };
596
633
  function proxyDefaultThreadOps(options) {
597
- const activities = proxyActivities(
634
+ return proxyActivities(
598
635
  options ?? {
599
636
  startToCloseTimeout: "10s",
600
637
  retry: {
@@ -605,12 +642,6 @@ function proxyDefaultThreadOps(options) {
605
642
  }
606
643
  }
607
644
  );
608
- return {
609
- initializeThread: activities.initializeThread,
610
- appendHumanMessage: activities.appendHumanMessage,
611
- appendToolResult: activities.appendToolResult,
612
- appendSystemMessage: activities.appendSystemMessage
613
- };
614
645
  }
615
646
 
616
647
  // src/lib/types.ts
@@ -1197,6 +1228,6 @@ var createAskUserQuestionHandler = () => async (args) => {
1197
1228
  };
1198
1229
  };
1199
1230
 
1200
- export { agentQueryName, agentStateChangeUpdateName, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createSubagentTool, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineTool, editTool, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyDefaultThreadOps, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
1231
+ export { agentQueryName, agentStateChangeUpdateName, askUserQuestionTool, bashTool, createAgentStateManager, createAskUserQuestionHandler, createBashToolDescription, createReadSkillHandler, createReadSkillTool, createSession, createSubagentTool, createTaskCreateHandler, createTaskGetHandler, createTaskListHandler, createTaskUpdateHandler, createToolRouter, defineSubagent, defineTool, editTool, getShortId, globTool, grepTool, hasNoOtherToolCalls, isTerminalStatus, parseSkillFile, proxyDefaultThreadOps, readFileTool, taskCreateTool, taskGetTool, taskListTool, taskUpdateTool, writeFileTool };
1201
1232
  //# sourceMappingURL=workflow.js.map
1202
1233
  //# sourceMappingURL=workflow.js.map