zeitlich 0.2.3 → 0.2.4
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.
- package/dist/index.cjs +28 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +29 -42
- package/dist/index.js.map +1 -1
- package/dist/{workflow-D-2vp4Pq.d.cts → workflow-PjeURKw4.d.cts} +12 -29
- package/dist/{workflow-D-2vp4Pq.d.ts → workflow-PjeURKw4.d.ts} +12 -29
- package/dist/workflow.cjs +20 -31
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +1 -1
- package/dist/workflow.d.ts +1 -1
- package/dist/workflow.js +20 -31
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/activities.ts +0 -19
- package/src/lib/model-invoker.ts +7 -1
- package/src/lib/session.ts +3 -15
- package/src/lib/tool-router.ts +9 -9
- package/src/lib/types.ts +7 -5
- package/src/tools/{task → subagent}/handler.ts +18 -31
- package/src/tools/{task → subagent}/tool.ts +13 -13
- package/src/workflow.ts +2 -3
package/src/lib/session.ts
CHANGED
|
@@ -7,12 +7,10 @@ import type {
|
|
|
7
7
|
SessionEndHook,
|
|
8
8
|
SessionExitReason,
|
|
9
9
|
} from "./types";
|
|
10
|
-
import type { StoredMessage } from "@langchain/core/messages";
|
|
11
10
|
import { type AgentStateManager, type JsonSerializable } from "./state-manager";
|
|
12
11
|
import {
|
|
13
12
|
createToolRouter,
|
|
14
13
|
type ParsedToolCallUnion,
|
|
15
|
-
type RawToolCall,
|
|
16
14
|
type ToolMap,
|
|
17
15
|
} from "./tool-router";
|
|
18
16
|
|
|
@@ -95,28 +93,19 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
95
93
|
stateManager.incrementTurns();
|
|
96
94
|
const currentTurn = stateManager.getTurns();
|
|
97
95
|
|
|
98
|
-
const { message,
|
|
96
|
+
const { message, rawToolCalls } = await runAgent({
|
|
99
97
|
threadId,
|
|
100
98
|
agentName,
|
|
101
99
|
metadata,
|
|
102
100
|
});
|
|
103
101
|
|
|
104
|
-
if (stopReason === "end_turn") {
|
|
105
|
-
stateManager.complete();
|
|
106
|
-
exitReason = "completed";
|
|
107
|
-
return message;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
102
|
// No tools configured - treat any non-end_turn as completed
|
|
111
|
-
if (!toolRouter.hasTools()) {
|
|
103
|
+
if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
|
|
112
104
|
stateManager.complete();
|
|
113
105
|
exitReason = "completed";
|
|
114
106
|
return message;
|
|
115
107
|
}
|
|
116
108
|
|
|
117
|
-
const rawToolCalls: RawToolCall[] =
|
|
118
|
-
await threadOps.parseToolCalls(message);
|
|
119
|
-
|
|
120
109
|
// Parse all tool calls uniformly through the router
|
|
121
110
|
const parsedToolCalls: ParsedToolCallUnion<T>[] = [];
|
|
122
111
|
for (const tc of rawToolCalls) {
|
|
@@ -176,7 +165,7 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
176
165
|
*/
|
|
177
166
|
export function proxyDefaultThreadOps(
|
|
178
167
|
options?: Parameters<typeof proxyActivities>[0]
|
|
179
|
-
): ThreadOps
|
|
168
|
+
): ThreadOps {
|
|
180
169
|
const activities = proxyActivities<ZeitlichSharedActivities>(
|
|
181
170
|
options ?? {
|
|
182
171
|
startToCloseTimeout: "30m",
|
|
@@ -194,6 +183,5 @@ export function proxyDefaultThreadOps(
|
|
|
194
183
|
initializeThread: activities.initializeThread,
|
|
195
184
|
appendHumanMessage: activities.appendHumanMessage,
|
|
196
185
|
appendToolResult: activities.appendToolResult,
|
|
197
|
-
parseToolCalls: activities.parseToolCalls,
|
|
198
186
|
};
|
|
199
187
|
}
|
package/src/lib/tool-router.ts
CHANGED
|
@@ -9,11 +9,11 @@ import type {
|
|
|
9
9
|
ToolHooks,
|
|
10
10
|
ToolResultConfig,
|
|
11
11
|
} from "./types";
|
|
12
|
-
import type {
|
|
12
|
+
import type { SubagentArgs } from "../tools/subagent/tool";
|
|
13
13
|
|
|
14
14
|
import type { z } from "zod";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
15
|
+
import { createSubagentTool } from "../tools/subagent/tool";
|
|
16
|
+
import { createSubagentHandler } from "../tools/subagent/handler";
|
|
17
17
|
|
|
18
18
|
export type { ToolMessageContent };
|
|
19
19
|
|
|
@@ -422,11 +422,11 @@ export function createToolRouter<T extends ToolMap>(
|
|
|
422
422
|
}
|
|
423
423
|
|
|
424
424
|
const resolveSubagentName = (args: unknown): string =>
|
|
425
|
-
(args as
|
|
425
|
+
(args as SubagentArgs).subagent;
|
|
426
426
|
|
|
427
|
-
toolMap.set("
|
|
428
|
-
...
|
|
429
|
-
handler:
|
|
427
|
+
toolMap.set("Subagent", {
|
|
428
|
+
...createSubagentTool(options.subagents),
|
|
429
|
+
handler: createSubagentHandler(options.subagents),
|
|
430
430
|
...(subagentHooksMap.size > 0 && {
|
|
431
431
|
hooks: {
|
|
432
432
|
onPreToolUse: async (ctx): Promise<PreToolUseHookResult> => {
|
|
@@ -912,7 +912,7 @@ export function defineSubagent<
|
|
|
912
912
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
913
913
|
| ((input: { prompt: string; context: TContext }) => Promise<any>);
|
|
914
914
|
context: TContext;
|
|
915
|
-
hooks?: SubagentHooks<
|
|
915
|
+
hooks?: SubagentHooks<SubagentArgs, z.infer<TResult>>;
|
|
916
916
|
}
|
|
917
917
|
): SubagentConfig<TResult>;
|
|
918
918
|
// Without context — verifies workflow accepts { prompt }
|
|
@@ -920,7 +920,7 @@ export function defineSubagent<TResult extends z.ZodType = z.ZodType>(
|
|
|
920
920
|
config: Omit<SubagentConfig<TResult>, "hooks" | "workflow"> & {
|
|
921
921
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
922
922
|
workflow: string | ((input: { prompt: string }) => Promise<any>);
|
|
923
|
-
hooks?: SubagentHooks<
|
|
923
|
+
hooks?: SubagentHooks<SubagentArgs, z.infer<TResult>>;
|
|
924
924
|
}
|
|
925
925
|
): SubagentConfig<TResult>;
|
|
926
926
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
package/src/lib/types.ts
CHANGED
|
@@ -54,7 +54,7 @@ export interface AgentFile {
|
|
|
54
54
|
*/
|
|
55
55
|
export interface AgentResponse<M = StoredMessage> {
|
|
56
56
|
message: M;
|
|
57
|
-
|
|
57
|
+
rawToolCalls: RawToolCall[];
|
|
58
58
|
usage?: {
|
|
59
59
|
input_tokens?: number;
|
|
60
60
|
output_tokens?: number;
|
|
@@ -67,7 +67,7 @@ export interface AgentResponse<M = StoredMessage> {
|
|
|
67
67
|
* Consumers provide these — typically by wrapping Temporal activities.
|
|
68
68
|
* Use `proxyDefaultThreadOps()` for the default StoredMessage implementation.
|
|
69
69
|
*/
|
|
70
|
-
export interface ThreadOps
|
|
70
|
+
export interface ThreadOps {
|
|
71
71
|
/** Initialize an empty thread */
|
|
72
72
|
initializeThread(threadId: string): Promise<void>;
|
|
73
73
|
/** Append a human message to the thread */
|
|
@@ -77,8 +77,6 @@ export interface ThreadOps<M = StoredMessage> {
|
|
|
77
77
|
): Promise<void>;
|
|
78
78
|
/** Append a tool result to the thread */
|
|
79
79
|
appendToolResult(config: ToolResultConfig): Promise<void>;
|
|
80
|
-
/** Extract raw tool calls from a message */
|
|
81
|
-
parseToolCalls(message: M): Promise<RawToolCall[]>;
|
|
82
80
|
}
|
|
83
81
|
|
|
84
82
|
/**
|
|
@@ -92,7 +90,7 @@ export interface ZeitlichAgentConfig<T extends ToolMap, M = StoredMessage> {
|
|
|
92
90
|
/** Workflow-specific runAgent activity (with tools pre-bound) */
|
|
93
91
|
runAgent: RunAgentActivity<M>;
|
|
94
92
|
/** Thread operations (initialize, append messages, parse tool calls) */
|
|
95
|
-
threadOps: ThreadOps
|
|
93
|
+
threadOps: ThreadOps;
|
|
96
94
|
/** Tool router for processing tool calls (optional if agent has no tools) */
|
|
97
95
|
tools?: T;
|
|
98
96
|
/** Subagent configurations */
|
|
@@ -152,6 +150,10 @@ export interface ToolResultConfig {
|
|
|
152
150
|
// Subagent Configuration
|
|
153
151
|
// ============================================================================
|
|
154
152
|
|
|
153
|
+
/** Infer the z.infer'd result type from a SubagentConfig, or null if no schema */
|
|
154
|
+
export type InferSubagentResult<T extends SubagentConfig> =
|
|
155
|
+
T extends SubagentConfig<infer S> ? z.infer<S> : null;
|
|
156
|
+
|
|
155
157
|
/**
|
|
156
158
|
* Configuration for a subagent that can be spawned by the parent workflow.
|
|
157
159
|
*
|
|
@@ -1,26 +1,20 @@
|
|
|
1
1
|
import { executeChild, workflowInfo, uuid4 } from "@temporalio/workflow";
|
|
2
2
|
import type { ToolHandlerResponse } from "../../lib/tool-router";
|
|
3
|
-
import type {
|
|
4
|
-
|
|
3
|
+
import type {
|
|
4
|
+
InferSubagentResult,
|
|
5
|
+
SubagentConfig,
|
|
6
|
+
SubagentInput,
|
|
7
|
+
} from "../../lib/types";
|
|
8
|
+
import type { SubagentArgs } from "./tool";
|
|
5
9
|
|
|
6
10
|
/**
|
|
7
|
-
*
|
|
8
|
-
*/
|
|
9
|
-
export interface TaskHandlerResult<TResult = unknown> {
|
|
10
|
-
/** The validated result from the child workflow */
|
|
11
|
-
result: TResult;
|
|
12
|
-
/** The child workflow ID (for reference/debugging) */
|
|
13
|
-
childWorkflowId: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates a Task tool handler that spawns child workflows for configured subagents.
|
|
11
|
+
* Creates a Subagent tool handler that spawns child workflows for configured subagents.
|
|
18
12
|
*
|
|
19
13
|
* @param subagents - Array of subagent configurations
|
|
20
14
|
* @returns A tool handler function that can be used with the tool router
|
|
21
15
|
*
|
|
22
16
|
* @example
|
|
23
|
-
* const
|
|
17
|
+
* const subagentHandler = subagentHandler([
|
|
24
18
|
* {
|
|
25
19
|
* name: "researcher",
|
|
26
20
|
* description: "Researches topics",
|
|
@@ -29,13 +23,15 @@ export interface TaskHandlerResult<TResult = unknown> {
|
|
|
29
23
|
* },
|
|
30
24
|
* ]);
|
|
31
25
|
*/
|
|
32
|
-
export function
|
|
26
|
+
export function createSubagentHandler<
|
|
27
|
+
const T extends readonly SubagentConfig[],
|
|
28
|
+
>(subagents: [...T]) {
|
|
33
29
|
const { workflowId: parentWorkflowId, taskQueue: parentTaskQueue } =
|
|
34
30
|
workflowInfo();
|
|
35
31
|
|
|
36
32
|
return async (
|
|
37
|
-
args:
|
|
38
|
-
): Promise<ToolHandlerResponse<
|
|
33
|
+
args: SubagentArgs
|
|
34
|
+
): Promise<ToolHandlerResponse<InferSubagentResult<T[number]> | null>> => {
|
|
39
35
|
const config = subagents.find((s) => s.name === args.subagent);
|
|
40
36
|
|
|
41
37
|
if (!config) {
|
|
@@ -58,28 +54,19 @@ export function createTaskHandler(subagents: SubagentConfig[]) {
|
|
|
58
54
|
taskQueue: config.taskQueue ?? parentTaskQueue,
|
|
59
55
|
};
|
|
60
56
|
|
|
61
|
-
const
|
|
57
|
+
const { toolResponse, data } =
|
|
62
58
|
typeof config.workflow === "string"
|
|
63
59
|
? await executeChild(config.workflow, childOpts)
|
|
64
60
|
: await executeChild(config.workflow, childOpts);
|
|
65
61
|
|
|
66
62
|
// Validate result if schema provided, otherwise pass through as-is
|
|
67
|
-
const validated =
|
|
68
|
-
? config.resultSchema.parse(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// Format content - stringify objects, pass strings through
|
|
72
|
-
const toolResponse =
|
|
73
|
-
typeof validated === "string"
|
|
74
|
-
? validated
|
|
75
|
-
: JSON.stringify(validated, null, 2);
|
|
63
|
+
const validated = (
|
|
64
|
+
config.resultSchema ? config.resultSchema.parse(data) : null
|
|
65
|
+
) as InferSubagentResult<T[number]> | null;
|
|
76
66
|
|
|
77
67
|
return {
|
|
78
68
|
toolResponse,
|
|
79
|
-
data:
|
|
80
|
-
result: validated,
|
|
81
|
-
childWorkflowId,
|
|
82
|
-
},
|
|
69
|
+
data: validated,
|
|
83
70
|
};
|
|
84
71
|
};
|
|
85
72
|
}
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
2
|
import type { SubagentConfig } from "../../lib/types";
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const SUBAGENT_TOOL = "Subagent" as const;
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Builds the tool description with available subagent information
|
|
8
8
|
*/
|
|
9
|
-
function
|
|
9
|
+
function buildSubagentDescription(subagents: SubagentConfig[]): string {
|
|
10
10
|
const subagentList = subagents
|
|
11
11
|
.map((s) => `- **${s.name}**: ${s.description}`)
|
|
12
12
|
.join("\n");
|
|
13
13
|
|
|
14
|
-
return `Launch a new agent to handle complex
|
|
14
|
+
return `Launch a new agent to handle complex tasks autonomously.
|
|
15
15
|
|
|
16
|
-
The ${
|
|
16
|
+
The ${SUBAGENT_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
|
|
17
17
|
|
|
18
18
|
Available agent types:
|
|
19
19
|
|
|
20
20
|
${subagentList}
|
|
21
21
|
|
|
22
|
-
When using the ${
|
|
22
|
+
When using the ${SUBAGENT_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
|
|
23
23
|
|
|
24
24
|
Usage notes:
|
|
25
25
|
|
|
26
26
|
- Always include a short description (3-5 words) summarizing what the agent will do
|
|
27
27
|
- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
|
|
28
|
-
- When the agent is done, it will return a single message back to you.
|
|
28
|
+
- When the agent is done, it will return a single message back to you.
|
|
29
29
|
- Each invocation starts fresh - provide a detailed task description with all necessary context.
|
|
30
30
|
- Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
|
|
31
31
|
- The agent's outputs should generally be trusted
|
|
@@ -34,13 +34,13 @@ Usage notes:
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* Creates a
|
|
37
|
+
* Creates a Subagent tool configured with the available subagents.
|
|
38
38
|
*
|
|
39
39
|
* @param subagents - Array of subagent configurations (must have at least one)
|
|
40
40
|
* @returns A tool definition with dynamic schema based on available subagents
|
|
41
41
|
*
|
|
42
42
|
* @example
|
|
43
|
-
* const
|
|
43
|
+
* const subagentTool = createSubagentTool([
|
|
44
44
|
* {
|
|
45
45
|
* name: "researcher",
|
|
46
46
|
* description: "Researches topics and gathers information",
|
|
@@ -49,7 +49,7 @@ Usage notes:
|
|
|
49
49
|
* },
|
|
50
50
|
* ]);
|
|
51
51
|
*/
|
|
52
|
-
export function
|
|
52
|
+
export function createSubagentTool<T extends SubagentConfig[]>(
|
|
53
53
|
subagents: T
|
|
54
54
|
): {
|
|
55
55
|
name: string;
|
|
@@ -67,8 +67,8 @@ export function createTaskTool<T extends SubagentConfig[]>(
|
|
|
67
67
|
const names = subagents.map((s) => s.name);
|
|
68
68
|
|
|
69
69
|
return {
|
|
70
|
-
name:
|
|
71
|
-
description:
|
|
70
|
+
name: SUBAGENT_TOOL,
|
|
71
|
+
description: buildSubagentDescription(subagents),
|
|
72
72
|
schema: z.object({
|
|
73
73
|
subagent: z.enum(names).describe("The type of subagent to launch"),
|
|
74
74
|
description: z
|
|
@@ -80,9 +80,9 @@ export function createTaskTool<T extends SubagentConfig[]>(
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Subagent tool args type (when subagent names are not known at compile time)
|
|
84
84
|
*/
|
|
85
|
-
export type
|
|
85
|
+
export type SubagentArgs = {
|
|
86
86
|
subagent: string;
|
|
87
87
|
description: string;
|
|
88
88
|
prompt: string;
|
package/src/workflow.ts
CHANGED
|
@@ -101,9 +101,8 @@ export type {
|
|
|
101
101
|
export { isTerminalStatus } from "./lib/types";
|
|
102
102
|
|
|
103
103
|
// Subagent support
|
|
104
|
-
export {
|
|
105
|
-
export type {
|
|
106
|
-
export type { TaskHandlerResult } from "./tools/task/handler";
|
|
104
|
+
export { createSubagentTool } from "./tools/subagent/tool";
|
|
105
|
+
export type { SubagentArgs } from "./tools/subagent/tool";
|
|
107
106
|
|
|
108
107
|
// Activity type interfaces (types only, no runtime code)
|
|
109
108
|
// These are safe to import in workflows for typing proxyActivities
|