zeitlich 0.2.4 → 0.2.6
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/README.md +70 -40
- package/dist/index.cjs +71 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +72 -37
- package/dist/index.js.map +1 -1
- package/dist/{workflow-PjeURKw4.d.cts → workflow-Dg5JMeOC.d.cts} +18 -4
- package/dist/{workflow-PjeURKw4.d.ts → workflow-Dg5JMeOC.d.ts} +18 -4
- package/dist/workflow.cjs +52 -35
- 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 +52 -35
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/activities.ts +11 -0
- package/src/index.ts +4 -4
- package/src/lib/model-invoker.ts +5 -4
- package/src/lib/session.ts +17 -4
- package/src/lib/thread-manager.ts +15 -3
- package/src/lib/tool-router.ts +40 -31
- package/src/lib/types.ts +10 -2
- package/src/tools/subagent/handler.ts +4 -5
- package/src/tools/subagent/tool.ts +3 -3
- package/src/workflow.ts +2 -2
package/src/lib/model-invoker.ts
CHANGED
|
@@ -23,10 +23,11 @@ export interface InvokeModelConfig {
|
|
|
23
23
|
/**
|
|
24
24
|
* Core model invocation logic - shared utility for workflow-specific activities
|
|
25
25
|
*
|
|
26
|
-
* @param
|
|
27
|
-
* @param
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
26
|
+
* @param options - Named options object
|
|
27
|
+
* @param options.redis - Redis client for thread management
|
|
28
|
+
* @param options.config - Model invocation configuration (threadId, agentName)
|
|
29
|
+
* @param options.model - Pre-instantiated LangChain chat model
|
|
30
|
+
* @param options.client - Temporal WorkflowClient for querying workflow state
|
|
30
31
|
* @returns Agent response with message and metadata
|
|
31
32
|
*/
|
|
32
33
|
export async function invokeModel({
|
package/src/lib/session.ts
CHANGED
|
@@ -42,10 +42,18 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
42
42
|
tools = {} as T,
|
|
43
43
|
processToolsInParallel = true,
|
|
44
44
|
hooks = {},
|
|
45
|
+
appendSystemPrompt = true,
|
|
46
|
+
systemPrompt,
|
|
45
47
|
}: ZeitlichAgentConfig<T, M>): Promise<ZeitlichSession<M>> => {
|
|
48
|
+
const {
|
|
49
|
+
appendToolResult,
|
|
50
|
+
appendHumanMessage,
|
|
51
|
+
initializeThread,
|
|
52
|
+
appendSystemMessage,
|
|
53
|
+
} = threadOps ?? proxyDefaultThreadOps();
|
|
46
54
|
const toolRouter = createToolRouter({
|
|
47
55
|
tools,
|
|
48
|
-
appendToolResult
|
|
56
|
+
appendToolResult,
|
|
49
57
|
threadId,
|
|
50
58
|
hooks,
|
|
51
59
|
subagents,
|
|
@@ -77,10 +85,14 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
77
85
|
metadata,
|
|
78
86
|
});
|
|
79
87
|
}
|
|
88
|
+
|
|
80
89
|
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
81
90
|
|
|
82
|
-
await
|
|
83
|
-
|
|
91
|
+
await initializeThread(threadId);
|
|
92
|
+
if (appendSystemPrompt && systemPrompt && systemPrompt.trim() !== "") {
|
|
93
|
+
await appendSystemMessage(threadId, systemPrompt);
|
|
94
|
+
}
|
|
95
|
+
await appendHumanMessage(threadId, await buildContextMessage());
|
|
84
96
|
|
|
85
97
|
let exitReason: SessionExitReason = "completed";
|
|
86
98
|
|
|
@@ -112,7 +124,7 @@ export const createSession = async <T extends ToolMap, M = unknown>({
|
|
|
112
124
|
try {
|
|
113
125
|
parsedToolCalls.push(toolRouter.parseToolCall(tc));
|
|
114
126
|
} catch (error) {
|
|
115
|
-
await
|
|
127
|
+
await appendToolResult({
|
|
116
128
|
threadId,
|
|
117
129
|
toolCallId: tc.id ?? "",
|
|
118
130
|
toolName: tc.name,
|
|
@@ -183,5 +195,6 @@ export function proxyDefaultThreadOps(
|
|
|
183
195
|
initializeThread: activities.initializeThread,
|
|
184
196
|
appendHumanMessage: activities.appendHumanMessage,
|
|
185
197
|
appendToolResult: activities.appendToolResult,
|
|
198
|
+
appendSystemMessage: activities.appendSystemMessage,
|
|
186
199
|
};
|
|
187
200
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type MessageContent,
|
|
8
8
|
type MessageStructure,
|
|
9
9
|
type StoredMessage,
|
|
10
|
+
SystemMessage,
|
|
10
11
|
ToolMessage,
|
|
11
12
|
} from "@langchain/core/messages";
|
|
12
13
|
import { v4 as uuidv4 } from "uuid";
|
|
@@ -50,21 +51,20 @@ export interface BaseThreadManager<T> {
|
|
|
50
51
|
export interface ThreadManager extends BaseThreadManager<StoredMessage> {
|
|
51
52
|
/** Create a HumanMessage (returns StoredMessage for storage) */
|
|
52
53
|
createHumanMessage(content: string | MessageContent): StoredMessage;
|
|
53
|
-
|
|
54
54
|
/** Create an AIMessage with optional additional kwargs */
|
|
55
55
|
createAIMessage(
|
|
56
56
|
content: string | MessageContent,
|
|
57
57
|
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
58
58
|
): StoredMessage;
|
|
59
|
-
|
|
60
59
|
/** Create a ToolMessage */
|
|
61
60
|
createToolMessage(
|
|
62
61
|
content: ToolMessageContent,
|
|
63
62
|
toolCallId: string
|
|
64
63
|
): StoredMessage;
|
|
65
|
-
|
|
66
64
|
/** Create and append a HumanMessage */
|
|
67
65
|
appendHumanMessage(content: string | MessageContent): Promise<void>;
|
|
66
|
+
/** Create and append a SystemMessage */
|
|
67
|
+
appendSystemMessage(content: string): Promise<void>;
|
|
68
68
|
/** Create and append a ToolMessage */
|
|
69
69
|
appendToolMessage(
|
|
70
70
|
content: ToolMessageContent,
|
|
@@ -127,6 +127,13 @@ export function createThreadManager<T>(
|
|
|
127
127
|
}).toDict();
|
|
128
128
|
},
|
|
129
129
|
|
|
130
|
+
createSystemMessage(content: string): StoredMessage {
|
|
131
|
+
return new SystemMessage({
|
|
132
|
+
id: uuidv4(),
|
|
133
|
+
content: content as string,
|
|
134
|
+
}).toDict();
|
|
135
|
+
},
|
|
136
|
+
|
|
130
137
|
createAIMessage(
|
|
131
138
|
content: string,
|
|
132
139
|
kwargs?: { header?: string; options?: string[]; multiSelect?: boolean }
|
|
@@ -171,6 +178,11 @@ export function createThreadManager<T>(
|
|
|
171
178
|
const message = helpers.createAIMessage(content as string);
|
|
172
179
|
await (base as BaseThreadManager<StoredMessage>).append([message]);
|
|
173
180
|
},
|
|
181
|
+
|
|
182
|
+
async appendSystemMessage(content: string): Promise<void> {
|
|
183
|
+
const message = helpers.createSystemMessage(content);
|
|
184
|
+
await (base as BaseThreadManager<StoredMessage>).append([message]);
|
|
185
|
+
},
|
|
174
186
|
};
|
|
175
187
|
|
|
176
188
|
return Object.assign(base, helpers);
|
package/src/lib/tool-router.ts
CHANGED
|
@@ -415,37 +415,42 @@ export function createToolRouter<T extends ToolMap>(
|
|
|
415
415
|
const isEnabled = (tool: ToolMap[string]): boolean => tool.enabled !== false;
|
|
416
416
|
|
|
417
417
|
if (options.subagents) {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
418
|
+
const enabledSubagents = options.subagents.filter(
|
|
419
|
+
(s) => s.enabled !== false
|
|
420
|
+
);
|
|
421
|
+
if (enabledSubagents.length > 0) {
|
|
422
|
+
// Build per-subagent hook dispatcher keyed by subagent name
|
|
423
|
+
const subagentHooksMap = new Map<string, SubagentHooks>();
|
|
424
|
+
for (const s of enabledSubagents) {
|
|
425
|
+
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
426
|
+
}
|
|
423
427
|
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
428
|
+
const resolveSubagentName = (args: unknown): string =>
|
|
429
|
+
(args as SubagentArgs).subagent;
|
|
430
|
+
|
|
431
|
+
toolMap.set("Subagent", {
|
|
432
|
+
...createSubagentTool(enabledSubagents),
|
|
433
|
+
handler: createSubagentHandler(enabledSubagents),
|
|
434
|
+
...(subagentHooksMap.size > 0 && {
|
|
435
|
+
hooks: {
|
|
436
|
+
onPreToolUse: async (ctx): Promise<PreToolUseHookResult> => {
|
|
437
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
438
|
+
return hooks?.onPreExecution?.(ctx) ?? {};
|
|
439
|
+
},
|
|
440
|
+
onPostToolUse: async (ctx): Promise<void> => {
|
|
441
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
442
|
+
await hooks?.onPostExecution?.(ctx);
|
|
443
|
+
},
|
|
444
|
+
onPostToolUseFailure: async (
|
|
445
|
+
ctx
|
|
446
|
+
): Promise<PostToolUseFailureHookResult> => {
|
|
447
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
448
|
+
return hooks?.onExecutionFailure?.(ctx) ?? {};
|
|
449
|
+
},
|
|
450
|
+
} satisfies ToolHooks,
|
|
451
|
+
}),
|
|
452
|
+
});
|
|
453
|
+
}
|
|
449
454
|
}
|
|
450
455
|
|
|
451
456
|
async function processToolCall(
|
|
@@ -837,7 +842,11 @@ export function withAutoAppend<
|
|
|
837
842
|
});
|
|
838
843
|
|
|
839
844
|
// Return with empty toolResponse to keep the Temporal payload small
|
|
840
|
-
return {
|
|
845
|
+
return {
|
|
846
|
+
toolResponse: "Response appended via withAutoAppend",
|
|
847
|
+
data: response.data,
|
|
848
|
+
resultAppended: true,
|
|
849
|
+
};
|
|
841
850
|
};
|
|
842
851
|
}
|
|
843
852
|
|
package/src/lib/types.ts
CHANGED
|
@@ -77,6 +77,8 @@ export interface ThreadOps {
|
|
|
77
77
|
): Promise<void>;
|
|
78
78
|
/** Append a tool result to the thread */
|
|
79
79
|
appendToolResult(config: ToolResultConfig): Promise<void>;
|
|
80
|
+
/** Append a system message to the thread */
|
|
81
|
+
appendSystemMessage(threadId: string, content: string): Promise<void>;
|
|
80
82
|
}
|
|
81
83
|
|
|
82
84
|
/**
|
|
@@ -85,12 +87,16 @@ export interface ThreadOps {
|
|
|
85
87
|
export interface ZeitlichAgentConfig<T extends ToolMap, M = StoredMessage> {
|
|
86
88
|
threadId: string;
|
|
87
89
|
agentName: string;
|
|
90
|
+
/** Description, used for sub agents */
|
|
91
|
+
description?: string;
|
|
92
|
+
systemPrompt?: string;
|
|
88
93
|
metadata?: Record<string, unknown>;
|
|
94
|
+
appendSystemPrompt?: boolean;
|
|
89
95
|
maxTurns?: number;
|
|
90
96
|
/** Workflow-specific runAgent activity (with tools pre-bound) */
|
|
91
97
|
runAgent: RunAgentActivity<M>;
|
|
92
98
|
/** Thread operations (initialize, append messages, parse tool calls) */
|
|
93
|
-
threadOps
|
|
99
|
+
threadOps?: ThreadOps;
|
|
94
100
|
/** Tool router for processing tool calls (optional if agent has no tools) */
|
|
95
101
|
tools?: T;
|
|
96
102
|
/** Subagent configurations */
|
|
@@ -161,9 +167,11 @@ export type InferSubagentResult<T extends SubagentConfig> =
|
|
|
161
167
|
*/
|
|
162
168
|
export interface SubagentConfig<TResult extends z.ZodType = z.ZodType> {
|
|
163
169
|
/** Identifier used in Task tool's subagent parameter */
|
|
164
|
-
|
|
170
|
+
agentName: string;
|
|
165
171
|
/** Description shown to the parent agent explaining what this subagent does */
|
|
166
172
|
description: string;
|
|
173
|
+
/** Whether this subagent is available (default: true). Disabled subagents are excluded from the Subagent tool. */
|
|
174
|
+
enabled?: boolean;
|
|
167
175
|
/** Temporal workflow function or type name (used with executeChild) */
|
|
168
176
|
workflow: string | Workflow;
|
|
169
177
|
/** Optional task queue - defaults to parent's queue if not specified */
|
|
@@ -26,21 +26,20 @@ import type { SubagentArgs } from "./tool";
|
|
|
26
26
|
export function createSubagentHandler<
|
|
27
27
|
const T extends readonly SubagentConfig[],
|
|
28
28
|
>(subagents: [...T]) {
|
|
29
|
-
const {
|
|
30
|
-
workflowInfo();
|
|
29
|
+
const { taskQueue: parentTaskQueue } = workflowInfo();
|
|
31
30
|
|
|
32
31
|
return async (
|
|
33
32
|
args: SubagentArgs
|
|
34
33
|
): Promise<ToolHandlerResponse<InferSubagentResult<T[number]> | null>> => {
|
|
35
|
-
const config = subagents.find((s) => s.
|
|
34
|
+
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
36
35
|
|
|
37
36
|
if (!config) {
|
|
38
37
|
throw new Error(
|
|
39
|
-
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.
|
|
38
|
+
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
|
|
40
39
|
);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
|
-
const childWorkflowId = `${
|
|
42
|
+
const childWorkflowId = `${args.subagent}-${uuid4()}`;
|
|
44
43
|
|
|
45
44
|
// Execute the child workflow
|
|
46
45
|
const input: SubagentInput = {
|
|
@@ -8,7 +8,7 @@ const SUBAGENT_TOOL = "Subagent" as const;
|
|
|
8
8
|
*/
|
|
9
9
|
function buildSubagentDescription(subagents: SubagentConfig[]): string {
|
|
10
10
|
const subagentList = subagents
|
|
11
|
-
.map((s) => `- **${s.
|
|
11
|
+
.map((s) => `- **${s.agentName}**: ${s.description}`)
|
|
12
12
|
.join("\n");
|
|
13
13
|
|
|
14
14
|
return `Launch a new agent to handle complex tasks autonomously.
|
|
@@ -42,7 +42,7 @@ Usage notes:
|
|
|
42
42
|
* @example
|
|
43
43
|
* const subagentTool = createSubagentTool([
|
|
44
44
|
* {
|
|
45
|
-
*
|
|
45
|
+
* agentName: "researcher",
|
|
46
46
|
* description: "Researches topics and gathers information",
|
|
47
47
|
* workflow: "researcherWorkflow",
|
|
48
48
|
* resultSchema: z.object({ findings: z.string() }),
|
|
@@ -64,7 +64,7 @@ export function createSubagentTool<T extends SubagentConfig[]>(
|
|
|
64
64
|
throw new Error("createTaskTool requires at least one subagent");
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const names = subagents.map((s) => s.
|
|
67
|
+
const names = subagents.map((s) => s.agentName);
|
|
68
68
|
|
|
69
69
|
return {
|
|
70
70
|
name: SUBAGENT_TOOL,
|
package/src/workflow.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Workflow-safe exports for use in Temporal workflow code.
|
|
3
3
|
*
|
|
4
|
-
* Import from '
|
|
4
|
+
* Import from 'zeitlich/workflow' in workflow files.
|
|
5
5
|
* These exports have no external dependencies (no Redis, no LangChain).
|
|
6
6
|
*
|
|
7
7
|
* @example
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* createSession,
|
|
12
12
|
* createAgentStateManager,
|
|
13
13
|
* createToolRouter,
|
|
14
|
-
* } from '
|
|
14
|
+
* } from 'zeitlich/workflow';
|
|
15
15
|
* ```
|
|
16
16
|
*/
|
|
17
17
|
|