@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
|
@@ -3,8 +3,8 @@ import { randomUUID } from "node:crypto";
|
|
|
3
3
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import process from "node:process";
|
|
6
|
-
import { tool } from "ai";
|
|
7
6
|
import { z } from "zod";
|
|
7
|
+
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
8
8
|
export const CodeInterpreterTool = {
|
|
9
9
|
name: "codeInterpreter",
|
|
10
10
|
};
|
|
@@ -24,143 +24,144 @@ import { functionName } from '../source/path/to/module.ts';
|
|
|
24
24
|
The interpreter supports ES Modules with TypeScript files directly.
|
|
25
25
|
|
|
26
26
|
Timeout defaults to 5 seconds and can be extended up to 60 seconds.`;
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
// Handle abort signal by killing the child process
|
|
94
|
-
if (abortSignal) {
|
|
95
|
-
abortSignal.addEventListener("abort", () => {
|
|
96
|
-
try {
|
|
97
|
-
child.kill("SIGKILL");
|
|
98
|
-
}
|
|
99
|
-
catch { }
|
|
100
|
-
throw new Error("Code interpretation aborted during execution");
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
let stdout = "";
|
|
104
|
-
let stderr = "";
|
|
105
|
-
let timedOut = false;
|
|
106
|
-
const timer = setTimeout(() => {
|
|
107
|
-
timedOut = true;
|
|
108
|
-
try {
|
|
109
|
-
child.kill("SIGKILL");
|
|
110
|
-
}
|
|
111
|
-
catch { }
|
|
112
|
-
}, timeoutMs);
|
|
113
|
-
child.stdout.setEncoding("utf8");
|
|
114
|
-
child.stderr.setEncoding("utf8");
|
|
115
|
-
child.stdout.on("data", (chunk) => {
|
|
116
|
-
stdout += String(chunk);
|
|
117
|
-
});
|
|
118
|
-
child.stderr.on("data", (chunk) => {
|
|
119
|
-
stderr += String(chunk);
|
|
120
|
-
});
|
|
121
|
-
const completed = await new Promise((resolve, reject) => {
|
|
122
|
-
child.on("error", (err) => reject(err));
|
|
123
|
-
child.on("close", (code, signal) => resolve({ code, signal }));
|
|
124
|
-
});
|
|
125
|
-
clearTimeout(timer);
|
|
126
|
-
// Cleanup temp file/directory
|
|
127
|
-
await rm(scriptPath, { force: true });
|
|
128
|
-
await rm(tmpBase, { force: true, recursive: true });
|
|
129
|
-
if (timedOut) {
|
|
130
|
-
throw new Error("Script timed out");
|
|
131
|
-
}
|
|
132
|
-
if (completed.code === null) {
|
|
133
|
-
throw new Error(`Process terminated by signal ${completed.signal ?? "unknown"}`);
|
|
134
|
-
}
|
|
135
|
-
if (completed.code !== 0) {
|
|
136
|
-
const message = `Process exited with code ${completed.code}. Stderr:\n${stderr.trim()}`;
|
|
137
|
-
throw new Error(message);
|
|
27
|
+
const inputSchema = z.object({
|
|
28
|
+
code: z.string().describe("The Typescript code to be executed."),
|
|
29
|
+
timeoutSeconds: z
|
|
30
|
+
.number()
|
|
31
|
+
.int()
|
|
32
|
+
.min(1)
|
|
33
|
+
.max(60)
|
|
34
|
+
.nullable()
|
|
35
|
+
.describe("Execution timeout in seconds (1-60). Default 5."),
|
|
36
|
+
});
|
|
37
|
+
export const createCodeInterpreterTool = async ({ tokenCounter, }) => {
|
|
38
|
+
const toolDef = {
|
|
39
|
+
description: toolDescription,
|
|
40
|
+
inputSchema,
|
|
41
|
+
};
|
|
42
|
+
async function* execute({ code, timeoutSeconds }, { toolCallId, abortSignal }) {
|
|
43
|
+
// Check if execution has been aborted
|
|
44
|
+
if (abortSignal?.aborted) {
|
|
45
|
+
throw new Error("Code interpretation aborted");
|
|
46
|
+
}
|
|
47
|
+
const workingDirectory = process.cwd();
|
|
48
|
+
const lines = code.split("\n");
|
|
49
|
+
try {
|
|
50
|
+
yield {
|
|
51
|
+
name: CodeInterpreterTool.name,
|
|
52
|
+
event: "tool-init",
|
|
53
|
+
id: toolCallId,
|
|
54
|
+
data: `Executing ${lines.length} lines of code.`,
|
|
55
|
+
};
|
|
56
|
+
if (code.trim().length === 0) {
|
|
57
|
+
throw new Error("No code provided");
|
|
58
|
+
}
|
|
59
|
+
if (abortSignal?.aborted) {
|
|
60
|
+
throw new Error("Code interpretation aborted before execution");
|
|
61
|
+
}
|
|
62
|
+
const timeoutMs = Math.min(Math.max((timeoutSeconds ?? 5) * 1000, 1000), 60000);
|
|
63
|
+
const tmpBase = join(workingDirectory, ".acai-ci-tmp");
|
|
64
|
+
await mkdir(tmpBase, { recursive: true });
|
|
65
|
+
const ext = ".ts";
|
|
66
|
+
const scriptPath = join(tmpBase, `temp_script_${Date.now()}_${randomUUID()}${ext}`);
|
|
67
|
+
await writeFile(scriptPath, code, { encoding: "utf8" });
|
|
68
|
+
const args = [
|
|
69
|
+
"--permission",
|
|
70
|
+
`--allow-fs-read=${workingDirectory}`,
|
|
71
|
+
`--allow-fs-write=${workingDirectory}`,
|
|
72
|
+
scriptPath,
|
|
73
|
+
];
|
|
74
|
+
const child = spawn(process.execPath, args, {
|
|
75
|
+
cwd: workingDirectory,
|
|
76
|
+
// do not rely solely on spawn's timeout; we implement manual timeout below
|
|
77
|
+
stdio: "pipe",
|
|
78
|
+
env: Object.assign({}, process.env, {
|
|
79
|
+
// biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
|
|
80
|
+
NO_COLOR: "true",
|
|
81
|
+
// biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
|
|
82
|
+
NODE_OPTIONS: "",
|
|
83
|
+
// biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
|
|
84
|
+
ACAI_CODE_INTERPRETER: "true",
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
// Handle abort signal by killing the child process
|
|
88
|
+
if (abortSignal) {
|
|
89
|
+
const abortHandler = () => {
|
|
90
|
+
try {
|
|
91
|
+
child.kill("SIGKILL");
|
|
138
92
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
catch (err) {
|
|
152
|
-
const errorMessage = err.name === "ETIMEDOUT" ||
|
|
153
|
-
err.message.includes("timed out")
|
|
154
|
-
? "Script timed out"
|
|
155
|
-
: `Error:\n${err.message}`;
|
|
156
|
-
sendData?.({
|
|
157
|
-
event: "tool-error",
|
|
158
|
-
id: toolCallId,
|
|
159
|
-
data: errorMessage,
|
|
160
|
-
});
|
|
161
|
-
return errorMessage;
|
|
93
|
+
catch { }
|
|
94
|
+
throw new Error("Code interpretation aborted during execution");
|
|
95
|
+
};
|
|
96
|
+
abortSignal.addEventListener("abort", abortHandler);
|
|
97
|
+
}
|
|
98
|
+
let stdout = "";
|
|
99
|
+
let stderr = "";
|
|
100
|
+
let timedOut = false;
|
|
101
|
+
const timer = setTimeout(() => {
|
|
102
|
+
timedOut = true;
|
|
103
|
+
try {
|
|
104
|
+
child.kill("SIGKILL");
|
|
162
105
|
}
|
|
163
|
-
|
|
164
|
-
|
|
106
|
+
catch { }
|
|
107
|
+
}, timeoutMs);
|
|
108
|
+
child.stdout.setEncoding("utf8");
|
|
109
|
+
child.stderr.setEncoding("utf8");
|
|
110
|
+
child.stdout.on("data", (chunk) => {
|
|
111
|
+
stdout += String(chunk);
|
|
112
|
+
});
|
|
113
|
+
child.stderr.on("data", (chunk) => {
|
|
114
|
+
stderr += String(chunk);
|
|
115
|
+
});
|
|
116
|
+
const completed = await new Promise((resolve, reject) => {
|
|
117
|
+
child.on("error", (err) => reject(err));
|
|
118
|
+
child.on("close", (code, signal) => resolve({ code, signal }));
|
|
119
|
+
});
|
|
120
|
+
clearTimeout(timer);
|
|
121
|
+
// Cleanup temp file/directory
|
|
122
|
+
await rm(scriptPath, { force: true });
|
|
123
|
+
await rm(tmpBase, { force: true, recursive: true });
|
|
124
|
+
if (timedOut) {
|
|
125
|
+
throw new Error("Script timed out");
|
|
126
|
+
}
|
|
127
|
+
if (completed.code === null) {
|
|
128
|
+
throw new Error(`Process terminated by signal ${completed.signal ?? "unknown"}`);
|
|
129
|
+
}
|
|
130
|
+
if (completed.code !== 0) {
|
|
131
|
+
const message = `Process exited with code ${completed.code}. Stderr:\n${stderr.trim()}`;
|
|
132
|
+
throw new Error(message);
|
|
133
|
+
}
|
|
134
|
+
const result = {
|
|
135
|
+
stdout: stdout.trim(),
|
|
136
|
+
stderr: stderr.trim(),
|
|
137
|
+
exitCode: completed.code ?? -1,
|
|
138
|
+
};
|
|
139
|
+
const resultJson = JSON.stringify(result, null, 2);
|
|
140
|
+
const managedResult = await manageTokenLimit(resultJson, tokenCounter, "CodeInterpreter", "Reduce script complexity or output size");
|
|
141
|
+
yield {
|
|
142
|
+
name: CodeInterpreterTool.name,
|
|
143
|
+
event: "tool-completion",
|
|
144
|
+
id: toolCallId,
|
|
145
|
+
data: `Completed successfully${managedResult.tokenCount > 0 ? ` (${managedResult.tokenCount} tokens)` : ""}`,
|
|
146
|
+
};
|
|
147
|
+
yield managedResult.content;
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
const errorMessage = err.name === "ETIMEDOUT" ||
|
|
151
|
+
err.message.includes("timed out")
|
|
152
|
+
? "Script timed out"
|
|
153
|
+
: err.message;
|
|
154
|
+
yield {
|
|
155
|
+
name: CodeInterpreterTool.name,
|
|
156
|
+
event: "tool-error",
|
|
157
|
+
id: toolCallId,
|
|
158
|
+
data: errorMessage,
|
|
159
|
+
};
|
|
160
|
+
yield errorMessage;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
toolDef,
|
|
165
|
+
execute,
|
|
165
166
|
};
|
|
166
167
|
};
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ToolResult } from "./types.ts";
|
|
4
4
|
export declare const DeleteFileTool: {
|
|
5
5
|
name: "deleteFile";
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
declare const inputSchema: z.ZodObject<{
|
|
8
|
+
path: z.ZodString;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
type DeleteFileInputSchema = z.infer<typeof inputSchema>;
|
|
11
|
+
export declare const createDeleteFileTool: ({ workingDir, allowedDirs, }: {
|
|
8
12
|
workingDir: string;
|
|
9
|
-
|
|
10
|
-
sendData?: SendData;
|
|
11
|
-
toolExecutor?: ToolExecutor;
|
|
13
|
+
allowedDirs?: string[];
|
|
12
14
|
}) => Promise<{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
toolDef: {
|
|
16
|
+
description: string;
|
|
17
|
+
inputSchema: z.ZodObject<{
|
|
18
|
+
path: z.ZodString;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
};
|
|
21
|
+
execute({ path: userPath }: DeleteFileInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
16
22
|
}>;
|
|
23
|
+
export {};
|
|
17
24
|
//# sourceMappingURL=delete-file.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete-file.d.ts","sourceRoot":"","sources":["../../source/tools/delete-file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"delete-file.d.ts","sourceRoot":"","sources":["../../source/tools/delete-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,cAAc;;CAE1B,CAAC;AAEF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAEH,KAAK,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEzD,eAAO,MAAM,oBAAoB,GAAU,8BAGxC;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;;;;;;;gCASyB,qBAAqB,+BACZ,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EA2DhC,CAAC"}
|
|
@@ -1,114 +1,70 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
|
-
import { tool } from "ai";
|
|
4
3
|
import { z } from "zod";
|
|
5
4
|
import style from "../terminal/style.js";
|
|
6
5
|
import { joinWorkingDir, validatePath } from "./filesystem-utils.js";
|
|
7
6
|
export const DeleteFileTool = {
|
|
8
7
|
name: "deleteFile",
|
|
9
8
|
};
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const inputSchema = z.object({
|
|
10
|
+
path: z.string().describe("Absolute path to the file to delete"),
|
|
11
|
+
});
|
|
12
|
+
export const createDeleteFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
13
|
+
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
12
14
|
return {
|
|
13
|
-
|
|
15
|
+
toolDef: {
|
|
14
16
|
description: "Delete a file permanently.",
|
|
15
|
-
inputSchema
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// Check if execution has been aborted
|
|
17
|
+
inputSchema,
|
|
18
|
+
},
|
|
19
|
+
async *execute({ path: userPath }, { toolCallId, abortSignal }) {
|
|
20
|
+
try {
|
|
20
21
|
if (abortSignal?.aborted) {
|
|
21
22
|
throw new Error("File deletion aborted");
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
+
yield {
|
|
25
|
+
name: DeleteFileTool.name,
|
|
24
26
|
id: toolCallId,
|
|
25
27
|
event: "tool-init",
|
|
26
|
-
data:
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
throw new Error(`File not found: ${filePath}`);
|
|
33
|
-
}
|
|
34
|
-
// Pre-check for stat
|
|
35
|
-
if (abortSignal?.aborted) {
|
|
36
|
-
throw new Error("File deletion aborted before stat");
|
|
37
|
-
}
|
|
38
|
-
// Ensure it's a file, not a directory
|
|
39
|
-
const stats = await fs.stat(filePath);
|
|
40
|
-
if (stats.isDirectory()) {
|
|
41
|
-
throw new Error(`Path is a directory, not a file: ${filePath}`);
|
|
42
|
-
}
|
|
43
|
-
if (terminal) {
|
|
44
|
-
terminal.writeln(`\n${style.red.bold("●")} Proposing file deletion: ${style.cyan(userPath)}`);
|
|
45
|
-
terminal.lineBreak();
|
|
46
|
-
terminal.writeln("This action cannot be undone.");
|
|
47
|
-
terminal.lineBreak();
|
|
48
|
-
let userResponse;
|
|
49
|
-
if (toolExecutor) {
|
|
50
|
-
const ctx = {
|
|
51
|
-
toolName: DeleteFileTool.name,
|
|
52
|
-
toolCallId,
|
|
53
|
-
message: "What would you like to do with this deletion?",
|
|
54
|
-
choices: {
|
|
55
|
-
accept: "Accept this deletion",
|
|
56
|
-
acceptAll: "Accept all future deletions (including this)",
|
|
57
|
-
reject: "Reject this deletion",
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
try {
|
|
61
|
-
userResponse = await toolExecutor.ask(ctx, { abortSignal });
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
if (e.name === "AbortError") {
|
|
65
|
-
throw new Error("File deletion aborted during user input");
|
|
66
|
-
}
|
|
67
|
-
throw e;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
const { result: userChoice, reason } = userResponse ?? {
|
|
71
|
-
result: "accept",
|
|
72
|
-
};
|
|
73
|
-
terminal.lineBreak();
|
|
74
|
-
if (userChoice === "accept-all") {
|
|
75
|
-
terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all deletions"));
|
|
76
|
-
terminal.lineBreak();
|
|
77
|
-
}
|
|
78
|
-
if (userChoice === "reject") {
|
|
79
|
-
terminal.lineBreak();
|
|
80
|
-
const rejectionReason = reason || "No reason provided";
|
|
81
|
-
sendData?.({
|
|
82
|
-
id: toolCallId,
|
|
83
|
-
event: "tool-completion",
|
|
84
|
-
data: `Deletion rejected by user. Reason: ${rejectionReason}`,
|
|
85
|
-
});
|
|
86
|
-
return `The user rejected this deletion. Reason: ${rejectionReason}`;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
// Pre-side-effect check
|
|
90
|
-
if (abortSignal?.aborted) {
|
|
91
|
-
throw new Error("File deletion aborted before unlink");
|
|
92
|
-
}
|
|
93
|
-
// Delete the file with signal
|
|
94
|
-
await fs.unlink(filePath);
|
|
95
|
-
sendData?.({
|
|
96
|
-
id: toolCallId,
|
|
97
|
-
event: "tool-completion",
|
|
98
|
-
data: "File deleted successfully",
|
|
99
|
-
});
|
|
100
|
-
return `Successfully deleted ${filePath}`;
|
|
28
|
+
data: `${style.cyan(userPath)}`,
|
|
29
|
+
};
|
|
30
|
+
const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory, { abortSignal });
|
|
31
|
+
// Check if file exists before attempting delete
|
|
32
|
+
if (!existsSync(filePath)) {
|
|
33
|
+
throw new Error(`File not found: ${filePath}`);
|
|
101
34
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
35
|
+
// Pre-check for stat
|
|
36
|
+
if (abortSignal?.aborted) {
|
|
37
|
+
throw new Error("File deletion aborted before stat");
|
|
38
|
+
}
|
|
39
|
+
// Ensure it's a file, not a directory
|
|
40
|
+
const stats = await fs.stat(filePath);
|
|
41
|
+
if (stats.isDirectory()) {
|
|
42
|
+
throw new Error(`Path is a directory, not a file: ${filePath}`);
|
|
43
|
+
}
|
|
44
|
+
// Pre-side-effect check
|
|
45
|
+
if (abortSignal?.aborted) {
|
|
46
|
+
throw new Error("File deletion aborted before unlink");
|
|
110
47
|
}
|
|
111
|
-
|
|
112
|
-
|
|
48
|
+
// Delete the file with signal
|
|
49
|
+
await fs.unlink(filePath);
|
|
50
|
+
yield {
|
|
51
|
+
name: DeleteFileTool.name,
|
|
52
|
+
id: toolCallId,
|
|
53
|
+
event: "tool-completion",
|
|
54
|
+
data: "File deleted",
|
|
55
|
+
};
|
|
56
|
+
yield `Successfully deleted ${filePath}`;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const errorMessage = error.message;
|
|
60
|
+
yield {
|
|
61
|
+
name: DeleteFileTool.name,
|
|
62
|
+
id: toolCallId,
|
|
63
|
+
event: "tool-error",
|
|
64
|
+
data: errorMessage,
|
|
65
|
+
};
|
|
66
|
+
yield errorMessage;
|
|
67
|
+
}
|
|
68
|
+
},
|
|
113
69
|
};
|
|
114
70
|
};
|
|
@@ -1,16 +1,26 @@
|
|
|
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 DirectoryTreeTool: {
|
|
4
6
|
name: "directoryTree";
|
|
5
7
|
};
|
|
6
|
-
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
path: z.ZodString;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
type DirectoryTreeInputSchema = z.infer<typeof inputSchema>;
|
|
12
|
+
export declare const createDirectoryTreeTool: ({ workingDir, allowedDirs, tokenCounter, }: {
|
|
7
13
|
workingDir: string;
|
|
8
|
-
|
|
14
|
+
allowedDirs?: string[];
|
|
9
15
|
tokenCounter: TokenCounter;
|
|
10
16
|
}) => Promise<{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
toolDef: {
|
|
18
|
+
description: string;
|
|
19
|
+
inputSchema: z.ZodObject<{
|
|
20
|
+
path: z.ZodString;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
};
|
|
23
|
+
execute({ path }: DirectoryTreeInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
14
24
|
}>;
|
|
15
25
|
/**
|
|
16
26
|
* Generates a string representation of a directory tree starting from the given path.
|
|
@@ -18,4 +28,5 @@ export declare const createDirectoryTreeTool: ({ workingDir, sendData, tokenCoun
|
|
|
18
28
|
* @returns A Promise that resolves to a string representation of the directory tree.
|
|
19
29
|
*/
|
|
20
30
|
export declare function directoryTree(dirPath: string): Promise<string>;
|
|
31
|
+
export {};
|
|
21
32
|
//# sourceMappingURL=directory-tree.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../../source/tools/directory-tree.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"directory-tree.d.ts","sourceRoot":"","sources":["../../source/tools/directory-tree.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,iBAAiB;;CAE7B,CAAC;AAEF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAEH,KAAK,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAE5D,eAAO,MAAM,uBAAuB,GAAU,4CAI3C;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;sBASe,wBAAwB,+BACL,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EA+DhC,CAAC;AA8CF;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAYpE"}
|