@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.
Files changed (311) hide show
  1. package/README.md +4 -2
  2. package/dist/agent/index.d.ts +119 -0
  3. package/dist/agent/index.d.ts.map +1 -0
  4. package/dist/agent/index.js +406 -0
  5. package/dist/agent/manual-loop.d.ts +41 -0
  6. package/dist/agent/manual-loop.d.ts.map +1 -0
  7. package/dist/agent/manual-loop.js +278 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +27 -33
  11. package/dist/commands/add-directory-command.d.ts +3 -0
  12. package/dist/commands/add-directory-command.d.ts.map +1 -0
  13. package/dist/commands/add-directory-command.js +85 -0
  14. package/dist/commands/application-log-command.d.ts.map +1 -1
  15. package/dist/commands/application-log-command.js +34 -0
  16. package/dist/commands/clear-command.d.ts.map +1 -1
  17. package/dist/commands/clear-command.js +8 -0
  18. package/dist/commands/compact-command.d.ts.map +1 -1
  19. package/dist/commands/compact-command.js +15 -2
  20. package/dist/commands/context-command.d.ts +3 -0
  21. package/dist/commands/context-command.d.ts.map +1 -0
  22. package/dist/commands/context-command.js +183 -0
  23. package/dist/commands/copy-command.d.ts.map +1 -1
  24. package/dist/commands/copy-command.js +28 -0
  25. package/dist/commands/edit-command.d.ts.map +1 -1
  26. package/dist/commands/edit-command.js +33 -0
  27. package/dist/commands/edit-prompt-command.d.ts.map +1 -1
  28. package/dist/commands/edit-prompt-command.js +28 -0
  29. package/dist/commands/exit-command.d.ts.map +1 -1
  30. package/dist/commands/exit-command.js +20 -0
  31. package/dist/commands/files-command.d.ts.map +1 -1
  32. package/dist/commands/files-command.js +57 -0
  33. package/dist/commands/generate-rules-command.d.ts.map +1 -1
  34. package/dist/commands/generate-rules-command.js +311 -1
  35. package/dist/commands/handoff-command.d.ts +3 -0
  36. package/dist/commands/handoff-command.d.ts.map +1 -0
  37. package/dist/commands/handoff-command.js +202 -0
  38. package/dist/commands/health-command.d.ts.map +1 -1
  39. package/dist/commands/health-command.js +119 -2
  40. package/dist/commands/help-command.d.ts.map +1 -1
  41. package/dist/commands/help-command.js +28 -0
  42. package/dist/commands/history-command.d.ts +3 -0
  43. package/dist/commands/history-command.d.ts.map +1 -0
  44. package/dist/commands/history-command.js +534 -0
  45. package/dist/commands/init-command.d.ts +1 -1
  46. package/dist/commands/init-command.d.ts.map +1 -1
  47. package/dist/commands/init-command.js +55 -18
  48. package/dist/commands/last-log-command.d.ts.map +1 -1
  49. package/dist/commands/last-log-command.js +27 -0
  50. package/dist/commands/list-directories-command.d.ts +3 -0
  51. package/dist/commands/list-directories-command.d.ts.map +1 -0
  52. package/dist/commands/list-directories-command.js +48 -0
  53. package/dist/commands/list-tools-command.d.ts.map +1 -1
  54. package/dist/commands/list-tools-command.js +66 -3
  55. package/dist/commands/manager.d.ts +15 -3
  56. package/dist/commands/manager.d.ts.map +1 -1
  57. package/dist/commands/manager.js +86 -26
  58. package/dist/commands/model-command.d.ts +22 -0
  59. package/dist/commands/model-command.d.ts.map +1 -1
  60. package/dist/commands/model-command.js +256 -0
  61. package/dist/commands/paste-command.d.ts.map +1 -1
  62. package/dist/commands/paste-command.js +92 -0
  63. package/dist/commands/pickup-command.d.ts +3 -0
  64. package/dist/commands/pickup-command.d.ts.map +1 -0
  65. package/dist/commands/pickup-command.js +161 -0
  66. package/dist/commands/prompt-command.d.ts +1 -1
  67. package/dist/commands/prompt-command.d.ts.map +1 -1
  68. package/dist/commands/prompt-command.js +117 -2
  69. package/dist/commands/remove-directory-command.d.ts +3 -0
  70. package/dist/commands/remove-directory-command.d.ts.map +1 -0
  71. package/dist/commands/remove-directory-command.js +87 -0
  72. package/dist/commands/reset-command.d.ts +1 -1
  73. package/dist/commands/reset-command.d.ts.map +1 -1
  74. package/dist/commands/reset-command.js +13 -2
  75. package/dist/commands/rules-command.d.ts.map +1 -1
  76. package/dist/commands/rules-command.js +65 -0
  77. package/dist/commands/save-command.d.ts.map +1 -1
  78. package/dist/commands/save-command.js +12 -0
  79. package/dist/commands/shell-command.d.ts.map +1 -1
  80. package/dist/commands/shell-command.js +68 -0
  81. package/dist/commands/types.d.ts +9 -4
  82. package/dist/commands/types.d.ts.map +1 -1
  83. package/dist/commands/usage-command.d.ts.map +1 -1
  84. package/dist/commands/usage-command.js +22 -0
  85. package/dist/config.d.ts +6 -7
  86. package/dist/config.d.ts.map +1 -1
  87. package/dist/config.js +23 -29
  88. package/dist/formatting.d.ts +108 -0
  89. package/dist/formatting.d.ts.map +1 -1
  90. package/dist/formatting.js +147 -0
  91. package/dist/index.d.ts +7 -2
  92. package/dist/index.d.ts.map +1 -1
  93. package/dist/index.js +140 -38
  94. package/dist/logger.d.ts.map +1 -1
  95. package/dist/logger.js +47 -18
  96. package/dist/mentions.d.ts +2 -1
  97. package/dist/mentions.d.ts.map +1 -1
  98. package/dist/mentions.js +16 -1
  99. package/dist/messages.d.ts +8 -0
  100. package/dist/messages.d.ts.map +1 -1
  101. package/dist/messages.js +56 -19
  102. package/dist/middleware/cache.d.ts +3 -0
  103. package/dist/middleware/cache.d.ts.map +1 -0
  104. package/dist/middleware/cache.js +53 -0
  105. package/dist/middleware/index.d.ts +1 -0
  106. package/dist/middleware/index.d.ts.map +1 -1
  107. package/dist/middleware/index.js +1 -0
  108. package/dist/models/ai-config.d.ts +4 -2
  109. package/dist/models/ai-config.d.ts.map +1 -1
  110. package/dist/models/ai-config.js +12 -2
  111. package/dist/models/anthropic-provider.d.ts.map +1 -1
  112. package/dist/models/anthropic-provider.js +3 -60
  113. package/dist/models/manager.d.ts +2 -1
  114. package/dist/models/manager.d.ts.map +1 -1
  115. package/dist/models/manager.js +26 -2
  116. package/dist/models/openrouter-provider.d.ts +7 -14
  117. package/dist/models/openrouter-provider.d.ts.map +1 -1
  118. package/dist/models/openrouter-provider.js +114 -169
  119. package/dist/models/providers.d.ts +1 -1
  120. package/dist/models/providers.d.ts.map +1 -1
  121. package/dist/prompts.d.ts +1 -0
  122. package/dist/prompts.d.ts.map +1 -1
  123. package/dist/prompts.js +53 -4
  124. package/dist/repl/display-tool-messages.d.ts +1 -1
  125. package/dist/repl/display-tool-messages.d.ts.map +1 -1
  126. package/dist/repl/display-tool-messages.js +47 -44
  127. package/dist/repl/get-prompt-header.d.ts.map +1 -1
  128. package/dist/repl/get-prompt-header.js +1 -30
  129. package/dist/repl/project-status-line.d.ts +2 -0
  130. package/dist/repl/project-status-line.d.ts.map +1 -0
  131. package/dist/repl/project-status-line.js +31 -0
  132. package/dist/repl/prompt.d.ts +21 -0
  133. package/dist/repl/prompt.d.ts.map +1 -0
  134. package/dist/{repl-prompt.js → repl/prompt.js} +119 -22
  135. package/dist/repl/tool-call-repair.d.ts.map +1 -1
  136. package/dist/repl/tool-call-repair.js +8 -4
  137. package/dist/repl-new.d.ts +53 -0
  138. package/dist/repl-new.d.ts.map +1 -0
  139. package/dist/repl-new.js +374 -0
  140. package/dist/repl.d.ts +3 -5
  141. package/dist/repl.d.ts.map +1 -1
  142. package/dist/repl.js +74 -166
  143. package/dist/terminal/checkbox-prompt.d.ts.map +1 -1
  144. package/dist/terminal/checkbox-prompt.js +10 -4
  145. package/dist/terminal/index.d.ts +7 -0
  146. package/dist/terminal/index.d.ts.map +1 -1
  147. package/dist/terminal/index.js +94 -0
  148. package/dist/terminal/input-prompt.d.ts +2 -1
  149. package/dist/terminal/input-prompt.d.ts.map +1 -1
  150. package/dist/terminal/markdown.js +3 -0
  151. package/dist/terminal/search-prompt.d.ts.map +1 -1
  152. package/dist/terminal/search-prompt.js +11 -10
  153. package/dist/terminal/select-prompt.d.ts +2 -2
  154. package/dist/terminal/select-prompt.d.ts.map +1 -1
  155. package/dist/terminal/select-prompt.js +47 -39
  156. package/dist/tokens/threshold.d.ts +35 -0
  157. package/dist/tokens/threshold.d.ts.map +1 -0
  158. package/dist/tokens/threshold.js +85 -0
  159. package/dist/tools/advanced-edit-file.d.ts +69 -0
  160. package/dist/tools/advanced-edit-file.d.ts.map +1 -0
  161. package/dist/tools/advanced-edit-file.js +281 -0
  162. package/dist/tools/agent.d.ts +16 -5
  163. package/dist/tools/agent.d.ts.map +1 -1
  164. package/dist/tools/agent.js +71 -58
  165. package/dist/tools/bash-utils.d.ts +1 -1
  166. package/dist/tools/bash-utils.d.ts.map +1 -1
  167. package/dist/tools/bash-utils.js +14 -6
  168. package/dist/tools/bash.d.ts +21 -12
  169. package/dist/tools/bash.d.ts.map +1 -1
  170. package/dist/tools/bash.js +88 -135
  171. package/dist/tools/code-interpreter.d.ts +21 -9
  172. package/dist/tools/code-interpreter.d.ts.map +1 -1
  173. package/dist/tools/code-interpreter.js +138 -137
  174. package/dist/tools/delete-file.d.ts +17 -10
  175. package/dist/tools/delete-file.d.ts.map +1 -1
  176. package/dist/tools/delete-file.js +51 -95
  177. package/dist/tools/directory-tree.d.ts +17 -6
  178. package/dist/tools/directory-tree.d.ts.map +1 -1
  179. package/dist/tools/directory-tree.js +47 -49
  180. package/dist/tools/dynamic-tool-loader.d.ts +18 -8
  181. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  182. package/dist/tools/dynamic-tool-loader.js +121 -129
  183. package/dist/tools/dynamic-tool-parser.d.ts +1 -0
  184. package/dist/tools/dynamic-tool-parser.d.ts.map +1 -1
  185. package/dist/tools/dynamic-tool-parser.js +1 -0
  186. package/dist/tools/edit-file.d.ts +35 -15
  187. package/dist/tools/edit-file.d.ts.map +1 -1
  188. package/dist/tools/edit-file.js +112 -112
  189. package/dist/tools/filesystem-utils.d.ts +2 -1
  190. package/dist/tools/filesystem-utils.d.ts.map +1 -1
  191. package/dist/tools/filesystem-utils.js +31 -17
  192. package/dist/tools/glob.d.ts +36 -0
  193. package/dist/tools/glob.d.ts.map +1 -0
  194. package/dist/tools/glob.js +143 -0
  195. package/dist/tools/grep.d.ts +73 -12
  196. package/dist/tools/grep.d.ts.map +1 -1
  197. package/dist/tools/grep.js +413 -168
  198. package/dist/tools/index.d.ts +204 -124
  199. package/dist/tools/index.d.ts.map +1 -1
  200. package/dist/tools/index.js +242 -135
  201. package/dist/tools/llm-edit-fixer.d.ts +25 -0
  202. package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
  203. package/dist/tools/llm-edit-fixer.js +150 -0
  204. package/dist/tools/move-file.d.ts +19 -7
  205. package/dist/tools/move-file.d.ts.map +1 -1
  206. package/dist/tools/move-file.js +40 -33
  207. package/dist/tools/read-file.d.ts +47 -9
  208. package/dist/tools/read-file.d.ts.map +1 -1
  209. package/dist/tools/read-file.js +74 -69
  210. package/dist/tools/read-multiple-files.d.ts +17 -6
  211. package/dist/tools/read-multiple-files.d.ts.map +1 -1
  212. package/dist/tools/read-multiple-files.js +76 -73
  213. package/dist/tools/save-file.d.ts +45 -12
  214. package/dist/tools/save-file.d.ts.map +1 -1
  215. package/dist/tools/save-file.js +58 -101
  216. package/dist/tools/think.d.ts +15 -7
  217. package/dist/tools/think.d.ts.map +1 -1
  218. package/dist/tools/think.js +30 -22
  219. package/dist/tools/types.d.ts +4 -10
  220. package/dist/tools/types.d.ts.map +1 -1
  221. package/dist/tools/types.js +9 -0
  222. package/dist/tools/utils.d.ts +14 -0
  223. package/dist/tools/utils.d.ts.map +1 -0
  224. package/dist/tools/utils.js +16 -0
  225. package/dist/tools/web-fetch.d.ts +11 -4
  226. package/dist/tools/web-fetch.d.ts.map +1 -1
  227. package/dist/tools/web-fetch.js +39 -38
  228. package/dist/tools/web-search.d.ts +15 -6
  229. package/dist/tools/web-search.d.ts.map +1 -1
  230. package/dist/tools/web-search.js +50 -32
  231. package/dist/tui/autocomplete.d.ts +44 -0
  232. package/dist/tui/autocomplete.d.ts.map +1 -0
  233. package/dist/tui/autocomplete.js +466 -0
  234. package/dist/tui/components/assistant-message.d.ts +18 -0
  235. package/dist/tui/components/assistant-message.d.ts.map +1 -0
  236. package/dist/tui/components/assistant-message.js +29 -0
  237. package/dist/tui/components/editor.d.ts +51 -0
  238. package/dist/tui/components/editor.d.ts.map +1 -0
  239. package/dist/tui/components/editor.js +758 -0
  240. package/dist/tui/components/footer.d.ts +24 -0
  241. package/dist/tui/components/footer.d.ts.map +1 -0
  242. package/dist/tui/components/footer.js +197 -0
  243. package/dist/tui/components/input.d.ts +14 -0
  244. package/dist/tui/components/input.d.ts.map +1 -0
  245. package/dist/tui/components/input.js +122 -0
  246. package/dist/tui/components/loader.d.ts +19 -0
  247. package/dist/tui/components/loader.d.ts.map +1 -0
  248. package/dist/tui/components/loader.js +45 -0
  249. package/dist/tui/components/markdown.d.ts +103 -0
  250. package/dist/tui/components/markdown.d.ts.map +1 -0
  251. package/dist/tui/components/markdown.js +533 -0
  252. package/dist/tui/components/modal.d.ts +40 -0
  253. package/dist/tui/components/modal.d.ts.map +1 -0
  254. package/dist/tui/components/modal.js +292 -0
  255. package/dist/tui/components/prompt-status.d.ts +16 -0
  256. package/dist/tui/components/prompt-status.d.ts.map +1 -0
  257. package/dist/tui/components/prompt-status.js +21 -0
  258. package/dist/tui/components/select-list.d.ts +22 -0
  259. package/dist/tui/components/select-list.d.ts.map +1 -0
  260. package/dist/tui/components/select-list.js +143 -0
  261. package/dist/tui/components/spacer.d.ts +16 -0
  262. package/dist/tui/components/spacer.d.ts.map +1 -0
  263. package/dist/tui/components/spacer.js +27 -0
  264. package/dist/tui/components/text.d.ts +26 -0
  265. package/dist/tui/components/text.d.ts.map +1 -0
  266. package/dist/tui/components/text.js +143 -0
  267. package/dist/tui/components/thinking-block.d.ts +14 -0
  268. package/dist/tui/components/thinking-block.d.ts.map +1 -0
  269. package/dist/tui/components/thinking-block.js +30 -0
  270. package/dist/tui/components/tool-execution.d.ts +17 -0
  271. package/dist/tui/components/tool-execution.d.ts.map +1 -0
  272. package/dist/tui/components/tool-execution.js +153 -0
  273. package/dist/tui/components/user-message.d.ts +9 -0
  274. package/dist/tui/components/user-message.d.ts.map +1 -0
  275. package/dist/tui/components/user-message.js +21 -0
  276. package/dist/tui/components/welcome.d.ts +6 -0
  277. package/dist/tui/components/welcome.d.ts.map +1 -0
  278. package/dist/tui/components/welcome.js +30 -0
  279. package/dist/tui/index.d.ts +14 -0
  280. package/dist/tui/index.d.ts.map +1 -0
  281. package/dist/tui/index.js +18 -0
  282. package/dist/tui/terminal.d.ts +37 -0
  283. package/dist/tui/terminal.d.ts.map +1 -0
  284. package/dist/tui/terminal.js +104 -0
  285. package/dist/tui/tui.d.ts +67 -0
  286. package/dist/tui/tui.d.ts.map +1 -0
  287. package/dist/tui/tui.js +184 -0
  288. package/dist/tui/utils.d.ts +19 -0
  289. package/dist/tui/utils.d.ts.map +1 -0
  290. package/dist/tui/utils.js +31 -0
  291. package/dist/utils/generators.d.ts +3 -0
  292. package/dist/utils/generators.d.ts.map +1 -0
  293. package/dist/utils/generators.js +25 -0
  294. package/dist/utils/iterables.d.ts +2 -0
  295. package/dist/utils/iterables.d.ts.map +1 -0
  296. package/dist/utils/iterables.js +6 -0
  297. package/package.json +16 -16
  298. package/dist/conversation-analyzer.d.ts +0 -11
  299. package/dist/conversation-analyzer.d.ts.map +0 -1
  300. package/dist/conversation-analyzer.js +0 -88
  301. package/dist/repl-prompt.d.ts +0 -15
  302. package/dist/repl-prompt.d.ts.map +0 -1
  303. package/dist/tokens/manage-output.d.ts +0 -34
  304. package/dist/tokens/manage-output.d.ts.map +0 -1
  305. package/dist/tokens/manage-output.js +0 -44
  306. package/dist/tool-executor.d.ts +0 -28
  307. package/dist/tool-executor.d.ts.map +0 -1
  308. package/dist/tool-executor.js +0 -74
  309. package/dist/tools/file-editing-utils.d.ts +0 -2
  310. package/dist/tools/file-editing-utils.d.ts.map +0 -1
  311. package/dist/tools/file-editing-utils.js +0 -135
