zeitlich 0.2.1 → 0.2.3
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 +36 -33
- package/dist/index.cjs +445 -385
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -42
- package/dist/index.d.ts +25 -42
- package/dist/index.js +415 -362
- package/dist/index.js.map +1 -1
- package/dist/{workflow-CCoHnc3B.d.cts → workflow-D-2vp4Pq.d.cts} +456 -253
- package/dist/{workflow-CCoHnc3B.d.ts → workflow-D-2vp4Pq.d.ts} +456 -253
- package/dist/workflow.cjs +339 -272
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +4 -3
- package/dist/workflow.d.ts +4 -3
- package/dist/workflow.js +315 -252
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -2
- package/src/activities.ts +1 -14
- package/src/index.ts +17 -11
- package/src/lib/session.ts +69 -86
- package/src/lib/state-manager.ts +9 -2
- package/src/lib/thread-manager.ts +45 -37
- package/src/lib/tool-router.ts +338 -116
- package/src/lib/types.ts +110 -28
- package/src/tools/ask-user-question/handler.ts +6 -6
- package/src/tools/ask-user-question/tool.ts +3 -2
- package/src/tools/bash/bash.test.ts +32 -32
- package/src/tools/bash/handler.ts +9 -9
- package/src/tools/bash/tool.ts +3 -2
- package/src/tools/edit/handler.ts +78 -123
- package/src/tools/edit/tool.ts +3 -2
- package/src/tools/glob/handler.ts +17 -48
- package/src/tools/glob/tool.ts +3 -2
- package/src/tools/grep/tool.ts +3 -2
- package/src/tools/{read → read-file}/tool.ts +3 -2
- package/src/tools/task/handler.ts +19 -9
- package/src/tools/task/tool.ts +3 -10
- package/src/tools/task-create/handler.ts +11 -20
- package/src/tools/task-create/tool.ts +3 -2
- package/src/tools/task-get/handler.ts +9 -14
- package/src/tools/task-get/tool.ts +3 -2
- package/src/tools/task-list/handler.ts +7 -12
- package/src/tools/task-list/tool.ts +3 -2
- package/src/tools/task-update/handler.ts +9 -16
- package/src/tools/task-update/tool.ts +3 -2
- package/src/tools/{write → write-file}/tool.ts +5 -6
- package/src/workflow.ts +25 -19
|
@@ -1,38 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ActivityToolHandler } from "../../lib/tool-router";
|
|
2
|
+
import type { FileEditArgs } from "./tool";
|
|
2
3
|
import type { IFileSystem } from "just-bash";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Result of an edit operation
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
interface EditResult {
|
|
8
9
|
path: string;
|
|
9
10
|
success: boolean;
|
|
10
11
|
replacements: number;
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* Edit handler response
|
|
15
|
-
*/
|
|
16
|
-
export interface EditHandlerResponse {
|
|
17
|
-
content: string;
|
|
18
|
-
result: EditResult;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Options for edit handler
|
|
23
|
-
*/
|
|
24
|
-
export interface EditHandlerOptions {
|
|
25
|
-
/**
|
|
26
|
-
* Set of file paths that have been read in this session.
|
|
27
|
-
* Required for enforcing read-before-write policy.
|
|
28
|
-
*/
|
|
29
|
-
readFiles: Set<string>;
|
|
30
|
-
/**
|
|
31
|
-
* If true, skip the read-before-write check (not recommended)
|
|
32
|
-
*/
|
|
33
|
-
skipReadCheck?: boolean;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
14
|
/**
|
|
37
15
|
* Escape special regex characters in a string
|
|
38
16
|
*/
|
|
@@ -41,116 +19,93 @@ function escapeRegExp(str: string): string {
|
|
|
41
19
|
}
|
|
42
20
|
|
|
43
21
|
/**
|
|
44
|
-
*
|
|
22
|
+
* Creates an edit handler that edits files within the scoped file tree.
|
|
45
23
|
*
|
|
46
|
-
* @param
|
|
47
|
-
* @
|
|
24
|
+
* @param fs - File system implementation for I/O operations
|
|
25
|
+
* @returns An ActivityToolHandler for edit tool calls
|
|
48
26
|
*/
|
|
49
|
-
export
|
|
50
|
-
args: EditToolSchemaType,
|
|
27
|
+
export function createEditHandler(
|
|
51
28
|
fs: IFileSystem
|
|
52
|
-
):
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// Validate old_string !== new_string
|
|
56
|
-
if (old_string === new_string) {
|
|
57
|
-
return {
|
|
58
|
-
content: `Error: old_string and new_string must be different.`,
|
|
59
|
-
result: {
|
|
60
|
-
path: file_path,
|
|
61
|
-
success: false,
|
|
62
|
-
replacements: 0,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
29
|
+
): ActivityToolHandler<FileEditArgs, EditResult> {
|
|
30
|
+
return async (args) => {
|
|
31
|
+
const { file_path, old_string, new_string, replace_all = false } = args;
|
|
66
32
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
const exists = await fs.exists(file_path);
|
|
70
|
-
if (!exists) {
|
|
33
|
+
// Validate old_string !== new_string
|
|
34
|
+
if (old_string === new_string) {
|
|
71
35
|
return {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
path: file_path,
|
|
75
|
-
success: false,
|
|
76
|
-
replacements: 0,
|
|
77
|
-
},
|
|
36
|
+
toolResponse: `Error: old_string and new_string must be different.`,
|
|
37
|
+
data: { path: file_path, success: false, replacements: 0 },
|
|
78
38
|
};
|
|
79
39
|
}
|
|
80
40
|
|
|
81
|
-
|
|
82
|
-
|
|
41
|
+
try {
|
|
42
|
+
// Check if file exists
|
|
43
|
+
const exists = await fs.exists(file_path);
|
|
44
|
+
if (!exists) {
|
|
45
|
+
return {
|
|
46
|
+
toolResponse: `Error: File "${file_path}" does not exist.`,
|
|
47
|
+
data: { path: file_path, success: false, replacements: 0 },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Read current content
|
|
52
|
+
const content = await fs.readFile(file_path);
|
|
53
|
+
|
|
54
|
+
// Check if old_string exists in the file
|
|
55
|
+
if (!content.includes(old_string)) {
|
|
56
|
+
return {
|
|
57
|
+
toolResponse: `Error: Could not find the specified text in "${file_path}". Make sure old_string matches exactly (whitespace-sensitive).`,
|
|
58
|
+
data: { path: file_path, success: false, replacements: 0 },
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Count occurrences
|
|
63
|
+
const escapedOldString = escapeRegExp(old_string);
|
|
64
|
+
const globalRegex = new RegExp(escapedOldString, "g");
|
|
65
|
+
const occurrences = (content.match(globalRegex) || []).length;
|
|
66
|
+
|
|
67
|
+
// Check uniqueness if not replace_all
|
|
68
|
+
if (!replace_all && occurrences > 1) {
|
|
69
|
+
return {
|
|
70
|
+
toolResponse: `Error: old_string appears ${occurrences} times in "${file_path}". Either provide more context to make it unique, or use replace_all: true.`,
|
|
71
|
+
data: { path: file_path, success: false, replacements: 0 },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Perform replacement
|
|
76
|
+
let newContent: string;
|
|
77
|
+
let replacements: number;
|
|
78
|
+
|
|
79
|
+
if (replace_all) {
|
|
80
|
+
newContent = content.split(old_string).join(new_string);
|
|
81
|
+
replacements = occurrences;
|
|
82
|
+
} else {
|
|
83
|
+
// Replace only the first occurrence
|
|
84
|
+
const index = content.indexOf(old_string);
|
|
85
|
+
newContent =
|
|
86
|
+
content.slice(0, index) +
|
|
87
|
+
new_string +
|
|
88
|
+
content.slice(index + old_string.length);
|
|
89
|
+
replacements = 1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Write the modified content
|
|
93
|
+
await fs.writeFile(file_path, newContent);
|
|
94
|
+
|
|
95
|
+
const summary = replace_all
|
|
96
|
+
? `Replaced ${replacements} occurrence(s)`
|
|
97
|
+
: `Replaced 1 occurrence`;
|
|
83
98
|
|
|
84
|
-
// Check if old_string exists in the file
|
|
85
|
-
if (!content.includes(old_string)) {
|
|
86
99
|
return {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
path: file_path,
|
|
90
|
-
success: false,
|
|
91
|
-
replacements: 0,
|
|
92
|
-
},
|
|
100
|
+
toolResponse: `${summary} in ${file_path}`,
|
|
101
|
+
data: { path: file_path, success: true, replacements },
|
|
93
102
|
};
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Count occurrences
|
|
97
|
-
const escapedOldString = escapeRegExp(old_string);
|
|
98
|
-
const globalRegex = new RegExp(escapedOldString, "g");
|
|
99
|
-
const occurrences = (content.match(globalRegex) || []).length;
|
|
100
|
-
|
|
101
|
-
// Check uniqueness if not replace_all
|
|
102
|
-
if (!replace_all && occurrences > 1) {
|
|
103
|
+
} catch (error) {
|
|
104
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
103
105
|
return {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
path: file_path,
|
|
107
|
-
success: false,
|
|
108
|
-
replacements: 0,
|
|
109
|
-
},
|
|
106
|
+
toolResponse: `Error editing file "${file_path}": ${message}`,
|
|
107
|
+
data: { path: file_path, success: false, replacements: 0 },
|
|
110
108
|
};
|
|
111
109
|
}
|
|
112
|
-
|
|
113
|
-
// Perform replacement
|
|
114
|
-
let newContent: string;
|
|
115
|
-
let replacements: number;
|
|
116
|
-
|
|
117
|
-
if (replace_all) {
|
|
118
|
-
newContent = content.split(old_string).join(new_string);
|
|
119
|
-
replacements = occurrences;
|
|
120
|
-
} else {
|
|
121
|
-
// Replace only the first occurrence
|
|
122
|
-
const index = content.indexOf(old_string);
|
|
123
|
-
newContent =
|
|
124
|
-
content.slice(0, index) +
|
|
125
|
-
new_string +
|
|
126
|
-
content.slice(index + old_string.length);
|
|
127
|
-
replacements = 1;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Write the modified content
|
|
131
|
-
await fs.writeFile(file_path, newContent);
|
|
132
|
-
|
|
133
|
-
const summary = replace_all
|
|
134
|
-
? `Replaced ${replacements} occurrence(s)`
|
|
135
|
-
: `Replaced 1 occurrence`;
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
content: `${summary} in ${file_path}`,
|
|
139
|
-
result: {
|
|
140
|
-
path: file_path,
|
|
141
|
-
success: true,
|
|
142
|
-
replacements,
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
} catch (error) {
|
|
146
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
147
|
-
return {
|
|
148
|
-
content: `Error editing file "${file_path}": ${message}`,
|
|
149
|
-
result: {
|
|
150
|
-
path: file_path,
|
|
151
|
-
success: false,
|
|
152
|
-
replacements: 0,
|
|
153
|
-
},
|
|
154
|
-
};
|
|
155
|
-
}
|
|
110
|
+
};
|
|
156
111
|
}
|
package/src/tools/edit/tool.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const editTool = {
|
|
4
5
|
name: "FileEdit" as const,
|
|
@@ -34,6 +35,6 @@ IMPORTANT:
|
|
|
34
35
|
),
|
|
35
36
|
}),
|
|
36
37
|
strict: true,
|
|
37
|
-
};
|
|
38
|
+
} satisfies ToolDefinition;
|
|
38
39
|
|
|
39
|
-
export type
|
|
40
|
+
export type FileEditArgs = z.infer<typeof editTool.schema>;
|
|
@@ -1,62 +1,31 @@
|
|
|
1
|
+
import type { ActivityToolHandler } from "../../lib/tool-router";
|
|
2
|
+
import type { GlobArgs } from "./tool";
|
|
1
3
|
import type { IFileSystem } from "just-bash";
|
|
2
4
|
import { Bash } from "just-bash";
|
|
3
|
-
import type { GlobToolSchemaType } from "./tool";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Result of a glob operation
|
|
7
8
|
*/
|
|
8
|
-
|
|
9
|
+
interface GlobResult {
|
|
9
10
|
files: string[];
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
*
|
|
14
|
-
*/
|
|
15
|
-
export interface GlobHandlerResponse {
|
|
16
|
-
content: string;
|
|
17
|
-
result: GlobResult;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Glob handler that searches within the scoped file tree.
|
|
14
|
+
* Creates a glob handler that searches within the scoped file tree.
|
|
22
15
|
*
|
|
23
|
-
* @param
|
|
24
|
-
* @
|
|
16
|
+
* @param fs - File system implementation for I/O operations
|
|
17
|
+
* @returns An ActivityToolHandler for glob tool calls
|
|
25
18
|
*/
|
|
26
|
-
export
|
|
27
|
-
_args: GlobToolSchemaType,
|
|
19
|
+
export function createGlobHandler(
|
|
28
20
|
fs: IFileSystem
|
|
29
|
-
):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// const matches = await bash.exec(`glob ${root} -name "${pattern}"`);
|
|
40
|
-
|
|
41
|
-
// if (matches.length === 0) {
|
|
42
|
-
// return {
|
|
43
|
-
// content: `No files found matching pattern: ${pattern}`,
|
|
44
|
-
// result: { files: [] },
|
|
45
|
-
// };
|
|
46
|
-
// }
|
|
47
|
-
|
|
48
|
-
// const paths = matches.map((node) => node.path);
|
|
49
|
-
// const fileList = paths.map((p) => ` ${p}`).join("\n");
|
|
50
|
-
|
|
51
|
-
// return {
|
|
52
|
-
// content: `Found ${matches.length} file(s) matching "${pattern}":\n${fileList}`,
|
|
53
|
-
// result: { files: matches },
|
|
54
|
-
// };
|
|
55
|
-
// } catch (error) {
|
|
56
|
-
// const message = error instanceof Error ? error.message : "Unknown error";
|
|
57
|
-
// return {
|
|
58
|
-
// content: `Error searching for files: ${message}`,
|
|
59
|
-
// result: { files: [] },
|
|
60
|
-
// };
|
|
61
|
-
// }
|
|
21
|
+
): ActivityToolHandler<GlobArgs, GlobResult> {
|
|
22
|
+
return async (_args) => {
|
|
23
|
+
// const { pattern, root } = args;
|
|
24
|
+
const _bash = new Bash({ fs });
|
|
25
|
+
|
|
26
|
+
return {
|
|
27
|
+
toolResponse: "Hello, world!",
|
|
28
|
+
data: { files: [] },
|
|
29
|
+
};
|
|
30
|
+
};
|
|
62
31
|
}
|
package/src/tools/glob/tool.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const globTool = {
|
|
4
5
|
name: "Glob" as const,
|
|
@@ -22,6 +23,6 @@ Examples:
|
|
|
22
23
|
.describe("Optional root directory to search from"),
|
|
23
24
|
}),
|
|
24
25
|
strict: true,
|
|
25
|
-
};
|
|
26
|
+
} satisfies ToolDefinition;
|
|
26
27
|
|
|
27
|
-
export type
|
|
28
|
+
export type GlobArgs = z.infer<typeof globTool.schema>;
|
package/src/tools/grep/tool.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const grepTool = {
|
|
4
5
|
name: "Grep" as const,
|
|
@@ -40,6 +41,6 @@ Examples:
|
|
|
40
41
|
.describe("Number of context lines to show around matches"),
|
|
41
42
|
}),
|
|
42
43
|
strict: true,
|
|
43
|
-
};
|
|
44
|
+
} satisfies ToolDefinition;
|
|
44
45
|
|
|
45
|
-
export type
|
|
46
|
+
export type GrepArgs = z.infer<typeof grepTool.schema>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const readTool = {
|
|
4
5
|
name: "FileRead" as const,
|
|
@@ -28,6 +29,6 @@ The tool returns the file content in an appropriate format:
|
|
|
28
29
|
.describe("Maximum number of lines to read (for text files)"),
|
|
29
30
|
}),
|
|
30
31
|
strict: true,
|
|
31
|
-
};
|
|
32
|
+
} satisfies ToolDefinition;
|
|
32
33
|
|
|
33
|
-
export type
|
|
34
|
+
export type FileReadArgs = z.infer<typeof readTool.schema>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { executeChild, workflowInfo, uuid4 } from "@temporalio/workflow";
|
|
2
2
|
import type { ToolHandlerResponse } from "../../lib/tool-router";
|
|
3
3
|
import type { SubagentConfig, SubagentInput } from "../../lib/types";
|
|
4
|
-
import type {
|
|
4
|
+
import type { TaskArgs } from "./tool";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Result from a task handler execution
|
|
@@ -24,7 +24,7 @@ export interface TaskHandlerResult<TResult = unknown> {
|
|
|
24
24
|
* {
|
|
25
25
|
* name: "researcher",
|
|
26
26
|
* description: "Researches topics",
|
|
27
|
-
*
|
|
27
|
+
* workflow: "researcherWorkflow",
|
|
28
28
|
* resultSchema: z.object({ findings: z.string() }),
|
|
29
29
|
* },
|
|
30
30
|
* ]);
|
|
@@ -34,7 +34,7 @@ export function createTaskHandler(subagents: SubagentConfig[]) {
|
|
|
34
34
|
workflowInfo();
|
|
35
35
|
|
|
36
36
|
return async (
|
|
37
|
-
args:
|
|
37
|
+
args: TaskArgs
|
|
38
38
|
): Promise<ToolHandlerResponse<TaskHandlerResult>> => {
|
|
39
39
|
const config = subagents.find((s) => s.name === args.subagent);
|
|
40
40
|
|
|
@@ -47,11 +47,21 @@ export function createTaskHandler(subagents: SubagentConfig[]) {
|
|
|
47
47
|
const childWorkflowId = `${parentWorkflowId}-${args.subagent}-${uuid4()}`;
|
|
48
48
|
|
|
49
49
|
// Execute the child workflow
|
|
50
|
-
const
|
|
50
|
+
const input: SubagentInput = {
|
|
51
|
+
prompt: args.prompt,
|
|
52
|
+
...(config.context && { context: config.context }),
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const childOpts = {
|
|
51
56
|
workflowId: childWorkflowId,
|
|
52
|
-
args: [
|
|
57
|
+
args: [input],
|
|
53
58
|
taskQueue: config.taskQueue ?? parentTaskQueue,
|
|
54
|
-
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const childResult =
|
|
62
|
+
typeof config.workflow === "string"
|
|
63
|
+
? await executeChild(config.workflow, childOpts)
|
|
64
|
+
: await executeChild(config.workflow, childOpts);
|
|
55
65
|
|
|
56
66
|
// Validate result if schema provided, otherwise pass through as-is
|
|
57
67
|
const validated = config.resultSchema
|
|
@@ -59,14 +69,14 @@ export function createTaskHandler(subagents: SubagentConfig[]) {
|
|
|
59
69
|
: childResult;
|
|
60
70
|
|
|
61
71
|
// Format content - stringify objects, pass strings through
|
|
62
|
-
const
|
|
72
|
+
const toolResponse =
|
|
63
73
|
typeof validated === "string"
|
|
64
74
|
? validated
|
|
65
75
|
: JSON.stringify(validated, null, 2);
|
|
66
76
|
|
|
67
77
|
return {
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
toolResponse,
|
|
79
|
+
data: {
|
|
70
80
|
result: validated,
|
|
71
81
|
childWorkflowId,
|
|
72
82
|
},
|
package/src/tools/task/tool.ts
CHANGED
|
@@ -44,7 +44,7 @@ Usage notes:
|
|
|
44
44
|
* {
|
|
45
45
|
* name: "researcher",
|
|
46
46
|
* description: "Researches topics and gathers information",
|
|
47
|
-
*
|
|
47
|
+
* workflow: "researcherWorkflow",
|
|
48
48
|
* resultSchema: z.object({ findings: z.string() }),
|
|
49
49
|
* },
|
|
50
50
|
* ]);
|
|
@@ -80,16 +80,9 @@ export function createTaskTool<T extends SubagentConfig[]>(
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Task tool args type (when subagent names are not known at compile time)
|
|
84
84
|
*/
|
|
85
|
-
export type
|
|
86
|
-
ReturnType<typeof createTaskTool<T>>["schema"]
|
|
87
|
-
>;
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Generic task tool schema type (when subagent names are not known at compile time)
|
|
91
|
-
*/
|
|
92
|
-
export type GenericTaskToolSchemaType = {
|
|
85
|
+
export type TaskArgs = {
|
|
93
86
|
subagent: string;
|
|
94
87
|
description: string;
|
|
95
88
|
prompt: string;
|
|
@@ -2,34 +2,25 @@ import type {
|
|
|
2
2
|
AgentStateManager,
|
|
3
3
|
JsonSerializable,
|
|
4
4
|
} from "../../lib/state-manager";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolHandler } from "../../lib/tool-router";
|
|
6
6
|
import type { WorkflowTask } from "../../lib/types";
|
|
7
|
-
import type {
|
|
7
|
+
import type { TaskCreateArgs } from "./tool";
|
|
8
|
+
import { uuid4 } from "@temporalio/workflow";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Creates a TaskCreate handler that adds tasks to the workflow state.
|
|
11
12
|
*
|
|
12
13
|
* @param stateManager - State manager containing tasks state
|
|
13
|
-
* @
|
|
14
|
-
* @returns A tool handler function
|
|
15
|
-
*
|
|
16
|
-
* @example
|
|
17
|
-
* const handler = createTaskCreateHandler(stateManager, uuid4);
|
|
14
|
+
* @returns A ToolHandler for TaskCreate tool calls
|
|
18
15
|
*/
|
|
19
16
|
export function createTaskCreateHandler<
|
|
20
17
|
TCustom extends JsonSerializable<TCustom>,
|
|
21
|
-
>(
|
|
22
|
-
stateManager
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
stateManager: AgentStateManager<TCustom>;
|
|
26
|
-
idGenerator: () => string;
|
|
27
|
-
}): (args: TaskCreateToolSchemaType) => ToolHandlerResponse<WorkflowTask> {
|
|
28
|
-
return (
|
|
29
|
-
args: TaskCreateToolSchemaType
|
|
30
|
-
): ToolHandlerResponse<WorkflowTask> => {
|
|
18
|
+
>(
|
|
19
|
+
stateManager: AgentStateManager<TCustom>
|
|
20
|
+
): ToolHandler<TaskCreateArgs, WorkflowTask> {
|
|
21
|
+
return (args) => {
|
|
31
22
|
const task: WorkflowTask = {
|
|
32
|
-
id:
|
|
23
|
+
id: uuid4(),
|
|
33
24
|
subject: args.subject,
|
|
34
25
|
description: args.description,
|
|
35
26
|
activeForm: args.activeForm,
|
|
@@ -42,8 +33,8 @@ export function createTaskCreateHandler<
|
|
|
42
33
|
stateManager.setTask(task);
|
|
43
34
|
|
|
44
35
|
return {
|
|
45
|
-
|
|
46
|
-
|
|
36
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
37
|
+
data: task,
|
|
47
38
|
};
|
|
48
39
|
};
|
|
49
40
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const taskCreateTool = {
|
|
4
5
|
name: "TaskCreate" as const,
|
|
@@ -61,6 +62,6 @@ export const taskCreateTool = {
|
|
|
61
62
|
.record(z.string(), z.string())
|
|
62
63
|
.describe("Arbitrary key-value pairs for tracking"),
|
|
63
64
|
}),
|
|
64
|
-
};
|
|
65
|
+
} satisfies ToolDefinition;
|
|
65
66
|
|
|
66
|
-
export type
|
|
67
|
+
export type TaskCreateArgs = z.infer<typeof taskCreateTool.schema>;
|
|
@@ -2,37 +2,32 @@ import type {
|
|
|
2
2
|
AgentStateManager,
|
|
3
3
|
JsonSerializable,
|
|
4
4
|
} from "../../lib/state-manager";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolHandler } from "../../lib/tool-router";
|
|
6
6
|
import type { WorkflowTask } from "../../lib/types";
|
|
7
|
-
import type {
|
|
7
|
+
import type { TaskGetArgs } from "./tool";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Creates a TaskGet handler that retrieves a task by ID.
|
|
11
11
|
*
|
|
12
12
|
* @param stateManager - State manager containing tasks state
|
|
13
|
-
* @returns A tool
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* const handler = createTaskGetHandler(stateManager);
|
|
13
|
+
* @returns A ToolHandler for TaskGet tool calls
|
|
17
14
|
*/
|
|
18
15
|
export function createTaskGetHandler<TCustom extends JsonSerializable<TCustom>>(
|
|
19
16
|
stateManager: AgentStateManager<TCustom>
|
|
20
|
-
):
|
|
21
|
-
return (
|
|
22
|
-
args: TaskGetToolSchemaType
|
|
23
|
-
): ToolHandlerResponse<WorkflowTask | null> => {
|
|
17
|
+
): ToolHandler<TaskGetArgs, WorkflowTask | null> {
|
|
18
|
+
return (args) => {
|
|
24
19
|
const task = stateManager.getTask(args.taskId) ?? null;
|
|
25
20
|
|
|
26
21
|
if (!task) {
|
|
27
22
|
return {
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
toolResponse: JSON.stringify({ error: `Task not found: ${args.taskId}` }),
|
|
24
|
+
data: null,
|
|
30
25
|
};
|
|
31
26
|
}
|
|
32
27
|
|
|
33
28
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
toolResponse: JSON.stringify(task, null, 2),
|
|
30
|
+
data: task,
|
|
36
31
|
};
|
|
37
32
|
};
|
|
38
33
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const taskGetTool = {
|
|
4
5
|
name: "TaskGet" as const,
|
|
@@ -6,6 +7,6 @@ export const taskGetTool = {
|
|
|
6
7
|
schema: z.object({
|
|
7
8
|
taskId: z.string().describe("The ID of the task to get"),
|
|
8
9
|
}),
|
|
9
|
-
};
|
|
10
|
+
} satisfies ToolDefinition;
|
|
10
11
|
|
|
11
|
-
export type
|
|
12
|
+
export type TaskGetArgs = z.infer<typeof taskGetTool.schema>;
|
|
@@ -2,32 +2,27 @@ import type {
|
|
|
2
2
|
AgentStateManager,
|
|
3
3
|
JsonSerializable,
|
|
4
4
|
} from "../../lib/state-manager";
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolHandler } from "../../lib/tool-router";
|
|
6
6
|
import type { WorkflowTask } from "../../lib/types";
|
|
7
|
-
import type {
|
|
7
|
+
import type { TaskListArgs } from "./tool";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Creates a TaskList handler that returns all tasks.
|
|
11
11
|
*
|
|
12
12
|
* @param stateManager - State manager containing tasks state
|
|
13
|
-
* @returns A tool
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* const handler = createTaskListHandler(stateManager);
|
|
13
|
+
* @returns A ToolHandler for TaskList tool calls
|
|
17
14
|
*/
|
|
18
15
|
export function createTaskListHandler<
|
|
19
16
|
TCustom extends JsonSerializable<TCustom>,
|
|
20
17
|
>(
|
|
21
18
|
stateManager: AgentStateManager<TCustom>
|
|
22
|
-
):
|
|
23
|
-
return (
|
|
24
|
-
_args: TaskListToolSchemaType
|
|
25
|
-
): ToolHandlerResponse<WorkflowTask[]> => {
|
|
19
|
+
): ToolHandler<TaskListArgs, WorkflowTask[]> {
|
|
20
|
+
return () => {
|
|
26
21
|
const taskList = stateManager.getTasks();
|
|
27
22
|
|
|
28
23
|
return {
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
toolResponse: JSON.stringify(taskList, null, 2),
|
|
25
|
+
data: taskList,
|
|
31
26
|
};
|
|
32
27
|
};
|
|
33
28
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
+
import type { ToolDefinition } from "../../lib/tool-router";
|
|
2
3
|
|
|
3
4
|
export const taskListTool = {
|
|
4
5
|
name: "TaskList" as const,
|
|
5
6
|
description: `List all tasks with current state.`,
|
|
6
7
|
schema: z.object({}),
|
|
7
|
-
};
|
|
8
|
+
} satisfies ToolDefinition;
|
|
8
9
|
|
|
9
|
-
export type
|
|
10
|
+
export type TaskListArgs = z.infer<typeof taskListTool.schema>;
|