@travisennis/acai 0.0.5 → 0.0.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 +4 -2
- package/dist/agent/index.d.ts +119 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +406 -0
- package/dist/agent/manual-loop.d.ts +41 -0
- package/dist/agent/manual-loop.d.ts.map +1 -0
- package/dist/agent/manual-loop.js +278 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +27 -33
- package/dist/commands/add-directory-command.d.ts +3 -0
- package/dist/commands/add-directory-command.d.ts.map +1 -0
- package/dist/commands/add-directory-command.js +85 -0
- package/dist/commands/application-log-command.d.ts.map +1 -1
- package/dist/commands/application-log-command.js +34 -0
- package/dist/commands/clear-command.d.ts.map +1 -1
- package/dist/commands/clear-command.js +8 -0
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +15 -2
- package/dist/commands/context-command.d.ts +3 -0
- package/dist/commands/context-command.d.ts.map +1 -0
- package/dist/commands/context-command.js +183 -0
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +28 -0
- package/dist/commands/edit-command.d.ts.map +1 -1
- package/dist/commands/edit-command.js +33 -0
- package/dist/commands/edit-prompt-command.d.ts.map +1 -1
- package/dist/commands/edit-prompt-command.js +28 -0
- package/dist/commands/exit-command.d.ts.map +1 -1
- package/dist/commands/exit-command.js +20 -0
- package/dist/commands/files-command.d.ts.map +1 -1
- package/dist/commands/files-command.js +57 -0
- package/dist/commands/generate-rules-command.d.ts.map +1 -1
- package/dist/commands/generate-rules-command.js +311 -1
- package/dist/commands/handoff-command.d.ts +3 -0
- package/dist/commands/handoff-command.d.ts.map +1 -0
- package/dist/commands/handoff-command.js +202 -0
- package/dist/commands/health-command.d.ts.map +1 -1
- package/dist/commands/health-command.js +119 -2
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +28 -0
- package/dist/commands/history-command.d.ts +3 -0
- package/dist/commands/history-command.d.ts.map +1 -0
- package/dist/commands/history-command.js +534 -0
- package/dist/commands/init-command.d.ts +1 -1
- package/dist/commands/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +55 -18
- package/dist/commands/last-log-command.d.ts.map +1 -1
- package/dist/commands/last-log-command.js +27 -0
- package/dist/commands/list-directories-command.d.ts +3 -0
- package/dist/commands/list-directories-command.d.ts.map +1 -0
- package/dist/commands/list-directories-command.js +48 -0
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +66 -3
- package/dist/commands/manager.d.ts +15 -3
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +86 -26
- package/dist/commands/model-command.d.ts +22 -0
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +256 -0
- package/dist/commands/paste-command.d.ts.map +1 -1
- package/dist/commands/paste-command.js +92 -0
- package/dist/commands/pickup-command.d.ts +3 -0
- package/dist/commands/pickup-command.d.ts.map +1 -0
- package/dist/commands/pickup-command.js +161 -0
- package/dist/commands/prompt-command.d.ts +1 -1
- package/dist/commands/prompt-command.d.ts.map +1 -1
- package/dist/commands/prompt-command.js +117 -2
- package/dist/commands/remove-directory-command.d.ts +3 -0
- package/dist/commands/remove-directory-command.d.ts.map +1 -0
- package/dist/commands/remove-directory-command.js +87 -0
- package/dist/commands/reset-command.d.ts +1 -1
- package/dist/commands/reset-command.d.ts.map +1 -1
- package/dist/commands/reset-command.js +13 -2
- package/dist/commands/rules-command.d.ts.map +1 -1
- package/dist/commands/rules-command.js +65 -0
- package/dist/commands/save-command.d.ts.map +1 -1
- package/dist/commands/save-command.js +12 -0
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +68 -0
- package/dist/commands/types.d.ts +9 -4
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/usage-command.d.ts.map +1 -1
- package/dist/commands/usage-command.js +22 -0
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -29
- package/dist/formatting.d.ts +108 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +147 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -38
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +47 -18
- package/dist/mentions.d.ts +2 -1
- package/dist/mentions.d.ts.map +1 -1
- package/dist/mentions.js +16 -1
- package/dist/messages.d.ts +8 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +56 -19
- package/dist/middleware/cache.d.ts +3 -0
- package/dist/middleware/cache.d.ts.map +1 -0
- package/dist/middleware/cache.js +53 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -0
- package/dist/models/ai-config.d.ts +4 -2
- package/dist/models/ai-config.d.ts.map +1 -1
- package/dist/models/ai-config.js +12 -2
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +3 -60
- package/dist/models/manager.d.ts +2 -1
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +26 -2
- package/dist/models/openrouter-provider.d.ts +7 -14
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +114 -169
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +53 -4
- package/dist/repl/display-tool-messages.d.ts +1 -1
- package/dist/repl/display-tool-messages.d.ts.map +1 -1
- package/dist/repl/display-tool-messages.js +47 -44
- package/dist/repl/get-prompt-header.d.ts.map +1 -1
- package/dist/repl/get-prompt-header.js +1 -30
- package/dist/repl/project-status-line.d.ts +2 -0
- package/dist/repl/project-status-line.d.ts.map +1 -0
- package/dist/repl/project-status-line.js +31 -0
- package/dist/repl/prompt.d.ts +21 -0
- package/dist/repl/prompt.d.ts.map +1 -0
- package/dist/{repl-prompt.js → repl/prompt.js} +119 -22
- package/dist/repl/tool-call-repair.d.ts.map +1 -1
- package/dist/repl/tool-call-repair.js +8 -4
- package/dist/repl-new.d.ts +53 -0
- package/dist/repl-new.d.ts.map +1 -0
- package/dist/repl-new.js +374 -0
- package/dist/repl.d.ts +3 -5
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +74 -166
- package/dist/terminal/checkbox-prompt.d.ts.map +1 -1
- package/dist/terminal/checkbox-prompt.js +10 -4
- package/dist/terminal/index.d.ts +7 -0
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +94 -0
- package/dist/terminal/input-prompt.d.ts +2 -1
- package/dist/terminal/input-prompt.d.ts.map +1 -1
- package/dist/terminal/markdown.js +3 -0
- package/dist/terminal/search-prompt.d.ts.map +1 -1
- package/dist/terminal/search-prompt.js +11 -10
- package/dist/terminal/select-prompt.d.ts +2 -2
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +47 -39
- package/dist/tokens/threshold.d.ts +35 -0
- package/dist/tokens/threshold.d.ts.map +1 -0
- package/dist/tokens/threshold.js +85 -0
- package/dist/tools/advanced-edit-file.d.ts +69 -0
- package/dist/tools/advanced-edit-file.d.ts.map +1 -0
- package/dist/tools/advanced-edit-file.js +281 -0
- package/dist/tools/agent.d.ts +16 -5
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +71 -58
- package/dist/tools/bash-utils.d.ts +1 -1
- package/dist/tools/bash-utils.d.ts.map +1 -1
- package/dist/tools/bash-utils.js +14 -6
- package/dist/tools/bash.d.ts +21 -12
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +88 -135
- package/dist/tools/code-interpreter.d.ts +21 -9
- package/dist/tools/code-interpreter.d.ts.map +1 -1
- package/dist/tools/code-interpreter.js +138 -137
- package/dist/tools/delete-file.d.ts +17 -10
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +51 -95
- package/dist/tools/directory-tree.d.ts +17 -6
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +47 -49
- package/dist/tools/dynamic-tool-loader.d.ts +18 -8
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +121 -129
- package/dist/tools/dynamic-tool-parser.d.ts +1 -0
- package/dist/tools/dynamic-tool-parser.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-parser.js +1 -0
- package/dist/tools/edit-file.d.ts +35 -15
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +112 -112
- package/dist/tools/filesystem-utils.d.ts +2 -1
- package/dist/tools/filesystem-utils.d.ts.map +1 -1
- package/dist/tools/filesystem-utils.js +31 -17
- package/dist/tools/glob.d.ts +36 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +143 -0
- package/dist/tools/grep.d.ts +73 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +413 -168
- package/dist/tools/index.d.ts +204 -124
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +242 -135
- package/dist/tools/llm-edit-fixer.d.ts +25 -0
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
- package/dist/tools/llm-edit-fixer.js +150 -0
- package/dist/tools/move-file.d.ts +19 -7
- package/dist/tools/move-file.d.ts.map +1 -1
- package/dist/tools/move-file.js +40 -33
- package/dist/tools/read-file.d.ts +47 -9
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +74 -69
- package/dist/tools/read-multiple-files.d.ts +17 -6
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +76 -73
- package/dist/tools/save-file.d.ts +45 -12
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +58 -101
- package/dist/tools/think.d.ts +15 -7
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +30 -22
- package/dist/tools/types.d.ts +4 -10
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +9 -0
- package/dist/tools/utils.d.ts +14 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +16 -0
- package/dist/tools/web-fetch.d.ts +11 -4
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +39 -38
- package/dist/tools/web-search.d.ts +15 -6
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +50 -32
- package/dist/tui/autocomplete.d.ts +44 -0
- package/dist/tui/autocomplete.d.ts.map +1 -0
- package/dist/tui/autocomplete.js +466 -0
- package/dist/tui/components/assistant-message.d.ts +18 -0
- package/dist/tui/components/assistant-message.d.ts.map +1 -0
- package/dist/tui/components/assistant-message.js +29 -0
- package/dist/tui/components/editor.d.ts +51 -0
- package/dist/tui/components/editor.d.ts.map +1 -0
- package/dist/tui/components/editor.js +758 -0
- package/dist/tui/components/footer.d.ts +24 -0
- package/dist/tui/components/footer.d.ts.map +1 -0
- package/dist/tui/components/footer.js +197 -0
- package/dist/tui/components/input.d.ts +14 -0
- package/dist/tui/components/input.d.ts.map +1 -0
- package/dist/tui/components/input.js +122 -0
- package/dist/tui/components/loader.d.ts +19 -0
- package/dist/tui/components/loader.d.ts.map +1 -0
- package/dist/tui/components/loader.js +45 -0
- package/dist/tui/components/markdown.d.ts +103 -0
- package/dist/tui/components/markdown.d.ts.map +1 -0
- package/dist/tui/components/markdown.js +533 -0
- package/dist/tui/components/modal.d.ts +40 -0
- package/dist/tui/components/modal.d.ts.map +1 -0
- package/dist/tui/components/modal.js +292 -0
- package/dist/tui/components/prompt-status.d.ts +16 -0
- package/dist/tui/components/prompt-status.d.ts.map +1 -0
- package/dist/tui/components/prompt-status.js +21 -0
- package/dist/tui/components/select-list.d.ts +22 -0
- package/dist/tui/components/select-list.d.ts.map +1 -0
- package/dist/tui/components/select-list.js +143 -0
- package/dist/tui/components/spacer.d.ts +16 -0
- package/dist/tui/components/spacer.d.ts.map +1 -0
- package/dist/tui/components/spacer.js +27 -0
- package/dist/tui/components/text.d.ts +26 -0
- package/dist/tui/components/text.d.ts.map +1 -0
- package/dist/tui/components/text.js +143 -0
- package/dist/tui/components/thinking-block.d.ts +14 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -0
- package/dist/tui/components/thinking-block.js +30 -0
- package/dist/tui/components/tool-execution.d.ts +17 -0
- package/dist/tui/components/tool-execution.d.ts.map +1 -0
- package/dist/tui/components/tool-execution.js +153 -0
- package/dist/tui/components/user-message.d.ts +9 -0
- package/dist/tui/components/user-message.d.ts.map +1 -0
- package/dist/tui/components/user-message.js +21 -0
- package/dist/tui/components/welcome.d.ts +6 -0
- package/dist/tui/components/welcome.d.ts.map +1 -0
- package/dist/tui/components/welcome.js +30 -0
- package/dist/tui/index.d.ts +14 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +18 -0
- package/dist/tui/terminal.d.ts +37 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +104 -0
- package/dist/tui/tui.d.ts +67 -0
- package/dist/tui/tui.d.ts.map +1 -0
- package/dist/tui/tui.js +184 -0
- package/dist/tui/utils.d.ts +19 -0
- package/dist/tui/utils.d.ts.map +1 -0
- package/dist/tui/utils.js +31 -0
- package/dist/utils/generators.d.ts +3 -0
- package/dist/utils/generators.d.ts.map +1 -0
- package/dist/utils/generators.js +25 -0
- package/dist/utils/iterables.d.ts +2 -0
- package/dist/utils/iterables.d.ts.map +1 -0
- package/dist/utils/iterables.js +6 -0
- package/package.json +16 -16
- package/dist/conversation-analyzer.d.ts +0 -11
- package/dist/conversation-analyzer.d.ts.map +0 -1
- package/dist/conversation-analyzer.js +0 -88
- package/dist/repl-prompt.d.ts +0 -15
- package/dist/repl-prompt.d.ts.map +0 -1
- package/dist/tokens/manage-output.d.ts +0 -34
- package/dist/tokens/manage-output.d.ts.map +0 -1
- package/dist/tokens/manage-output.js +0 -44
- package/dist/tool-executor.d.ts +0 -28
- package/dist/tool-executor.d.ts.map +0 -1
- package/dist/tool-executor.js +0 -74
- package/dist/tools/file-editing-utils.d.ts +0 -2
- package/dist/tools/file-editing-utils.d.ts.map +0 -1
- package/dist/tools/file-editing-utils.js +0 -135
package/dist/tools/save-file.js
CHANGED
|
@@ -1,126 +1,83 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { tool } from "ai";
|
|
4
3
|
import { z } from "zod";
|
|
5
|
-
import { formatCodeBlock } from "../formatting.js";
|
|
6
4
|
import style from "../terminal/style.js";
|
|
7
5
|
import { joinWorkingDir, validatePath } from "./filesystem-utils.js";
|
|
8
6
|
import { fileEncodingSchema } from "./types.js";
|
|
9
7
|
export const SaveFileTool = {
|
|
10
8
|
name: "saveFile",
|
|
11
9
|
};
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
const inputSchema = z.object({
|
|
11
|
+
path: z.string().describe("Absolute path to file to save to"),
|
|
12
|
+
content: z.string().describe("Content to save in the file"),
|
|
13
|
+
encoding: fileEncodingSchema.describe('Encoding format for saving the file. Use "utf-8" as default for text files'),
|
|
14
|
+
});
|
|
15
|
+
export const createSaveFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
16
|
+
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
14
17
|
return {
|
|
15
|
-
|
|
18
|
+
toolDef: {
|
|
16
19
|
description: "Create a new file or completely overwrite an existing file with new content. " +
|
|
17
20
|
"Automatically creates all missing parent directories. " +
|
|
18
21
|
"Use with caution as it will overwrite existing files without warning. " +
|
|
19
22
|
"Handles text content with proper encoding. Only works within allowed directories.",
|
|
20
|
-
inputSchema
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}),
|
|
25
|
-
execute: async ({ path: userPath, content, encoding, }, { toolCallId, abortSignal }) => {
|
|
26
|
-
// Check if execution has been aborted
|
|
23
|
+
inputSchema,
|
|
24
|
+
},
|
|
25
|
+
async *execute({ path: userPath, content, encoding }, { toolCallId, abortSignal }) {
|
|
26
|
+
try {
|
|
27
27
|
if (abortSignal?.aborted) {
|
|
28
28
|
throw new Error("File saving aborted");
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
yield {
|
|
31
|
+
name: SaveFileTool.name,
|
|
32
32
|
event: "tool-init",
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
id: toolCallId,
|
|
34
|
+
data: `${style.cyan(userPath)}`,
|
|
35
|
+
};
|
|
36
|
+
const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory, { requireExistence: false, abortSignal });
|
|
37
|
+
// Check if path exists and is a directory
|
|
35
38
|
try {
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
terminal.lineBreak();
|
|
40
|
-
terminal.writeln("Proposed file content:");
|
|
41
|
-
terminal.hr();
|
|
42
|
-
terminal.display(formatCodeBlock(userPath, content));
|
|
43
|
-
terminal.hr();
|
|
44
|
-
// Determine overwrite status for display
|
|
45
|
-
let overwriteMessage = "";
|
|
46
|
-
try {
|
|
47
|
-
const stat = await fs.stat(filePath);
|
|
48
|
-
if (stat.isFile()) {
|
|
49
|
-
overwriteMessage = style.yellow("(Will overwrite existing file)");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
overwriteMessage = style.green("(Will create new file)");
|
|
54
|
-
}
|
|
55
|
-
let userResponse;
|
|
56
|
-
if (toolExecutor) {
|
|
57
|
-
const ctx = {
|
|
58
|
-
toolName: SaveFileTool.name,
|
|
59
|
-
toolCallId,
|
|
60
|
-
message: `What would you like to do with this save? ${overwriteMessage}`,
|
|
61
|
-
choices: {
|
|
62
|
-
accept: "Accept this save",
|
|
63
|
-
acceptAll: "Accept all future saves (including this)",
|
|
64
|
-
reject: "Reject this save",
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
try {
|
|
68
|
-
userResponse = await toolExecutor.ask(ctx, { abortSignal });
|
|
69
|
-
}
|
|
70
|
-
catch (e) {
|
|
71
|
-
if (e.name === "AbortError") {
|
|
72
|
-
throw new Error("File saving aborted during user input");
|
|
73
|
-
}
|
|
74
|
-
throw e;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const { result: userChoice, reason } = userResponse ?? {
|
|
78
|
-
result: "accept",
|
|
79
|
-
};
|
|
80
|
-
terminal.lineBreak();
|
|
81
|
-
if (userChoice === "accept-all") {
|
|
82
|
-
terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all saves"));
|
|
83
|
-
terminal.lineBreak();
|
|
84
|
-
}
|
|
85
|
-
if (userChoice === "reject") {
|
|
86
|
-
terminal.lineBreak();
|
|
87
|
-
const rejectionReason = reason || "No reason provided";
|
|
88
|
-
sendData?.({
|
|
89
|
-
id: toolCallId,
|
|
90
|
-
event: "tool-completion",
|
|
91
|
-
data: `Save rejected by user. Reason: ${rejectionReason}`,
|
|
92
|
-
});
|
|
93
|
-
return `The user rejected this save. Reason: ${rejectionReason}`;
|
|
94
|
-
}
|
|
95
|
-
// If accepted, proceed to write file
|
|
39
|
+
const stat = await fs.stat(filePath);
|
|
40
|
+
if (stat.isDirectory()) {
|
|
41
|
+
throw new Error(`Cannot save file - path is a directory: ${filePath}`);
|
|
96
42
|
}
|
|
97
|
-
// Pre-side-effect check
|
|
98
|
-
if (abortSignal?.aborted) {
|
|
99
|
-
throw new Error("File saving aborted before writing");
|
|
100
|
-
}
|
|
101
|
-
// Ensure parent directory exists (create missing parents)
|
|
102
|
-
const parentDir = path.dirname(filePath);
|
|
103
|
-
await fs.mkdir(parentDir, { recursive: true });
|
|
104
|
-
await fs.writeFile(filePath, content, {
|
|
105
|
-
encoding,
|
|
106
|
-
signal: abortSignal,
|
|
107
|
-
});
|
|
108
|
-
sendData?.({
|
|
109
|
-
id: toolCallId,
|
|
110
|
-
event: "tool-completion",
|
|
111
|
-
data: `File saved successfully: ${userPath}`,
|
|
112
|
-
});
|
|
113
|
-
return `File saved successfully: ${filePath}`;
|
|
114
43
|
}
|
|
115
44
|
catch (error) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
return `Failed to save file: ${error.message}`;
|
|
45
|
+
// Only re-throw if it's our directory error, otherwise continue (file doesn't exist)
|
|
46
|
+
if (error instanceof Error &&
|
|
47
|
+
error.message.includes("is a directory")) {
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
122
50
|
}
|
|
123
|
-
|
|
124
|
-
|
|
51
|
+
// Pre-side-effect check
|
|
52
|
+
if (abortSignal?.aborted) {
|
|
53
|
+
throw new Error("File saving aborted before writing");
|
|
54
|
+
}
|
|
55
|
+
// Ensure parent directory exists (create missing parents)
|
|
56
|
+
const parentDir = path.dirname(filePath);
|
|
57
|
+
await fs.mkdir(parentDir, { recursive: true });
|
|
58
|
+
await fs.writeFile(filePath, content, {
|
|
59
|
+
encoding,
|
|
60
|
+
signal: abortSignal,
|
|
61
|
+
});
|
|
62
|
+
const lines = content.split("\n").length;
|
|
63
|
+
const bytes = Buffer.byteLength(content, encoding);
|
|
64
|
+
yield {
|
|
65
|
+
name: SaveFileTool.name,
|
|
66
|
+
event: "tool-completion",
|
|
67
|
+
id: toolCallId,
|
|
68
|
+
data: `Saved ${lines} lines, ${bytes} bytes`,
|
|
69
|
+
};
|
|
70
|
+
yield `File saved successfully: ${filePath}`;
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
yield {
|
|
74
|
+
name: SaveFileTool.name,
|
|
75
|
+
event: "tool-error",
|
|
76
|
+
id: toolCallId,
|
|
77
|
+
data: error.message,
|
|
78
|
+
};
|
|
79
|
+
yield `Failed to save file: ${error.message}`;
|
|
80
|
+
}
|
|
81
|
+
},
|
|
125
82
|
};
|
|
126
83
|
};
|
package/dist/tools/think.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ToolResult } from "./types.ts";
|
|
2
4
|
export declare const ThinkTool: {
|
|
3
5
|
name: "think";
|
|
4
6
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
declare const inputSchema: z.ZodObject<{
|
|
8
|
+
thought: z.ZodString;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export declare const createThinkTool: () => {
|
|
11
|
+
toolDef: {
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: z.ZodObject<{
|
|
14
|
+
thought: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
};
|
|
17
|
+
execute({ thought }: z.infer<typeof inputSchema>, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
11
18
|
};
|
|
19
|
+
export {};
|
|
12
20
|
//# sourceMappingURL=think.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,SAAS;;CAErB,CAAC;AAWF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;yBAOT,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACX,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;CAqChC,CAAC"}
|
package/dist/tools/think.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
export const ThinkTool = {
|
|
4
3
|
name: "think",
|
|
@@ -11,39 +10,48 @@ Common use cases:
|
|
|
11
10
|
4. When designing a new feature, use this tool to think through architecture decisions and implementation details
|
|
12
11
|
5. When debugging a complex issue, use this tool to organize your thoughts and hypotheses
|
|
13
12
|
The tool simply logs your thought process for better transparency and does not execute any code or make changes.`;
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
thought: z.string().describe("Your thought"),
|
|
15
|
+
});
|
|
14
16
|
// This is a no-op tool that logs a thought. It is inspired by the tau-bench think tool.
|
|
15
|
-
export const createThinkTool = (
|
|
16
|
-
const { sendData } = options;
|
|
17
|
+
export const createThinkTool = () => {
|
|
17
18
|
return {
|
|
18
|
-
|
|
19
|
+
toolDef: {
|
|
19
20
|
description: toolDescription,
|
|
20
|
-
inputSchema
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
inputSchema,
|
|
22
|
+
},
|
|
23
|
+
async *execute({ thought }, { toolCallId, abortSignal }) {
|
|
24
|
+
try {
|
|
24
25
|
// Check if execution has been aborted
|
|
25
26
|
if (abortSignal?.aborted) {
|
|
26
27
|
throw new Error("Thinking process aborted");
|
|
27
28
|
}
|
|
28
29
|
// Replace literal '\\n' with actual newline characters
|
|
29
30
|
const formattedThought = thought.replace(/\\n/g, "\n");
|
|
30
|
-
|
|
31
|
+
yield {
|
|
32
|
+
name: ThinkTool.name,
|
|
31
33
|
event: "tool-init",
|
|
32
34
|
id: toolCallId,
|
|
33
|
-
data:
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
id: toolCallId,
|
|
38
|
-
data: { primary: "Thought:", secondary: [formattedThought] },
|
|
39
|
-
});
|
|
40
|
-
sendData?.({
|
|
35
|
+
data: `\n${formattedThought}`,
|
|
36
|
+
};
|
|
37
|
+
yield {
|
|
38
|
+
name: ThinkTool.name,
|
|
41
39
|
event: "tool-completion",
|
|
42
40
|
id: toolCallId,
|
|
43
|
-
data: "
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
41
|
+
data: "Thought logged",
|
|
42
|
+
};
|
|
43
|
+
yield "Your thought has been logged.";
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
47
|
+
yield {
|
|
48
|
+
name: ThinkTool.name,
|
|
49
|
+
event: "tool-error",
|
|
50
|
+
id: toolCallId,
|
|
51
|
+
data: errorMessage,
|
|
52
|
+
};
|
|
53
|
+
yield errorMessage;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
48
56
|
};
|
|
49
57
|
};
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -12,11 +12,8 @@ export declare const fileEncodingSchema: z.ZodEnum<{
|
|
|
12
12
|
binary: "binary";
|
|
13
13
|
hex: "hex";
|
|
14
14
|
}>;
|
|
15
|
-
interface MessageData {
|
|
16
|
-
primary: string;
|
|
17
|
-
secondary?: string[] | undefined;
|
|
18
|
-
}
|
|
19
15
|
interface BaseMessage {
|
|
16
|
+
name: string;
|
|
20
17
|
id: string;
|
|
21
18
|
retry?: number;
|
|
22
19
|
}
|
|
@@ -32,11 +29,8 @@ interface ToolCompletionMessage extends BaseMessage {
|
|
|
32
29
|
event: "tool-completion";
|
|
33
30
|
data: string;
|
|
34
31
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
export type Message = ToolInitMessage | ToolErrorMessage | ToolCompletionMessage | ToolUpdateMessage;
|
|
40
|
-
export type SendData = ({ data, event, id, retry, }: Message) => void | Promise<void>;
|
|
32
|
+
export type Message = ToolInitMessage | ToolErrorMessage | ToolCompletionMessage;
|
|
33
|
+
export type ToolResult = Message | string;
|
|
34
|
+
export declare function isToolMessage(value: unknown): value is Message;
|
|
41
35
|
export {};
|
|
42
36
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,UAAU,WAAW;IACnB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAgB,SAAQ,WAAW;IAC3C,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAiB,SAAQ,WAAW;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,qBAAsB,SAAQ,WAAW;IACjD,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,OAAO,GACf,eAAe,GACf,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAc9D"}
|
package/dist/tools/types.js
CHANGED
|
@@ -12,3 +12,12 @@ export const fileEncodingSchema = z.enum([
|
|
|
12
12
|
"binary",
|
|
13
13
|
"hex",
|
|
14
14
|
]);
|
|
15
|
+
export function isToolMessage(value) {
|
|
16
|
+
if (!value || typeof value !== "object") {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const candidate = value;
|
|
20
|
+
return (typeof candidate.event === "string" &&
|
|
21
|
+
typeof candidate.id === "string" &&
|
|
22
|
+
("data" in candidate || "retry" in candidate));
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Tool } from "ai";
|
|
2
|
+
export declare function prepareTools(tools: {
|
|
3
|
+
[toolName: string]: Tool;
|
|
4
|
+
}): {
|
|
5
|
+
tools: undefined | Array<{
|
|
6
|
+
type: "function";
|
|
7
|
+
function: {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string | undefined;
|
|
10
|
+
parameters: unknown;
|
|
11
|
+
};
|
|
12
|
+
}>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../source/tools/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG;IACjE,KAAK,EACD,SAAS,GACT,KAAK,CAAC;QACJ,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;YAChC,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;KACH,CAAC,CAAC;CACR,CAuBA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export function prepareTools(tools) {
|
|
3
|
+
const openaiCompatTools = [];
|
|
4
|
+
for (const tool of Object.entries(tools)) {
|
|
5
|
+
openaiCompatTools.push({
|
|
6
|
+
type: "function",
|
|
7
|
+
function: {
|
|
8
|
+
name: tool[0],
|
|
9
|
+
description: tool[1].description,
|
|
10
|
+
// biome-ignore lint/suspicious/noExplicitAny: try to figure it out for now
|
|
11
|
+
parameters: z.toJSONSchema(tool[1].inputSchema),
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return { tools: openaiCompatTools };
|
|
16
|
+
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
1
3
|
import type { TokenCounter } from "../tokens/counter.ts";
|
|
2
|
-
import type {
|
|
4
|
+
import type { ToolResult } from "./types.ts";
|
|
3
5
|
export declare const WebFetchTool: {
|
|
4
6
|
name: "webFetch";
|
|
5
7
|
};
|
|
6
8
|
export declare const createWebFetchTool: (options: {
|
|
7
|
-
sendData?: SendData | undefined;
|
|
8
9
|
tokenCounter: TokenCounter;
|
|
9
10
|
}) => {
|
|
10
|
-
|
|
11
|
+
toolDef: {
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: z.ZodObject<{
|
|
14
|
+
url: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
};
|
|
17
|
+
execute({ url }: {
|
|
11
18
|
url: string;
|
|
12
|
-
},
|
|
19
|
+
}, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
13
20
|
};
|
|
14
21
|
type ContentType = "text/plain" | "text/html" | "text/markdown" | "application/json" | "application/xml" | "application/pdf" | "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "image/svg+xml" | "audio/mpeg" | "audio/wav" | "video/mp4" | "video/webm" | "application/zip" | "application/octet-stream";
|
|
15
22
|
export type ReadUrlResult = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../source/tools/web-fetch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../source/tools/web-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,YAAY;;CAExB,CAAC;AAMF,eAAO,MAAM,kBAAkB,GAAI,SAAS;IAAE,YAAY,EAAE,YAAY,CAAA;CAAE;;;;;;;qBAQ3D;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,+BACK,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;CAmChC,CAAC;AAEF,KAAK,WAAW,GACZ,YAAY,GACZ,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,WAAW,GACX,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,eAAe,GACf,YAAY,GACZ,WAAW,GACX,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,0BAA0B,CAAC;AAE/B,MAAM,MAAM,aAAa,GAAG;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvE,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,GACpC,OAAO,CAAC,aAAa,CAAC,CA6HxB;AAED,qBAAa,WAAW;IACtB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAIrC,OAAO,CAAC,IAAI,CAAS;IAErB,OAAO;IAIP;;;;;;OAMG;IACH,KAAK,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM;IAuBhE;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAyCjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAG5B"}
|
package/dist/tools/web-fetch.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
1
|
import { load } from "cheerio";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import { logger } from "../logger.js";
|
|
@@ -6,46 +5,48 @@ import style from "../terminal/style.js";
|
|
|
6
5
|
export const WebFetchTool = {
|
|
7
6
|
name: "webFetch",
|
|
8
7
|
};
|
|
8
|
+
const inputSchema = z.object({
|
|
9
|
+
url: z.string().describe("The URL to fetch content from."),
|
|
10
|
+
});
|
|
9
11
|
export const createWebFetchTool = (options) => {
|
|
10
|
-
const { sendData } = options;
|
|
11
12
|
return {
|
|
12
|
-
|
|
13
|
+
toolDef: {
|
|
13
14
|
description: "Fetches the content of a given URL. It intelligently handles HTML content by attempting to use a specialized service for cleaner extraction, falling back to local cleaning if needed. For non-HTML content (like plain text or markdown), it fetches the raw content directly. IMPORTANT: Does not retrieve binary files.",
|
|
14
|
-
inputSchema
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
15
|
+
inputSchema,
|
|
16
|
+
},
|
|
17
|
+
async *execute({ url }, { toolCallId, abortSignal }) {
|
|
18
|
+
try {
|
|
19
|
+
yield {
|
|
20
|
+
name: WebFetchTool.name,
|
|
21
|
+
event: "tool-init",
|
|
22
|
+
id: toolCallId,
|
|
23
|
+
data: `${style.cyan(url)}`,
|
|
24
|
+
};
|
|
25
|
+
logger.info(`Initiating fetch for URL: ${url}`);
|
|
26
|
+
const result = await readUrl(url, abortSignal);
|
|
27
|
+
const urlContent = result.data;
|
|
28
|
+
const tokenCount = options.tokenCounter.count(urlContent);
|
|
29
|
+
yield {
|
|
30
|
+
name: WebFetchTool.name,
|
|
31
|
+
event: "tool-completion",
|
|
32
|
+
id: toolCallId,
|
|
33
|
+
data: `Fetched URL (${tokenCount} tokens)`,
|
|
34
|
+
};
|
|
35
|
+
logger.info(`Successfully read URL: ${url} (${tokenCount} tokens)`);
|
|
36
|
+
yield urlContent;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
const errorMessage = error.message;
|
|
40
|
+
yield {
|
|
41
|
+
name: WebFetchTool.name,
|
|
42
|
+
event: "tool-error",
|
|
43
|
+
id: toolCallId,
|
|
44
|
+
data: `${style.cyan(url)} ${errorMessage}`,
|
|
45
|
+
};
|
|
46
|
+
logger.error(`Error reading URL ${url}: ${errorMessage}`);
|
|
47
|
+
yield `Failed to read URL: ${errorMessage}`;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
49
50
|
};
|
|
50
51
|
};
|
|
51
52
|
export async function readUrl(url, abortSignal) {
|
|
@@ -1,14 +1,23 @@
|
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
1
3
|
import type { TokenCounter } from "../tokens/counter.ts";
|
|
2
|
-
import type {
|
|
4
|
+
import type { ToolResult } from "./types.ts";
|
|
3
5
|
export declare const WebSearchTool: {
|
|
4
6
|
name: "webSearch";
|
|
5
7
|
};
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
query: z.ZodString;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export declare const createWebSearchTool: ({ tokenCounter, }: {
|
|
8
12
|
tokenCounter: TokenCounter;
|
|
9
13
|
}) => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
toolDef: {
|
|
15
|
+
description: string;
|
|
16
|
+
inputSchema: z.ZodObject<{
|
|
17
|
+
query: z.ZodString;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
};
|
|
20
|
+
execute: ({ query }: z.infer<typeof inputSchema>, { toolCallId, abortSignal }: ToolCallOptions) => AsyncGenerator<ToolResult>;
|
|
13
21
|
};
|
|
22
|
+
export {};
|
|
14
23
|
//# sourceMappingURL=web-search.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAEF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAEH,eAAO,MAAM,mBAAmB,GAAI,mBAEjC;IACD,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;yBAQc,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACT,eAAe,KAC3C,cAAc,CAAC,UAAU,CAAC;CA0D9B,CAAC"}
|
package/dist/tools/web-search.js
CHANGED
|
@@ -1,43 +1,61 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
1
|
import { SafeSearchType, search } from "duck-duck-scrape";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import Exa from "../api/exa/index.js";
|
|
5
4
|
import style from "../terminal/style.js";
|
|
5
|
+
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
6
6
|
export const WebSearchTool = {
|
|
7
7
|
name: "webSearch",
|
|
8
8
|
};
|
|
9
|
-
|
|
9
|
+
const inputSchema = z.object({
|
|
10
|
+
query: z.string().describe("The search query."),
|
|
11
|
+
});
|
|
12
|
+
export const createWebSearchTool = ({ tokenCounter, }) => {
|
|
13
|
+
const toolDef = {
|
|
14
|
+
description: "Searches the web and returns match documents with their title, url, and text content. The query should be formulated as a natural language question.",
|
|
15
|
+
inputSchema,
|
|
16
|
+
};
|
|
17
|
+
const execute = async function* ({ query }, { toolCallId, abortSignal }) {
|
|
18
|
+
try {
|
|
19
|
+
// Check if execution has been aborted
|
|
20
|
+
if (abortSignal?.aborted) {
|
|
21
|
+
throw new Error("Web search aborted");
|
|
22
|
+
}
|
|
23
|
+
yield {
|
|
24
|
+
name: WebSearchTool.name,
|
|
25
|
+
event: "tool-init",
|
|
26
|
+
id: toolCallId,
|
|
27
|
+
data: `${style.cyan(query)}`,
|
|
28
|
+
};
|
|
29
|
+
if (abortSignal?.aborted) {
|
|
30
|
+
throw new Error("Web search aborted before search execution");
|
|
31
|
+
}
|
|
32
|
+
const result = await performSearch(query, abortSignal);
|
|
33
|
+
const sources = result.results.map((source) => `## ${source.title}\nURL: ${source.url}\n\n${source.text}`);
|
|
34
|
+
const resultText = `# Search Results:\n\n${sources.join("\n\n")}`;
|
|
35
|
+
const searchResult = await manageTokenLimit(resultText, tokenCounter, "WebSearch", "Use more specific search queries or reduce number of results");
|
|
36
|
+
yield {
|
|
37
|
+
name: WebSearchTool.name,
|
|
38
|
+
event: "tool-completion",
|
|
39
|
+
id: toolCallId,
|
|
40
|
+
data: `Found ${result.results.length} results (${searchResult.tokenCount} tokens)`,
|
|
41
|
+
};
|
|
42
|
+
yield searchResult.content;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
46
|
+
yield {
|
|
47
|
+
name: WebSearchTool.name,
|
|
48
|
+
event: "tool-error",
|
|
49
|
+
id: toolCallId,
|
|
50
|
+
data: errorMessage,
|
|
51
|
+
};
|
|
52
|
+
yield errorMessage;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
10
55
|
return {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
query: z.string().describe("The search query."),
|
|
15
|
-
}),
|
|
16
|
-
execute: async ({ query }, { toolCallId, abortSignal }) => {
|
|
17
|
-
// Check if execution has been aborted
|
|
18
|
-
if (abortSignal?.aborted) {
|
|
19
|
-
throw new Error("Web search aborted");
|
|
20
|
-
}
|
|
21
|
-
sendData?.({
|
|
22
|
-
id: toolCallId,
|
|
23
|
-
event: "tool-init",
|
|
24
|
-
data: `Web search: ${style.cyan(query)}`,
|
|
25
|
-
});
|
|
26
|
-
if (abortSignal?.aborted) {
|
|
27
|
-
throw new Error("Web search aborted before search execution");
|
|
28
|
-
}
|
|
29
|
-
const result = await performSearch(query, abortSignal);
|
|
30
|
-
const sources = result.results.map((source) => `## ${source.title}\nURL: ${source.url}\n\n${source.text}`);
|
|
31
|
-
const resultText = `# Search Results:\n\n${sources.join("\n\n")}`;
|
|
32
|
-
const tokenCount = tokenCounter.count(resultText);
|
|
33
|
-
sendData?.({
|
|
34
|
-
id: toolCallId,
|
|
35
|
-
event: "tool-completion",
|
|
36
|
-
data: `Found ${result.results.length} results. (${tokenCount} tokens)`,
|
|
37
|
-
});
|
|
38
|
-
return resultText;
|
|
39
|
-
},
|
|
40
|
-
}),
|
|
56
|
+
toolDef,
|
|
57
|
+
execute,
|
|
58
|
+
// No ask method needed for read-only tool
|
|
41
59
|
};
|
|
42
60
|
};
|
|
43
61
|
async function performSearch(query, abortSignal) {
|