@@ -1,9 +1,9 @@
1
- import { generateText, stepCountIs, tool } from "ai";
1
+ import { generateText, stepCountIs } from "ai";
2
2
  import { z } from "zod";
3
3
  import { AiConfig } from "../models/ai-config.js";
4
4
  import style from "../terminal/style.js";
5
- import { BashTool } from "./bash.js";
6
- // import { DirectoryTreeTool } from "./directory-tree.ts";
5
+ import { DirectoryTreeTool } from "./directory-tree.js";
6
+ import { GlobTool } from "./glob.js";
7
7
  import { GrepTool } from "./grep.js";
8
8
  import { initCliTools } from "./index.js";
9
9
  import { ReadFileTool } from "./read-file.js";
@@ -13,18 +13,24 @@ export const AgentTool = {
13
13
  };
14
14
  const TOOLS = [
15
15
  GrepTool.name,
16
- BashTool.name,
16
+ GlobTool.name,
17
17
  ReadFileTool.name,
18
18
  ReadMultipleFilesTool.name,
19
- // DirectoryTreeTool.name,
19
+ DirectoryTreeTool.name,
20
20
  ];
21
21
  function getToolDescription() {
22
22
  const toolNames = TOOLS.join(", ");
23
- return `Launch a new agent that has access to the following tools: ${toolNames}. When you are searching for a keyword or file and are not confident that you will find the right match on the first try, use the ${AgentTool.name} tool to perform the search for you. For example:
23
+ return `Launch a new agent that has access to the following tools: ${toolNames}. This agent is specifically designed for file discovery and code search tasks. Use the ${AgentTool.name} tool when you need to search for files or code patterns across the codebase.
24
24
 
25
- - If you are searching for a keyword like "config" or "logger", the ${AgentTool.name} tool is appropriate
26
- - If you want to read a specific file path, use the ${ReadFileTool.name} or appropriate command via the ${BashTool.name} tool instead of this tool, to find the match more quickly
27
- - If you are searching for a specific class definition like "class Foo", use the ${GrepTool.name} tool instead, to find the match more quickly
25
+ Use cases:
26
+ - Search for files matching specific patterns (e.g., "*.ts", "**/*.test.ts") using ${GlobTool.name}
27
+ - Find code patterns or text within files using ${GrepTool.name}
28
+ - Read specific files or multiple files using ${ReadFileTool.name} and ${ReadMultipleFilesTool.name}
29
+
30
+ Important limitations:
31
+ - This agent cannot execute shell commands or run external tools
32
+ - It is focused purely on file discovery and content reading
33
+ - For complex operations or command execution, use the main assistant directly
28
34
 
29
35
  Usage notes:
30
36
  1. Launch multiple agents concurrently whenever possible, to maximize performance; to do that, use a single message with multiple tool uses
@@ -36,55 +42,62 @@ const inputSchema = z.object({
36
42
  prompt: z.string().describe("The task for the agent to perform"),
37
43
  });
38
44
  export const createAgentTools = (options) => {
39
- const { modelManager, tokenTracker, tokenCounter, sendData } = options;
45
+ const { modelManager, tokenTracker, tokenCounter } = options;
46
+ const toolDef = {
47
+ description: getToolDescription(),
48
+ inputSchema,
49
+ };
50
+ async function* execute({ prompt }, { toolCallId, abortSignal }) {
51
+ if (abortSignal?.aborted) {
52
+ throw new Error("Agent execution aborted");
53
+ }
54
+ yield {
55
+ name: AgentTool.name,
56
+ event: "tool-init",
57
+ id: toolCallId,
58
+ data: `\n${style.cyan(prompt)}`,
59
+ };
60
+ try {
61
+ const modelConfig = modelManager.getModelMetadata("task-agent");
62
+ const aiConfig = new AiConfig({
63
+ modelMetadata: modelConfig,
64
+ prompt: prompt,
65
+ });
66
+ const { text, usage } = await generateText({
67
+ model: modelManager.getModel("task-agent"),
68
+ maxOutputTokens: aiConfig.maxOutputTokens(),
69
+ system: "You are a code search assistant that will be given a task that will require you to search a code base to find relevant code and files.",
70
+ prompt: prompt,
71
+ temperature: aiConfig.temperature(),
72
+ topP: aiConfig.topP(),
73
+ stopWhen: stepCountIs(30),
74
+ providerOptions: aiConfig.providerOptions(),
75
+ tools: (await initCliTools({ tokenCounter, workspace: options.workspace })).toolDefs,
76
+ abortSignal: abortSignal,
77
+ // biome-ignore lint/style/useNamingConvention: third-party code
78
+ experimental_activeTools: [...TOOLS],
79
+ });
80
+ tokenTracker.trackUsage("task-agent", usage);
81
+ yield {
82
+ name: AgentTool.name,
83
+ event: "tool-completion",
84
+ id: toolCallId,
85
+ data: `Finished running the agent tool (${usage.totalTokens} tokens)`,
86
+ };
87
+ yield text;
88
+ }
89
+ catch (error) {
90
+ yield {
91
+ name: AgentTool.name,
92
+ event: "tool-error",
93
+ id: toolCallId,
94
+ data: error.message,
95
+ };
96
+ yield error.message;
97
+ }
98
+ }
40
99
  return {
41
- [AgentTool.name]: tool({
42
- description: getToolDescription(),
43
- inputSchema: inputSchema,
44
- execute: async ({ prompt }, { abortSignal, toolCallId }) => {
45
- if (abortSignal?.aborted) {
46
- throw new Error("Agent execution aborted");
47
- }
48
- sendData?.({
49
- event: "tool-init",
50
- id: toolCallId,
51
- data: `Initializing agent with prompt: ${style.cyan(prompt)}`,
52
- });
53
- try {
54
- const modelConfig = modelManager.getModelMetadata("task-agent");
55
- const aiConfig = new AiConfig({
56
- modelMetadata: modelConfig,
57
- prompt: prompt,
58
- });
59
- const { text, usage } = await generateText({
60
- model: modelManager.getModel("task-agent"),
61
- maxOutputTokens: aiConfig.getMaxTokens(),
62
- system: "You are a code search assistant that will be given a task that will require you to search a code base to find relevant code and files.",
63
- prompt: prompt,
64
- stopWhen: stepCountIs(30),
65
- providerOptions: aiConfig.getProviderOptions(),
66
- tools: await initCliTools({ tokenCounter }),
67
- abortSignal: abortSignal,
68
- // biome-ignore lint/style/useNamingConvention: third-party code
69
- experimental_activeTools: [...TOOLS],
70
- });
71
- tokenTracker.trackUsage("task-agent", usage);
72
- sendData?.({
73
- event: "tool-completion",
74
- id: toolCallId,
75
- data: "Finished running the agent tool.",
76
- });
77
- return text;
78
- }
79
- catch (error) {
80
- sendData?.({
81
- event: "tool-error",
82
- id: toolCallId,
83
- data: "Error running agent tool.",
84
- });
85
- return Promise.resolve(error.message);
86
- }
87
- },
88
- }),
100
+ toolDef,
101
+ execute,
89
102
  };
90
103
  };
@@ -1,4 +1,4 @@
1
- export declare function validatePaths(command: string, baseDir: string, cwd: string): {
1
+ export declare function validatePaths(command: string, allowedDirs: string[], cwd: string, allowedPaths?: string[]): {
2
2
  isValid: boolean;
3
3
  error?: string;
4
4
  };
@@ -1 +1 @@
1
- {"version":3,"file":"bash-utils.d.ts","sourceRoot":"","sources":["../../source/tools/bash-utils.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACV;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiEtC;AAED,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,YAAY,MAAM,KACjB,MAiDF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,OAmHtD,CAAC"}
1
+ {"version":3,"file":"bash-utils.d.ts","sourceRoot":"","sources":["../../source/tools/bash-utils.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,MAAM,EACX,YAAY,CAAC,EAAE,MAAM,EAAE,GACtB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgFtC;AAED,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,YAAY,MAAM,KACjB,MAiDF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,OAmHtD,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import fs from "node:fs";
2
+ import os from "node:os";
2
3
  import path from "node:path";
3
- import { isPathWithinBaseDir } from "./filesystem-utils.js";
4
+ import { isPathWithinAllowedDirs } from "./filesystem-utils.js";
4
5
  // Validate path arguments to ensure they're within the project
5
- export function validatePaths(command, baseDir, cwd) {
6
+ export function validatePaths(command, allowedDirs, cwd, allowedPaths) {
6
7
  // Simple tokenization - split on spaces but respect quotes
7
8
  const tokens = [];
8
9
  let current = "";
@@ -43,7 +44,7 @@ export function validatePaths(command, baseDir, cwd) {
43
44
  // Skip if it's clearly not a path
44
45
  if (cleanToken.startsWith("-") ||
45
46
  cleanToken.includes("://") ||
46
- !cleanToken.includes("/")) {
47
+ (!cleanToken.includes("/") && cleanToken !== "~")) {
47
48
  continue;
48
49
  }
49
50
  // Skip git commit messages and other special cases
@@ -52,11 +53,18 @@ export function validatePaths(command, baseDir, cwd) {
52
53
  continue;
53
54
  }
54
55
  try {
55
- const resolvedPath = path.resolve(cwd, cleanToken);
56
- if (!isPathWithinBaseDir(resolvedPath, baseDir)) {
56
+ // Expand ~ to home directory for proper validation
57
+ const expandedToken = cleanToken.startsWith("~/") || cleanToken === "~"
58
+ ? path.join(os.homedir(), cleanToken.slice(1))
59
+ : cleanToken;
60
+ const resolvedPath = path.resolve(cwd, expandedToken);
61
+ // Allow access to explicitly allowed paths
62
+ const isAllowedPath = allowedPaths?.some((allowedPath) => resolvedPath === path.resolve(allowedPath));
63
+ if (!isAllowedPath &&
64
+ !isPathWithinAllowedDirs(resolvedPath, allowedDirs)) {
57
65
  return {
58
66
  isValid: false,
59
- error: `Path '${cleanToken}' resolves outside the project directory (${resolvedPath}). All paths must be within ${baseDir}`,
67
+ error: `Path '${cleanToken}' resolves outside the allowed directories (${resolvedPath}). All paths must be within ${allowedDirs.join(", ")}`,
60
68
  };
61
69
  }
62
70
  }
@@ -1,21 +1,30 @@
1
- import type { Terminal } from "../terminal/index.ts";
1
+ import type { ToolCallOptions } from "ai";
2
+ import { z } from "zod";
2
3
  import type { TokenCounter } from "../tokens/counter.ts";
3
- import type { ToolExecutor } from "../tool-executor.ts";
4
- import type { SendData } from "./types.ts";
4
+ import type { ToolResult } from "./types.ts";
5
5
  export declare const BashTool: {
6
6
  name: "bash";
7
7
  };
8
- export declare const createBashTool: ({ baseDir, sendData, tokenCounter, terminal, toolExecutor, }: {
8
+ declare const inputSchema: z.ZodObject<{
9
+ command: z.ZodString;
10
+ cwd: z.ZodNullable<z.ZodString>;
11
+ timeout: z.ZodNullable<z.ZodCoercedNumber<unknown>>;
12
+ }, z.core.$strip>;
13
+ type BashInputSchema = z.infer<typeof inputSchema>;
14
+ export declare const createBashTool: ({ baseDir, allowedDirs, tokenCounter, }: {
9
15
  baseDir: string;
10
- sendData?: SendData;
16
+ allowedDirs?: string[];
11
17
  tokenCounter: TokenCounter;
12
- terminal?: Terminal;
13
- toolExecutor?: ToolExecutor;
14
18
  }) => Promise<{
15
- bash: import("ai").Tool<{
16
- command: string;
17
- cwd: string | null;
18
- timeout: number | null;
19
- }, string>;
19
+ toolDef: {
20
+ description: string;
21
+ inputSchema: z.ZodObject<{
22
+ command: z.ZodString;
23
+ cwd: z.ZodNullable<z.ZodString>;
24
+ timeout: z.ZodNullable<z.ZodCoercedNumber<unknown>>;
25
+ }, z.core.$strip>;
26
+ };
27
+ execute({ command, cwd, timeout }: BashInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
20
28
  }>;
29
+ export {};
21
30
  //# sourceMappingURL=bash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,QAAQ;;CAEpB,CAAC;AAKF,eAAO,MAAM,cAAc,GAAU,8DAMlC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;;;;;;EAkLA,CAAC"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/tools/bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,QAAQ;;CAEpB,CAAC;AAKF,QAAA,MAAM,WAAW;;;;iBAcf,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEnD,eAAO,MAAM,cAAc,GAAU,yCAIlC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;;;uCAcgC,eAAe,+BACb,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EAyFhC,CAAC"}
@@ -1,155 +1,108 @@
1
- import { tool } from "ai";
2
1
  import { z } from "zod";
3
2
  import { config } from "../config.js";
4
3
  import { initExecutionEnvironment } from "../execution/index.js";
5
4
  import { logger } from "../logger.js";
6
5
  import style from "../terminal/style.js";
6
+ import { manageTokenLimit } from "../tokens/threshold.js";
7
7
  import { isMutatingCommand, resolveCwd, validatePaths } from "./bash-utils.js";
8
- import { isPathWithinBaseDir } from "./filesystem-utils.js";
8
+ import { isPathWithinAllowedDirs } from "./filesystem-utils.js";
9
9
  export const BashTool = {
10
10
  name: "bash",
11
11
  };
12
12
  // Command execution timeout in milliseconds
13
13
  const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
14
- export const createBashTool = async ({ baseDir, sendData, tokenCounter, terminal, toolExecutor, }) => {
14
+ const inputSchema = z.object({
15
+ command: z.string().describe("Full CLI command to execute."),
16
+ cwd: z
17
+ .string()
18
+ .nullable()
19
+ .describe("Working directory file path (default: project root). Must be within the project directory."),
20
+ timeout: z.coerce
21
+ .number()
22
+ .nullable()
23
+ .describe(`Command execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT}ms`),
24
+ });
25
+ export const createBashTool = async ({ baseDir, allowedDirs, tokenCounter, }) => {
15
26
  const execEnv = await initExecutionEnvironment();
27
+ const projectConfig = await config.readProjectConfig();
28
+ const allowedPaths = projectConfig.logs?.path
29
+ ? [projectConfig.logs.path]
30
+ : [];
31
+ const allowedDirectories = allowedDirs ?? [baseDir];
16
32
  return {
17
- [BashTool.name]: tool({
33
+ toolDef: {
18
34
  description: "Execute commands in a shell. Commands execute only within the project directory. Always use absolute paths.",
19
- inputSchema: z.object({
20
- command: z.string().describe("Full CLI command to execute."),
21
- cwd: z
22
- .string()
23
- .nullable()
24
- .describe("Working directory file path (default: project root). Must be within the project directory."),
25
- timeout: z.coerce
26
- .number()
27
- .nullable()
28
- .describe(`Command execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT}ms`),
29
- }),
30
- execute: async ({ command, cwd, timeout }, { toolCallId, abortSignal }) => {
31
- try {
32
- if (abortSignal?.aborted) {
33
- throw new Error("Command execution aborted");
34
- }
35
- // grok doesn't follow my instructions
36
- const safeCwd = cwd === "null" ? null : cwd;
37
- const resolvedCwd = resolveCwd(safeCwd, baseDir);
38
- const safeTimeout = timeout ?? DEFAULT_TIMEOUT;
39
- sendData?.({
40
- event: "tool-init",
41
- id: toolCallId,
42
- data: `Executing: ${style.cyan(command)} in ${style.cyan(resolvedCwd)}`,
43
- });
44
- if (!isPathWithinBaseDir(resolvedCwd, baseDir)) {
45
- const errorMsg = `Working directory must be within the project directory: ${baseDir}`;
46
- sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
47
- return errorMsg;
48
- }
49
- const pathValidation = validatePaths(command, baseDir, resolvedCwd);
50
- if (!pathValidation.isValid) {
51
- sendData?.({
52
- event: "tool-error",
53
- id: toolCallId,
54
- data: pathValidation.error ?? "Unknown error.",
55
- });
56
- return pathValidation.error ?? "Unknown error.";
57
- }
58
- if (terminal) {
59
- let userResponse;
60
- // Prompt only for potentially mutating commands when a toolExecutor is present
61
- if (toolExecutor && isMutatingCommand(command)) {
62
- // Display if autoAccept is false
63
- if (!toolExecutor.autoAccept(BashTool.name)) {
64
- terminal.writeln(`\n${style.blue.bold("●")} Proposing to execute command: ${style.cyan(command)} in ${style.cyan(resolvedCwd)}`);
65
- terminal.lineBreak();
66
- }
67
- const ctx = {
68
- toolName: BashTool.name,
69
- toolCallId,
70
- message: "What would you like to do with this command execution?",
71
- choices: {
72
- accept: "Execute this command",
73
- acceptAll: "Accept all future command executions (including this)",
74
- reject: "Reject this command execution",
75
- },
76
- };
77
- try {
78
- userResponse = await toolExecutor.ask(ctx, { abortSignal });
79
- }
80
- catch (e) {
81
- if (e.name === "AbortError") {
82
- throw new Error("Command execution aborted during user input");
83
- }
84
- throw e;
85
- }
86
- }
87
- const { result: userChoice, reason } = userResponse ?? {
88
- result: "accept",
89
- };
90
- terminal.lineBreak();
91
- if (userChoice === "accept-all") {
92
- terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all command executions"));
93
- terminal.lineBreak();
94
- }
95
- if (userChoice === "reject") {
96
- terminal.lineBreak();
97
- const rejectionReason = reason || "No reason provided";
98
- sendData?.({
99
- event: "tool-completion",
100
- id: toolCallId,
101
- data: `Command execution rejected by user. Reason: ${rejectionReason}`,
102
- });
103
- return `The user rejected this command execution. Reason: ${rejectionReason}`;
104
- }
105
- }
106
- if (abortSignal?.aborted) {
107
- throw new Error("Command execution aborted before running the command");
108
- }
109
- terminal?.startProgress();
110
- const { output, exitCode } = await execEnv.executeCommand(command, {
111
- cwd: resolvedCwd,
112
- timeout: safeTimeout,
113
- abortSignal,
114
- preserveOutputOnError: true,
115
- captureStderr: true,
116
- throwOnError: false,
117
- });
118
- sendData?.({
119
- event: "tool-update",
35
+ inputSchema,
36
+ },
37
+ async *execute({ command, cwd, timeout }, { toolCallId, abortSignal }) {
38
+ try {
39
+ if (abortSignal?.aborted) {
40
+ throw new Error("Command execution aborted");
41
+ }
42
+ // grok doesn't follow my instructions
43
+ const safeCwd = cwd === "null" ? null : cwd;
44
+ const resolvedCwd = resolveCwd(safeCwd, baseDir);
45
+ const safeTimeout = timeout ?? DEFAULT_TIMEOUT;
46
+ // Safety warning for potentially mutating commands
47
+ const isMutating = isMutatingCommand(command);
48
+ yield {
49
+ name: BashTool.name,
50
+ event: "tool-init",
51
+ id: toolCallId,
52
+ data: `${style.cyan(command)}${isMutating ? " *" : ""}`,
53
+ };
54
+ if (!isPathWithinAllowedDirs(resolvedCwd, allowedDirectories)) {
55
+ const errorMsg = `Working directory must be within the allowed directories: ${allowedDirectories.join(", ")}`;
56
+ yield {
57
+ name: BashTool.name,
58
+ event: "tool-error",
120
59
  id: toolCallId,
121
- data: {
122
- primary: "Result",
123
- secondary: output.trim().split("\n").slice(-20),
124
- },
125
- });
126
- let tokenCount = 0;
127
- try {
128
- tokenCount = tokenCounter.count(output);
129
- }
130
- catch (tokenError) {
131
- console.info("Error calculating token count:", tokenError);
132
- }
133
- const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
134
- const maxTokenMessage = `Output of command (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}). Please adjust how you call the command to get back more specific results.`;
135
- const finalResult = tokenCount <= maxTokens ? output : maxTokenMessage;
136
- sendData?.({
137
- event: "tool-completion",
60
+ data: errorMsg,
61
+ };
62
+ yield errorMsg;
63
+ return;
64
+ }
65
+ const pathValidation = validatePaths(command, allowedDirectories, resolvedCwd, allowedPaths);
66
+ if (!pathValidation.isValid) {
67
+ yield {
68
+ name: BashTool.name,
69
+ event: "tool-error",
138
70
  id: toolCallId,
139
- data: tokenCount <= maxTokens
140
- ? `Command executed successfully: ${exitCode} (${tokenCount} tokens)`
141
- : `Output of command (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}).`,
142
- });
143
- terminal?.stopProgress();
144
- return finalResult;
71
+ data: pathValidation.error ?? "Unknown error.",
72
+ };
73
+ yield pathValidation.error ?? "Unknown error.";
74
+ return;
145
75
  }
146
- catch (error) {
147
- logger.error(error, "Bash Tool Error:");
148
- const errorMsg = `Command failed: ${error.message}`;
149
- sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
150
- return errorMsg;
76
+ if (abortSignal?.aborted) {
77
+ throw new Error("Command execution aborted before running the command");
151
78
  }
152
- },
153
- }),
79
+ const { output, exitCode } = await execEnv.executeCommand(command, {
80
+ cwd: resolvedCwd,
81
+ timeout: safeTimeout,
82
+ abortSignal,
83
+ preserveOutputOnError: true,
84
+ captureStderr: true,
85
+ throwOnError: false,
86
+ });
87
+ const result = await manageTokenLimit(output, tokenCounter, "Bash", "Adjust command to return more specific results");
88
+ yield {
89
+ name: BashTool.name,
90
+ event: "tool-completion",
91
+ id: toolCallId,
92
+ data: `${exitCode} (${result.tokenCount} tokens)`,
93
+ };
94
+ yield result.content;
95
+ }
96
+ catch (error) {
97
+ logger.error(error, "Bash Tool Error:");
98
+ yield {
99
+ name: BashTool.name,
100
+ event: "tool-error",
101
+ id: toolCallId,
102
+ data: error.message,
103
+ };
104
+ yield error.message;
105
+ }
106
+ },
154
107
  };
155
108
  };
@@ -1,13 +1,25 @@
1
- import type { SendData } from "./types.ts";
1
+ import type { ToolCallOptions } from "ai";
2
+ import { z } from "zod";
3
+ import type { TokenCounter } from "../tokens/counter.ts";
4
+ import type { ToolResult } from "./types.ts";
2
5
  export declare const CodeInterpreterTool: {
3
6
  name: "codeInterpreter";
4
7
  };
5
- export declare const createCodeInterpreterTool: ({ sendData, }: Readonly<{
6
- sendData?: SendData | undefined;
7
- }>) => {
8
- codeInterpreter: import("ai").Tool<{
9
- code: string;
10
- timeoutSeconds: number | null;
11
- }, string>;
12
- };
8
+ declare const inputSchema: z.ZodObject<{
9
+ code: z.ZodString;
10
+ timeoutSeconds: z.ZodNullable<z.ZodNumber>;
11
+ }, z.core.$strip>;
12
+ export declare const createCodeInterpreterTool: ({ tokenCounter, }: {
13
+ tokenCounter: TokenCounter;
14
+ }) => Promise<{
15
+ toolDef: {
16
+ description: string;
17
+ inputSchema: z.ZodObject<{
18
+ code: z.ZodString;
19
+ timeoutSeconds: z.ZodNullable<z.ZodNumber>;
20
+ }, z.core.$strip>;
21
+ };
22
+ execute: ({ code, timeoutSeconds }: z.infer<typeof inputSchema>, { toolCallId, abortSignal }: ToolCallOptions) => AsyncGenerator<ToolResult>;
23
+ }>;
24
+ export {};
13
25
  //# sourceMappingURL=code-interpreter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"code-interpreter.d.ts","sourceRoot":"","sources":["../../source/tools/code-interpreter.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AAmBF,eAAO,MAAM,yBAAyB,GAAI,eAEvC,QAAQ,CAAC;IACV,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;CACjC,CAAC;;;;;CAiLD,CAAC"}
1
+ {"version":3,"file":"code-interpreter.d.ts","sourceRoot":"","sources":["../../source/tools/code-interpreter.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,mBAAmB;;CAE/B,CAAC;AAmBF,QAAA,MAAM,WAAW;;;iBASf,CAAC;AAEH,eAAO,MAAM,yBAAyB,GAAU,mBAE7C;IACD,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;;wCAO6B,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACxB,eAAe,KAC3C,cAAc,CAAC,UAAU,CAAC;EAqK9B,CAAC"}