zeitlich 0.2.3 → 0.2.5
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 +83 -71
- 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 +84 -72
- package/dist/index.js.map +1 -1
- package/dist/{workflow-D-2vp4Pq.d.cts → workflow-Dg5JMeOC.d.cts} +27 -30
- package/dist/{workflow-D-2vp4Pq.d.ts → workflow-Dg5JMeOC.d.ts} +27 -30
- package/dist/workflow.cjs +67 -61
- 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 +67 -61
- package/dist/workflow.js.map +1 -1
- package/package.json +1 -1
- package/src/activities.ts +8 -16
- package/src/index.ts +4 -4
- package/src/lib/model-invoker.ts +12 -5
- package/src/lib/session.ts +20 -19
- package/src/lib/thread-manager.ts +2 -3
- package/src/lib/tool-router.ts +45 -36
- package/src/lib/types.ts +16 -6
- package/src/tools/subagent/handler.ts +71 -0
- package/src/tools/{task → subagent}/tool.ts +16 -16
- package/src/workflow.ts +4 -5
- package/src/tools/task/handler.ts +0 -85
package/README.md
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
[](https://www.npmjs.org/package/zeitlich)
|
|
2
2
|
[](https://npm-stat.com/charts.html?package=zeitlich)
|
|
3
|
+
[](https://deepwiki.com/bead-ai/zeitlich)
|
|
3
4
|
|
|
4
5
|
# Zeitlich
|
|
5
6
|
|
|
@@ -51,7 +52,7 @@ const google = new ChatGoogleGenerativeAI({ model: "gemini-1.5-pro" });
|
|
|
51
52
|
|
|
52
53
|
// Pass to invokeModel in your activity
|
|
53
54
|
return {
|
|
54
|
-
runAgent: (config) => invokeModel(
|
|
55
|
+
runAgent: (config) => invokeModel({ config, model: anthropic, redis, client }),
|
|
55
56
|
};
|
|
56
57
|
```
|
|
57
58
|
|
|
@@ -121,17 +122,25 @@ export const searchTool: ToolDefinition<"Search", typeof searchSchema> = {
|
|
|
121
122
|
|
|
122
123
|
```typescript
|
|
123
124
|
import type Redis from "ioredis";
|
|
125
|
+
import type { WorkflowClient } from "@temporalio/client";
|
|
124
126
|
import { ChatAnthropic } from "@langchain/anthropic";
|
|
125
|
-
import { invokeModel } from "zeitlich";
|
|
126
|
-
|
|
127
|
-
export const createActivities = (
|
|
127
|
+
import { invokeModel, type InvokeModelConfig } from "zeitlich";
|
|
128
|
+
|
|
129
|
+
export const createActivities = ({
|
|
130
|
+
redis,
|
|
131
|
+
client,
|
|
132
|
+
}: {
|
|
133
|
+
redis: Redis;
|
|
134
|
+
client: WorkflowClient;
|
|
135
|
+
}) => {
|
|
128
136
|
const model = new ChatAnthropic({
|
|
129
137
|
model: "claude-sonnet-4-20250514",
|
|
130
138
|
maxTokens: 4096,
|
|
131
139
|
});
|
|
132
140
|
|
|
133
141
|
return {
|
|
134
|
-
runAgent: (config) =>
|
|
142
|
+
runAgent: (config: InvokeModelConfig) =>
|
|
143
|
+
invokeModel({ config, model, redis, client }),
|
|
135
144
|
|
|
136
145
|
handleSearchResult: async ({ args }) => {
|
|
137
146
|
const results = await performSearch(args.query);
|
|
@@ -147,12 +156,24 @@ export type MyActivities = ReturnType<typeof createActivities>;
|
|
|
147
156
|
|
|
148
157
|
```typescript
|
|
149
158
|
import { proxyActivities, workflowInfo } from "@temporalio/workflow";
|
|
150
|
-
import {
|
|
159
|
+
import {
|
|
160
|
+
createAgentStateManager,
|
|
161
|
+
createSession,
|
|
162
|
+
defineTool,
|
|
163
|
+
proxyDefaultThreadOps,
|
|
164
|
+
} from "zeitlich/workflow";
|
|
151
165
|
import { searchTool } from "./tools";
|
|
152
166
|
import type { MyActivities } from "./activities";
|
|
153
167
|
|
|
154
168
|
const { runAgent, handleSearchResult } = proxyActivities<MyActivities>({
|
|
155
169
|
startToCloseTimeout: "30m",
|
|
170
|
+
retry: {
|
|
171
|
+
maximumAttempts: 6,
|
|
172
|
+
initialInterval: "5s",
|
|
173
|
+
maximumInterval: "15m",
|
|
174
|
+
backoffCoefficient: 4,
|
|
175
|
+
},
|
|
176
|
+
heartbeatTimeout: "5m",
|
|
156
177
|
});
|
|
157
178
|
|
|
158
179
|
export async function myAgentWorkflow({ prompt }: { prompt: string }) {
|
|
@@ -164,13 +185,15 @@ export async function myAgentWorkflow({ prompt }: { prompt: string }) {
|
|
|
164
185
|
threadId: runId,
|
|
165
186
|
agentName: "my-agent",
|
|
166
187
|
maxTurns: 20,
|
|
188
|
+
systemPrompt: "You are a helpful assistant.",
|
|
167
189
|
runAgent,
|
|
190
|
+
threadOps: proxyDefaultThreadOps(),
|
|
168
191
|
buildContextMessage: () => [{ type: "text", text: prompt }],
|
|
169
192
|
tools: {
|
|
170
|
-
Search: {
|
|
193
|
+
Search: defineTool({
|
|
171
194
|
...searchTool,
|
|
172
195
|
handler: handleSearchResult,
|
|
173
|
-
},
|
|
196
|
+
}),
|
|
174
197
|
},
|
|
175
198
|
});
|
|
176
199
|
|
|
@@ -183,6 +206,7 @@ export async function myAgentWorkflow({ prompt }: { prompt: string }) {
|
|
|
183
206
|
|
|
184
207
|
```typescript
|
|
185
208
|
import { Worker, NativeConnection } from "@temporalio/worker";
|
|
209
|
+
import { Client } from "@temporalio/client";
|
|
186
210
|
import { ZeitlichPlugin } from "zeitlich";
|
|
187
211
|
import Redis from "ioredis";
|
|
188
212
|
import { createActivities } from "./activities";
|
|
@@ -191,6 +215,7 @@ async function run() {
|
|
|
191
215
|
const connection = await NativeConnection.connect({
|
|
192
216
|
address: "localhost:7233",
|
|
193
217
|
});
|
|
218
|
+
const client = new Client({ connection });
|
|
194
219
|
const redis = new Redis({ host: "localhost", port: 6379 });
|
|
195
220
|
|
|
196
221
|
const worker = await Worker.create({
|
|
@@ -198,7 +223,7 @@ async function run() {
|
|
|
198
223
|
connection,
|
|
199
224
|
taskQueue: "my-agent",
|
|
200
225
|
workflowsPath: require.resolve("./workflows"),
|
|
201
|
-
activities: createActivities(redis),
|
|
226
|
+
activities: createActivities({ redis, client: client.workflow }),
|
|
202
227
|
});
|
|
203
228
|
|
|
204
229
|
await worker.run();
|
|
@@ -242,14 +267,14 @@ const searchTool: ToolDefinition<"Search", typeof searchSchema> = {
|
|
|
242
267
|
schema: z.object({ query: z.string() }),
|
|
243
268
|
};
|
|
244
269
|
|
|
245
|
-
// In workflow - combine tool definition with handler
|
|
270
|
+
// In workflow - combine tool definition with handler using defineTool()
|
|
246
271
|
const session = await createSession({
|
|
247
272
|
// ... other config
|
|
248
273
|
tools: {
|
|
249
|
-
Search: {
|
|
274
|
+
Search: defineTool({
|
|
250
275
|
...searchTool,
|
|
251
276
|
handler: handleSearchResult, // Activity that implements the tool
|
|
252
|
-
},
|
|
277
|
+
}),
|
|
253
278
|
},
|
|
254
279
|
});
|
|
255
280
|
```
|
|
@@ -288,20 +313,17 @@ const session = await createSession({
|
|
|
288
313
|
Spawn child agents as Temporal child workflows:
|
|
289
314
|
|
|
290
315
|
```typescript
|
|
316
|
+
// Define subagent workflows (each is a Temporal workflow that returns string | null)
|
|
317
|
+
export const researcherSubagent = {
|
|
318
|
+
name: "researcher",
|
|
319
|
+
description: "Researches topics and returns findings",
|
|
320
|
+
workflow: researcherWorkflow,
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// In the main agent workflow
|
|
291
324
|
const session = await createSession({
|
|
292
325
|
// ... other config
|
|
293
|
-
subagents: [
|
|
294
|
-
{
|
|
295
|
-
name: "researcher",
|
|
296
|
-
description: "Researches topics and returns findings",
|
|
297
|
-
workflow: "researcherWorkflow",
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
name: "code-reviewer",
|
|
301
|
-
description: "Reviews code for quality and best practices",
|
|
302
|
-
workflow: "codeReviewerWorkflow",
|
|
303
|
-
},
|
|
304
|
-
],
|
|
326
|
+
subagents: [researcherSubagent, codeReviewerSubagent],
|
|
305
327
|
});
|
|
306
328
|
```
|
|
307
329
|
|
|
@@ -327,18 +349,26 @@ const session = await createSession({
|
|
|
327
349
|
});
|
|
328
350
|
```
|
|
329
351
|
|
|
330
|
-
For more advanced file operations, use the built-in tool
|
|
352
|
+
For more advanced file operations, use the built-in tool handler factories:
|
|
331
353
|
|
|
332
354
|
```typescript
|
|
333
|
-
import {
|
|
355
|
+
import { createGlobHandler, createEditHandler, toTree } from "zeitlich";
|
|
334
356
|
|
|
335
357
|
export const createActivities = () => ({
|
|
336
358
|
generateFileTree: () => toTree("/workspace"),
|
|
337
|
-
|
|
338
|
-
|
|
359
|
+
globHandlerActivity: createGlobHandler("/workspace"),
|
|
360
|
+
editHandlerActivity: createEditHandler("/workspace"),
|
|
339
361
|
});
|
|
340
362
|
```
|
|
341
363
|
|
|
364
|
+
`toTree` also accepts an in-memory filesystem object (e.g. from [`just-bash`](https://github.com/nicholasgasior/just-bash)):
|
|
365
|
+
|
|
366
|
+
```typescript
|
|
367
|
+
import { toTree } from "zeitlich";
|
|
368
|
+
|
|
369
|
+
const fileTree = toTree(inMemoryFileSystem);
|
|
370
|
+
```
|
|
371
|
+
|
|
342
372
|
### Built-in Tools
|
|
343
373
|
|
|
344
374
|
Zeitlich provides ready-to-use tool definitions and handlers for common agent operations.
|
|
@@ -366,12 +396,12 @@ import {
|
|
|
366
396
|
askUserQuestionTool,
|
|
367
397
|
} from "zeitlich/workflow";
|
|
368
398
|
|
|
369
|
-
// Import
|
|
399
|
+
// Import handler factories in activities
|
|
370
400
|
import {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
401
|
+
createEditHandler,
|
|
402
|
+
createGlobHandler,
|
|
403
|
+
createBashHandler,
|
|
404
|
+
createAskUserQuestionHandler,
|
|
375
405
|
} from "zeitlich";
|
|
376
406
|
```
|
|
377
407
|
|
|
@@ -381,14 +411,14 @@ All tools are passed via `tools`. The Bash tool's description is automatically e
|
|
|
381
411
|
const session = await createSession({
|
|
382
412
|
// ... other config
|
|
383
413
|
tools: {
|
|
384
|
-
AskUserQuestion: {
|
|
414
|
+
AskUserQuestion: defineTool({
|
|
385
415
|
...askUserQuestionTool,
|
|
386
|
-
handler:
|
|
387
|
-
},
|
|
388
|
-
Bash: {
|
|
416
|
+
handler: askUserQuestionHandlerActivity,
|
|
417
|
+
}),
|
|
418
|
+
Bash: defineTool({
|
|
389
419
|
...bashTool,
|
|
390
|
-
handler:
|
|
391
|
-
},
|
|
420
|
+
handler: bashHandlerActivity,
|
|
421
|
+
}),
|
|
392
422
|
},
|
|
393
423
|
});
|
|
394
424
|
```
|
|
@@ -419,7 +449,7 @@ For use in activities, worker setup, and Node.js code:
|
|
|
419
449
|
| `createSharedActivities` | Creates thread management activities |
|
|
420
450
|
| `invokeModel` | Core LLM invocation utility (requires Redis + LangChain) |
|
|
421
451
|
| `toTree` | Generate file tree string from a directory path |
|
|
422
|
-
| Tool handlers | `
|
|
452
|
+
| Tool handlers | `createGlobHandler`, `createEditHandler`, `createBashHandler`, `createAskUserQuestionHandler` |
|
|
423
453
|
|
|
424
454
|
### Types
|
|
425
455
|
|
package/dist/index.cjs
CHANGED
|
@@ -14,38 +14,38 @@ var z3__default = /*#__PURE__*/_interopDefault(z3);
|
|
|
14
14
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
15
15
|
|
|
16
16
|
// src/lib/session.ts
|
|
17
|
-
var
|
|
18
|
-
function
|
|
19
|
-
const subagentList = subagents.map((s) => `- **${s.
|
|
20
|
-
return `Launch a new agent to handle complex
|
|
17
|
+
var SUBAGENT_TOOL = "Subagent";
|
|
18
|
+
function buildSubagentDescription(subagents) {
|
|
19
|
+
const subagentList = subagents.map((s) => `- **${s.agentName}**: ${s.description}`).join("\n");
|
|
20
|
+
return `Launch a new agent to handle complex tasks autonomously.
|
|
21
21
|
|
|
22
|
-
The ${
|
|
22
|
+
The ${SUBAGENT_TOOL} tool launches specialized agents (subprocesses) that autonomously handle complex tasks. Each agent type has specific capabilities and tools available to it.
|
|
23
23
|
|
|
24
24
|
Available agent types:
|
|
25
25
|
|
|
26
26
|
${subagentList}
|
|
27
27
|
|
|
28
|
-
When using the ${
|
|
28
|
+
When using the ${SUBAGENT_TOOL} tool, you must specify a subagent parameter to select which agent type to use.
|
|
29
29
|
|
|
30
30
|
Usage notes:
|
|
31
31
|
|
|
32
32
|
- Always include a short description (3-5 words) summarizing what the agent will do
|
|
33
33
|
- Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
|
|
34
|
-
- When the agent is done, it will return a single message back to you.
|
|
34
|
+
- When the agent is done, it will return a single message back to you.
|
|
35
35
|
- Each invocation starts fresh - provide a detailed task description with all necessary context.
|
|
36
36
|
- Provide clear, detailed prompts so the agent can work autonomously and return exactly the information you need.
|
|
37
37
|
- The agent's outputs should generally be trusted
|
|
38
38
|
- Clearly tell the agent what type of work you expect since it is not aware of the user's intent
|
|
39
39
|
- If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.`;
|
|
40
40
|
}
|
|
41
|
-
function
|
|
41
|
+
function createSubagentTool(subagents) {
|
|
42
42
|
if (subagents.length === 0) {
|
|
43
43
|
throw new Error("createTaskTool requires at least one subagent");
|
|
44
44
|
}
|
|
45
|
-
const names = subagents.map((s) => s.
|
|
45
|
+
const names = subagents.map((s) => s.agentName);
|
|
46
46
|
return {
|
|
47
|
-
name:
|
|
48
|
-
description:
|
|
47
|
+
name: SUBAGENT_TOOL,
|
|
48
|
+
description: buildSubagentDescription(subagents),
|
|
49
49
|
schema: z3__default.default.object({
|
|
50
50
|
subagent: z3__default.default.enum(names).describe("The type of subagent to launch"),
|
|
51
51
|
description: z3__default.default.string().describe("A short (3-5 word) description of the task"),
|
|
@@ -53,16 +53,16 @@ function createTaskTool(subagents) {
|
|
|
53
53
|
})
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
const {
|
|
56
|
+
function createSubagentHandler(subagents) {
|
|
57
|
+
const { taskQueue: parentTaskQueue } = workflow.workflowInfo();
|
|
58
58
|
return async (args) => {
|
|
59
|
-
const config = subagents.find((s) => s.
|
|
59
|
+
const config = subagents.find((s) => s.agentName === args.subagent);
|
|
60
60
|
if (!config) {
|
|
61
61
|
throw new Error(
|
|
62
|
-
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.
|
|
62
|
+
`Unknown subagent: ${args.subagent}. Available: ${subagents.map((s) => s.agentName).join(", ")}`
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
|
-
const childWorkflowId = `${
|
|
65
|
+
const childWorkflowId = `${args.subagent}-${workflow.uuid4()}`;
|
|
66
66
|
const input = {
|
|
67
67
|
prompt: args.prompt,
|
|
68
68
|
...config.context && { context: config.context }
|
|
@@ -72,15 +72,11 @@ function createTaskHandler(subagents) {
|
|
|
72
72
|
args: [input],
|
|
73
73
|
taskQueue: config.taskQueue ?? parentTaskQueue
|
|
74
74
|
};
|
|
75
|
-
const
|
|
76
|
-
const validated = config.resultSchema ? config.resultSchema.parse(
|
|
77
|
-
const toolResponse = typeof validated === "string" ? validated : JSON.stringify(validated, null, 2);
|
|
75
|
+
const { toolResponse, data } = typeof config.workflow === "string" ? await workflow.executeChild(config.workflow, childOpts) : await workflow.executeChild(config.workflow, childOpts);
|
|
76
|
+
const validated = config.resultSchema ? config.resultSchema.parse(data) : null;
|
|
78
77
|
return {
|
|
79
78
|
toolResponse,
|
|
80
|
-
data:
|
|
81
|
-
result: validated,
|
|
82
|
-
childWorkflowId
|
|
83
|
-
}
|
|
79
|
+
data: validated
|
|
84
80
|
};
|
|
85
81
|
};
|
|
86
82
|
}
|
|
@@ -94,31 +90,36 @@ function createToolRouter(options) {
|
|
|
94
90
|
}
|
|
95
91
|
const isEnabled = (tool) => tool.enabled !== false;
|
|
96
92
|
if (options.subagents) {
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
93
|
+
const enabledSubagents = options.subagents.filter(
|
|
94
|
+
(s) => s.enabled !== false
|
|
95
|
+
);
|
|
96
|
+
if (enabledSubagents.length > 0) {
|
|
97
|
+
const subagentHooksMap = /* @__PURE__ */ new Map();
|
|
98
|
+
for (const s of enabledSubagents) {
|
|
99
|
+
if (s.hooks) subagentHooksMap.set(s.agentName, s.hooks);
|
|
100
|
+
}
|
|
101
|
+
const resolveSubagentName = (args) => args.subagent;
|
|
102
|
+
toolMap.set("Subagent", {
|
|
103
|
+
...createSubagentTool(enabledSubagents),
|
|
104
|
+
handler: createSubagentHandler(enabledSubagents),
|
|
105
|
+
...subagentHooksMap.size > 0 && {
|
|
106
|
+
hooks: {
|
|
107
|
+
onPreToolUse: async (ctx) => {
|
|
108
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
109
|
+
return hooks?.onPreExecution?.(ctx) ?? {};
|
|
110
|
+
},
|
|
111
|
+
onPostToolUse: async (ctx) => {
|
|
112
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
113
|
+
await hooks?.onPostExecution?.(ctx);
|
|
114
|
+
},
|
|
115
|
+
onPostToolUseFailure: async (ctx) => {
|
|
116
|
+
const hooks = subagentHooksMap.get(resolveSubagentName(ctx.args));
|
|
117
|
+
return hooks?.onExecutionFailure?.(ctx) ?? {};
|
|
118
|
+
}
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
122
123
|
}
|
|
123
124
|
async function processToolCall(toolCall, turn, handlerContext) {
|
|
124
125
|
const startTime = Date.now();
|
|
@@ -389,7 +390,11 @@ function withAutoAppend(threadHandler, handler) {
|
|
|
389
390
|
toolName,
|
|
390
391
|
content: response.toolResponse
|
|
391
392
|
});
|
|
392
|
-
return {
|
|
393
|
+
return {
|
|
394
|
+
toolResponse: "Response appended via withAutoAppend",
|
|
395
|
+
data: response.data,
|
|
396
|
+
resultAppended: true
|
|
397
|
+
};
|
|
393
398
|
};
|
|
394
399
|
}
|
|
395
400
|
function defineTool(tool) {
|
|
@@ -414,11 +419,19 @@ var createSession = async ({
|
|
|
414
419
|
subagents,
|
|
415
420
|
tools = {},
|
|
416
421
|
processToolsInParallel = true,
|
|
417
|
-
hooks = {}
|
|
422
|
+
hooks = {},
|
|
423
|
+
appendSystemPrompt = true,
|
|
424
|
+
systemPrompt
|
|
418
425
|
}) => {
|
|
426
|
+
const {
|
|
427
|
+
appendToolResult,
|
|
428
|
+
appendHumanMessage,
|
|
429
|
+
initializeThread,
|
|
430
|
+
appendSystemMessage
|
|
431
|
+
} = threadOps ?? proxyDefaultThreadOps();
|
|
419
432
|
const toolRouter = createToolRouter({
|
|
420
433
|
tools,
|
|
421
|
-
appendToolResult
|
|
434
|
+
appendToolResult,
|
|
422
435
|
threadId,
|
|
423
436
|
hooks,
|
|
424
437
|
subagents,
|
|
@@ -445,35 +458,32 @@ var createSession = async ({
|
|
|
445
458
|
});
|
|
446
459
|
}
|
|
447
460
|
stateManager.setTools(toolRouter.getToolDefinitions());
|
|
448
|
-
await
|
|
449
|
-
|
|
461
|
+
await initializeThread(threadId);
|
|
462
|
+
if (appendSystemPrompt && systemPrompt && systemPrompt.trim() !== "") {
|
|
463
|
+
await appendSystemMessage(threadId, systemPrompt);
|
|
464
|
+
}
|
|
465
|
+
await appendHumanMessage(threadId, await buildContextMessage());
|
|
450
466
|
let exitReason = "completed";
|
|
451
467
|
try {
|
|
452
468
|
while (stateManager.isRunning() && !stateManager.isTerminal() && stateManager.getTurns() < maxTurns) {
|
|
453
469
|
stateManager.incrementTurns();
|
|
454
470
|
const currentTurn = stateManager.getTurns();
|
|
455
|
-
const { message,
|
|
471
|
+
const { message, rawToolCalls } = await runAgent({
|
|
456
472
|
threadId,
|
|
457
473
|
agentName,
|
|
458
474
|
metadata
|
|
459
475
|
});
|
|
460
|
-
if (
|
|
461
|
-
stateManager.complete();
|
|
462
|
-
exitReason = "completed";
|
|
463
|
-
return message;
|
|
464
|
-
}
|
|
465
|
-
if (!toolRouter.hasTools()) {
|
|
476
|
+
if (!toolRouter.hasTools() || rawToolCalls.length === 0) {
|
|
466
477
|
stateManager.complete();
|
|
467
478
|
exitReason = "completed";
|
|
468
479
|
return message;
|
|
469
480
|
}
|
|
470
|
-
const rawToolCalls = await threadOps.parseToolCalls(message);
|
|
471
481
|
const parsedToolCalls = [];
|
|
472
482
|
for (const tc of rawToolCalls) {
|
|
473
483
|
try {
|
|
474
484
|
parsedToolCalls.push(toolRouter.parseToolCall(tc));
|
|
475
485
|
} catch (error) {
|
|
476
|
-
await
|
|
486
|
+
await appendToolResult({
|
|
477
487
|
threadId,
|
|
478
488
|
toolCallId: tc.id ?? "",
|
|
479
489
|
toolName: tc.name,
|
|
@@ -521,7 +531,7 @@ function proxyDefaultThreadOps(options) {
|
|
|
521
531
|
initializeThread: activities.initializeThread,
|
|
522
532
|
appendHumanMessage: activities.appendHumanMessage,
|
|
523
533
|
appendToolResult: activities.appendToolResult,
|
|
524
|
-
|
|
534
|
+
appendSystemMessage: activities.appendSystemMessage
|
|
525
535
|
};
|
|
526
536
|
}
|
|
527
537
|
|
|
@@ -1100,6 +1110,8 @@ function createThreadManager(config) {
|
|
|
1100
1110
|
};
|
|
1101
1111
|
return Object.assign(base, helpers);
|
|
1102
1112
|
}
|
|
1113
|
+
|
|
1114
|
+
// src/activities.ts
|
|
1103
1115
|
function createSharedActivities(redis) {
|
|
1104
1116
|
return {
|
|
1105
1117
|
async appendToolResult(config) {
|
|
@@ -1119,14 +1131,9 @@ function createSharedActivities(redis) {
|
|
|
1119
1131
|
const thread = createThreadManager({ redis, threadId });
|
|
1120
1132
|
await thread.appendHumanMessage(content);
|
|
1121
1133
|
},
|
|
1122
|
-
async
|
|
1123
|
-
const
|
|
1124
|
-
|
|
1125
|
-
return toolCalls.map((toolCall) => ({
|
|
1126
|
-
id: toolCall.id,
|
|
1127
|
-
name: toolCall.name,
|
|
1128
|
-
args: toolCall.args
|
|
1129
|
-
}));
|
|
1134
|
+
async appendSystemMessage(threadId, content) {
|
|
1135
|
+
const thread = createThreadManager({ redis, threadId });
|
|
1136
|
+
await thread.appendSystemMessage(content);
|
|
1130
1137
|
}
|
|
1131
1138
|
};
|
|
1132
1139
|
}
|
|
@@ -1164,9 +1171,14 @@ async function invokeModel({
|
|
|
1164
1171
|
}
|
|
1165
1172
|
);
|
|
1166
1173
|
await thread.append([response.toDict()]);
|
|
1174
|
+
const toolCalls = response.tool_calls ?? [];
|
|
1167
1175
|
return {
|
|
1168
1176
|
message: response.toDict(),
|
|
1169
|
-
|
|
1177
|
+
rawToolCalls: toolCalls.map((tc) => ({
|
|
1178
|
+
id: tc.id,
|
|
1179
|
+
name: tc.name,
|
|
1180
|
+
args: tc.args
|
|
1181
|
+
})),
|
|
1170
1182
|
usage: {
|
|
1171
1183
|
input_tokens: response.usage_metadata?.input_tokens,
|
|
1172
1184
|
output_tokens: response.usage_metadata?.output_tokens,
|
|
@@ -1368,10 +1380,10 @@ exports.createEditHandler = createEditHandler;
|
|
|
1368
1380
|
exports.createGlobHandler = createGlobHandler;
|
|
1369
1381
|
exports.createSession = createSession;
|
|
1370
1382
|
exports.createSharedActivities = createSharedActivities;
|
|
1383
|
+
exports.createSubagentTool = createSubagentTool;
|
|
1371
1384
|
exports.createTaskCreateHandler = createTaskCreateHandler;
|
|
1372
1385
|
exports.createTaskGetHandler = createTaskGetHandler;
|
|
1373
1386
|
exports.createTaskListHandler = createTaskListHandler;
|
|
1374
|
-
exports.createTaskTool = createTaskTool;
|
|
1375
1387
|
exports.createTaskUpdateHandler = createTaskUpdateHandler;
|
|
1376
1388
|
exports.createThreadManager = createThreadManager;
|
|
1377
1389
|
exports.createToolRouter = createToolRouter;
|