@travisennis/acai 0.0.1 → 0.0.2

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 (323) hide show
  1. package/README.md +3 -4
  2. package/dist/commands/health-command.d.ts +2 -0
  3. package/dist/commands/health-command.js +59 -0
  4. package/dist/commands/manager.js +2 -0
  5. package/dist/commands/paste-command.d.ts +1 -1
  6. package/dist/commands/paste-command.js +155 -11
  7. package/dist/commands/reset-command.js +1 -0
  8. package/dist/index.js +1 -1
  9. package/dist/models/openrouter-provider.d.ts +4 -1
  10. package/dist/models/openrouter-provider.js +46 -4
  11. package/dist/models/providers.d.ts +1 -1
  12. package/dist/prompts/manager.d.ts +1 -0
  13. package/dist/prompts/manager.js +10 -0
  14. package/dist/prompts.js +8 -6
  15. package/dist/repl.js +49 -26
  16. package/dist/terminal/formatting.d.ts +16 -5
  17. package/dist/terminal/formatting.js +40 -6
  18. package/dist/terminal/index.d.ts +1 -1
  19. package/dist/terminal/index.js +54 -14
  20. package/dist/terminal/markdown.js +0 -1
  21. package/dist/terminal/supports-color.d.ts +16 -0
  22. package/dist/terminal/supports-color.js +121 -0
  23. package/dist/terminal/supports-hyperlinks.d.ts +7 -0
  24. package/dist/terminal/supports-hyperlinks.js +98 -0
  25. package/dist/tools/bash.js +95 -117
  26. package/dist/tools/code-interpreter.js +11 -1
  27. package/dist/tools/command-validation.d.ts +7 -3
  28. package/dist/tools/command-validation.js +67 -23
  29. package/dist/tools/delete-file.d.ts +4 -1
  30. package/dist/tools/delete-file.js +47 -3
  31. package/dist/tools/git-utils.d.ts +6 -0
  32. package/dist/tools/git-utils.js +89 -12
  33. package/dist/tools/grep.d.ts +20 -0
  34. package/dist/tools/grep.js +128 -40
  35. package/dist/tools/index.d.ts +2 -18
  36. package/dist/tools/index.js +4 -18
  37. package/package.json +30 -20
  38. package/.acai/acai.json +0 -9
  39. package/.acai/prompts/add-openrouter-model.md +0 -13
  40. package/.acai/prompts/project-status.md +0 -4
  41. package/.acai/prompts/update-architecture-document.md +0 -9
  42. package/.acai/rules/learned-rules.md +0 -9
  43. package/.ai/docs/available-tools.txt +0 -3
  44. package/.ai/docs/cognitive_complexity_refactoring_progress.md +0 -65
  45. package/.ai/docs/deleted_tools.md +0 -168
  46. package/.ai/docs/deleted_tools_88ced9ef.md +0 -56
  47. package/.ai/docs/image-pasting.md +0 -46
  48. package/.ai/docs/initialize-app.md +0 -117
  49. package/.ai/docs/issue-4-plan.md +0 -44
  50. package/.ai/docs/marked-renderer-debug.md +0 -15
  51. package/.ai/docs/marked-renderer-refactor-plan.md +0 -64
  52. package/.ai/docs/memory-use-cases.md +0 -55
  53. package/.ai/docs/prompt-consistency.md +0 -31
  54. package/.ai/docs/refactoring-tools.md +0 -98
  55. package/.ai/docs/system-prompt-update.md +0 -174
  56. package/.ai/docs/system_prompt.txt +0 -210
  57. package/.ai/docs/tasks.md +0 -49
  58. package/.ai/plan.md +0 -131
  59. package/.ai/prompt.md +0 -1
  60. package/.ai/scripts/fetch_models.js +0 -27
  61. package/.ai/scripts/generateSystemPrompt.ts +0 -15
  62. package/.ai/scripts/list-tools.mjs +0 -4
  63. package/.ai/scripts/p5_geometric_shapes.js +0 -149
  64. package/.husky/commit-msg +0 -1
  65. package/.husky/pre-commit +0 -3
  66. package/.husky/pre-push +0 -1
  67. package/.ignore +0 -4
  68. package/AGENTS.md +0 -25
  69. package/ARCHITECTURE.md +0 -304
  70. package/TODO.md +0 -2
  71. package/biome.json +0 -61
  72. package/commitlint.config.js +0 -3
  73. package/dist/source/cli.d.ts +0 -19
  74. package/dist/source/cli.js +0 -116
  75. package/dist/source/commands/application-log-command.d.ts +0 -2
  76. package/dist/source/commands/application-log-command.js +0 -43
  77. package/dist/source/commands/clear-command.d.ts +0 -2
  78. package/dist/source/commands/clear-command.js +0 -12
  79. package/dist/source/commands/compact-command.d.ts +0 -2
  80. package/dist/source/commands/compact-command.js +0 -51
  81. package/dist/source/commands/copy-command.d.ts +0 -2
  82. package/dist/source/commands/copy-command.js +0 -51
  83. package/dist/source/commands/edit-command.d.ts +0 -2
  84. package/dist/source/commands/edit-command.js +0 -53
  85. package/dist/source/commands/edit-prompt-command.d.ts +0 -2
  86. package/dist/source/commands/edit-prompt-command.js +0 -25
  87. package/dist/source/commands/exit-command.d.ts +0 -2
  88. package/dist/source/commands/exit-command.js +0 -14
  89. package/dist/source/commands/files-command.d.ts +0 -2
  90. package/dist/source/commands/files-command.js +0 -63
  91. package/dist/source/commands/generate-rules-command.d.ts +0 -2
  92. package/dist/source/commands/generate-rules-command.js +0 -61
  93. package/dist/source/commands/help-command.d.ts +0 -2
  94. package/dist/source/commands/help-command.js +0 -19
  95. package/dist/source/commands/init-command.d.ts +0 -2
  96. package/dist/source/commands/init-command.js +0 -40
  97. package/dist/source/commands/last-log-command.d.ts +0 -2
  98. package/dist/source/commands/last-log-command.js +0 -76
  99. package/dist/source/commands/manager.d.ts +0 -22
  100. package/dist/source/commands/manager.js +0 -123
  101. package/dist/source/commands/model-command.d.ts +0 -2
  102. package/dist/source/commands/model-command.js +0 -84
  103. package/dist/source/commands/paste-command.d.ts +0 -2
  104. package/dist/source/commands/paste-command.js +0 -40
  105. package/dist/source/commands/prompt-command.d.ts +0 -2
  106. package/dist/source/commands/prompt-command.js +0 -111
  107. package/dist/source/commands/reset-command.d.ts +0 -2
  108. package/dist/source/commands/reset-command.js +0 -16
  109. package/dist/source/commands/rules-command.d.ts +0 -2
  110. package/dist/source/commands/rules-command.js +0 -68
  111. package/dist/source/commands/save-command.d.ts +0 -2
  112. package/dist/source/commands/save-command.js +0 -14
  113. package/dist/source/commands/types.d.ts +0 -26
  114. package/dist/source/commands/types.js +0 -1
  115. package/dist/source/commands/usage-command.d.ts +0 -2
  116. package/dist/source/commands/usage-command.js +0 -21
  117. package/dist/source/config.d.ts +0 -60
  118. package/dist/source/config.js +0 -193
  119. package/dist/source/conversation-analyzer.d.ts +0 -10
  120. package/dist/source/conversation-analyzer.js +0 -88
  121. package/dist/source/dedent.d.ts +0 -3
  122. package/dist/source/dedent.js +0 -38
  123. package/dist/source/formatting.d.ts +0 -17
  124. package/dist/source/formatting.js +0 -103
  125. package/dist/source/index.d.ts +0 -18
  126. package/dist/source/index.js +0 -213
  127. package/dist/source/logger.d.ts +0 -2
  128. package/dist/source/logger.js +0 -24
  129. package/dist/source/mentions.d.ts +0 -9
  130. package/dist/source/mentions.js +0 -182
  131. package/dist/source/messages.d.ts +0 -69
  132. package/dist/source/messages.js +0 -261
  133. package/dist/source/middleware/audit-message.d.ts +0 -5
  134. package/dist/source/middleware/audit-message.js +0 -95
  135. package/dist/source/middleware/index.d.ts +0 -2
  136. package/dist/source/middleware/index.js +0 -2
  137. package/dist/source/middleware/rate-limit.d.ts +0 -4
  138. package/dist/source/middleware/rate-limit.js +0 -17
  139. package/dist/source/models/ai-config.d.ts +0 -12
  140. package/dist/source/models/ai-config.js +0 -87
  141. package/dist/source/models/anthropic-provider.d.ts +0 -25
  142. package/dist/source/models/anthropic-provider.js +0 -184
  143. package/dist/source/models/deepseek-provider.d.ts +0 -20
  144. package/dist/source/models/deepseek-provider.js +0 -42
  145. package/dist/source/models/google-provider.d.ts +0 -19
  146. package/dist/source/models/google-provider.js +0 -56
  147. package/dist/source/models/manager.d.ts +0 -15
  148. package/dist/source/models/manager.js +0 -48
  149. package/dist/source/models/openai-provider.d.ts +0 -22
  150. package/dist/source/models/openai-provider.js +0 -70
  151. package/dist/source/models/openrouter-provider.d.ts +0 -36
  152. package/dist/source/models/openrouter-provider.js +0 -276
  153. package/dist/source/models/providers.d.ts +0 -33
  154. package/dist/source/models/providers.js +0 -116
  155. package/dist/source/models/xai-provider.d.ts +0 -20
  156. package/dist/source/models/xai-provider.js +0 -47
  157. package/dist/source/parsing.d.ts +0 -2
  158. package/dist/source/parsing.js +0 -18
  159. package/dist/source/prompts/manager.d.ts +0 -19
  160. package/dist/source/prompts/manager.js +0 -71
  161. package/dist/source/prompts.d.ts +0 -4
  162. package/dist/source/prompts.js +0 -158
  163. package/dist/source/repl-prompt.d.ts +0 -14
  164. package/dist/source/repl-prompt.js +0 -147
  165. package/dist/source/repl.d.ts +0 -27
  166. package/dist/source/repl.js +0 -431
  167. package/dist/source/terminal/formatting.d.ts +0 -37
  168. package/dist/source/terminal/formatting.js +0 -106
  169. package/dist/source/terminal/index.d.ts +0 -94
  170. package/dist/source/terminal/index.js +0 -420
  171. package/dist/source/terminal/markdown-utils.d.ts +0 -2
  172. package/dist/source/terminal/markdown-utils.js +0 -81
  173. package/dist/source/terminal/markdown.d.ts +0 -1
  174. package/dist/source/terminal/markdown.js +0 -111
  175. package/dist/source/terminal/types.d.ts +0 -71
  176. package/dist/source/terminal/types.js +0 -1
  177. package/dist/source/terminal-output.d.ts +0 -8
  178. package/dist/source/terminal-output.js +0 -213
  179. package/dist/source/terminal-output.test.d.ts +0 -8
  180. package/dist/source/terminal-output.test.js +0 -213
  181. package/dist/source/token-tracker.d.ts +0 -14
  182. package/dist/source/token-tracker.js +0 -53
  183. package/dist/source/token-utils.d.ts +0 -7
  184. package/dist/source/token-utils.js +0 -13
  185. package/dist/source/tools/agent.d.ts +0 -17
  186. package/dist/source/tools/agent.js +0 -87
  187. package/dist/source/tools/bash.d.ts +0 -19
  188. package/dist/source/tools/bash.js +0 -294
  189. package/dist/source/tools/code-interpreter.d.ts +0 -12
  190. package/dist/source/tools/code-interpreter.js +0 -131
  191. package/dist/source/tools/command-validation.d.ts +0 -8
  192. package/dist/source/tools/command-validation.js +0 -69
  193. package/dist/source/tools/delete-file.d.ts +0 -12
  194. package/dist/source/tools/delete-file.js +0 -56
  195. package/dist/source/tools/directory-tree.d.ts +0 -12
  196. package/dist/source/tools/directory-tree.js +0 -38
  197. package/dist/source/tools/edit-file.d.ts +0 -19
  198. package/dist/source/tools/edit-file.js +0 -107
  199. package/dist/source/tools/filesystem-utils.d.ts +0 -22
  200. package/dist/source/tools/filesystem-utils.js +0 -191
  201. package/dist/source/tools/git-utils.d.ts +0 -14
  202. package/dist/source/tools/git-utils.js +0 -64
  203. package/dist/source/tools/grep.d.ts +0 -17
  204. package/dist/source/tools/grep.js +0 -138
  205. package/dist/source/tools/index.d.ts +0 -161
  206. package/dist/source/tools/index.js +0 -209
  207. package/dist/source/tools/memory-read.d.ts +0 -13
  208. package/dist/source/tools/memory-read.js +0 -135
  209. package/dist/source/tools/memory-write.d.ts +0 -12
  210. package/dist/source/tools/memory-write.js +0 -83
  211. package/dist/source/tools/move-file.d.ts +0 -13
  212. package/dist/source/tools/move-file.js +0 -44
  213. package/dist/source/tools/read-file.d.ts +0 -17
  214. package/dist/source/tools/read-file.js +0 -86
  215. package/dist/source/tools/read-multiple-files.d.ts +0 -14
  216. package/dist/source/tools/read-multiple-files.js +0 -55
  217. package/dist/source/tools/save-file.d.ts +0 -17
  218. package/dist/source/tools/save-file.js +0 -98
  219. package/dist/source/tools/think.d.ts +0 -11
  220. package/dist/source/tools/think.js +0 -45
  221. package/dist/source/tools/types.d.ts +0 -29
  222. package/dist/source/tools/types.js +0 -14
  223. package/dist/source/tools/web-fetch.d.ts +0 -47
  224. package/dist/source/tools/web-fetch.js +0 -246
  225. package/dist/source/tools/web-search.d.ts +0 -13
  226. package/dist/source/tools/web-search.js +0 -80
  227. package/dist/source/utils/process.d.ts +0 -36
  228. package/dist/source/utils/process.js +0 -75
  229. package/dist/source/version.d.ts +0 -1
  230. package/dist/source/version.js +0 -21
  231. package/dist/terminal-output.d.ts +0 -8
  232. package/dist/terminal-output.js +0 -213
  233. package/dist/tools/memory-read.d.ts +0 -13
  234. package/dist/tools/memory-read.js +0 -135
  235. package/dist/tools/memory-write.d.ts +0 -12
  236. package/dist/tools/memory-write.js +0 -83
  237. package/knip.json +0 -5
  238. package/source/cli.ts +0 -172
  239. package/source/commands/application-log-command.ts +0 -53
  240. package/source/commands/clear-command.ts +0 -14
  241. package/source/commands/compact-command.ts +0 -64
  242. package/source/commands/copy-command.ts +0 -55
  243. package/source/commands/edit-command.ts +0 -63
  244. package/source/commands/edit-prompt-command.ts +0 -31
  245. package/source/commands/exit-command.ts +0 -18
  246. package/source/commands/files-command.ts +0 -85
  247. package/source/commands/generate-rules-command.ts +0 -82
  248. package/source/commands/help-command.ts +0 -27
  249. package/source/commands/init-command.ts +0 -48
  250. package/source/commands/last-log-command.ts +0 -88
  251. package/source/commands/manager.ts +0 -151
  252. package/source/commands/model-command.ts +0 -123
  253. package/source/commands/paste-command.ts +0 -62
  254. package/source/commands/prompt-command.ts +0 -150
  255. package/source/commands/reset-command.ts +0 -22
  256. package/source/commands/rules-command.ts +0 -76
  257. package/source/commands/save-command.ts +0 -20
  258. package/source/commands/types.ts +0 -28
  259. package/source/commands/usage-command.ts +0 -26
  260. package/source/config.ts +0 -223
  261. package/source/conversation-analyzer.ts +0 -115
  262. package/source/dedent.ts +0 -53
  263. package/source/formatting.ts +0 -132
  264. package/source/index.ts +0 -240
  265. package/source/logger.ts +0 -29
  266. package/source/mentions.ts +0 -227
  267. package/source/messages.ts +0 -360
  268. package/source/middleware/audit-message.ts +0 -133
  269. package/source/middleware/index.ts +0 -2
  270. package/source/middleware/rate-limit.ts +0 -24
  271. package/source/models/ai-config.ts +0 -109
  272. package/source/models/anthropic-provider.ts +0 -199
  273. package/source/models/deepseek-provider.ts +0 -53
  274. package/source/models/google-provider.ts +0 -68
  275. package/source/models/manager.ts +0 -84
  276. package/source/models/openai-provider.ts +0 -81
  277. package/source/models/openrouter-provider.ts +0 -288
  278. package/source/models/providers.ts +0 -197
  279. package/source/models/xai-provider.ts +0 -59
  280. package/source/parsing.ts +0 -20
  281. package/source/prompts/manager.ts +0 -90
  282. package/source/prompts.ts +0 -172
  283. package/source/repl-prompt.ts +0 -196
  284. package/source/repl.ts +0 -572
  285. package/source/terminal/formatting.ts +0 -121
  286. package/source/terminal/index.ts +0 -518
  287. package/source/terminal/markdown-utils.ts +0 -89
  288. package/source/terminal/markdown.ts +0 -155
  289. package/source/terminal/types.ts +0 -84
  290. package/source/terminal-output.test.ts +0 -266
  291. package/source/token-tracker.ts +0 -78
  292. package/source/token-utils.ts +0 -17
  293. package/source/tools/agent.ts +0 -107
  294. package/source/tools/bash.ts +0 -367
  295. package/source/tools/code-interpreter.ts +0 -172
  296. package/source/tools/command-validation.ts +0 -81
  297. package/source/tools/delete-file.ts +0 -71
  298. package/source/tools/directory-tree.ts +0 -54
  299. package/source/tools/edit-file.ts +0 -155
  300. package/source/tools/filesystem-utils.ts +0 -265
  301. package/source/tools/git-utils.ts +0 -70
  302. package/source/tools/grep.ts +0 -184
  303. package/source/tools/index.ts +0 -278
  304. package/source/tools/memory-read.ts +0 -174
  305. package/source/tools/memory-write.ts +0 -105
  306. package/source/tools/move-file.ts +0 -59
  307. package/source/tools/read-file.ts +0 -129
  308. package/source/tools/read-multiple-files.ts +0 -80
  309. package/source/tools/save-file.ts +0 -147
  310. package/source/tools/think.ts +0 -51
  311. package/source/tools/types.ts +0 -58
  312. package/source/tools/web-fetch.ts +0 -327
  313. package/source/tools/web-search.ts +0 -101
  314. package/source/utils/process.ts +0 -121
  315. package/source/version.ts +0 -21
  316. package/test/commands/copy-command.test.ts +0 -69
  317. package/test/config.test.ts +0 -200
  318. package/test/terminal/markdown-utils.test.ts +0 -124
  319. package/test/tools/bash-tool.test.ts +0 -58
  320. package/test/tools/code-interpreter.test.ts +0 -91
  321. package/test/tools/command-validation.test.ts +0 -48
  322. package/tsconfig.build.json +0 -9
  323. package/tsconfig.json +0 -30
package/README.md CHANGED
@@ -41,7 +41,6 @@ Acai is built primarily with **TypeScript** and runs on **Node.js**. Key technol
41
41
  * **Tree-sitter:** For robust and efficient code parsing and syntax analysis across multiple programming languages (TypeScript, JavaScript, Java, Python).
42
42
  * **`chalk`, `ora`, `log-update`:** For rich and interactive terminal output.
43
43
  * **`@inquirer/prompts`:** For interactive prompts; CLI args parsed with Node's `util.parseArgs`.
44
- * **`simple-git`:** For Git operations.
45
44
  * **`ripgrep` (via `grep.ts` tool):** For fast file content searching.
46
45
  * **`marked`:** For rendering Markdown in the terminal.
47
46
  * **`pino`:** For structured logging.
@@ -53,7 +52,7 @@ Acai is built primarily with **TypeScript** and runs on **Node.js**. Key technol
53
52
  ### Prerequisites
54
53
 
55
54
  **Required:**
56
- * Node.js 18.20.0 or higher
55
+ * Node.js 20 or higher
57
56
  * Git
58
57
  * [Ripgrep](https://github.com/BurntSushi/ripgrep) (`rg` command) - Fast file content searching
59
58
  * [GitHub CLI](https://cli.github.com/) (`gh` command) - Git operations and repository management
@@ -118,7 +117,7 @@ OPENAI_API_KEY=your_openai_api_key_here
118
117
  ANTHROPIC_API_KEY=your_anthropic_api_key_here
119
118
 
120
119
  # Google (Gemini models)
121
- GOOGLE_API_KEY=your_google_api_key_here
120
+ GOOGLE_GENERATIVE_AI_API_KEY=your_google_api_key_here
122
121
 
123
122
  # DeepSeek
124
123
  DEEPSEEK_API_KEY=your_deepseek_api_key_here
@@ -159,7 +158,7 @@ OPENAI_API_KEY=sk-...
159
158
  ANTHROPIC_API_KEY=sk-ant-...
160
159
 
161
160
  # Optional: Additional providers
162
- GOOGLE_API_KEY=...
161
+ GOOGLE_GENERATIVE_AI_API_KEY=...
163
162
  OPENROUTER_API_KEY=sk-or-...
164
163
 
165
164
  # Optional: Web services (fallbacks available if not provided)
@@ -0,0 +1,2 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+ export declare function healthCommand({ terminal }: CommandOptions): ReplCommand;
@@ -0,0 +1,59 @@
1
+ export function healthCommand({ terminal }) {
2
+ return {
3
+ command: "/health",
4
+ description: "Show application health status and environment variables",
5
+ result: "continue",
6
+ getSubCommands: () => Promise.resolve([]),
7
+ execute() {
8
+ // Define the environment variables we care about
9
+ const envVars = [
10
+ // AI Provider API Keys
11
+ { name: "OPENAI_API_KEY", description: "OpenAI (GPT models)" },
12
+ { name: "ANTHROPIC_API_KEY", description: "Anthropic (Claude models)" },
13
+ {
14
+ name: "GOOGLE_GENERATIVE_AI_API_KEY",
15
+ description: "Google (Gemini models)",
16
+ },
17
+ { name: "DEEPSEEK_API_KEY", description: "DeepSeek" },
18
+ { name: "X_AI_API_KEY", description: "X.AI (Grok models)" },
19
+ { name: "XAI_API_KEY", description: "X.AI (Grok models - alt)" },
20
+ {
21
+ name: "OPENROUTER_API_KEY",
22
+ description: "OpenRouter (multiple models)",
23
+ },
24
+ // Web Service API Keys
25
+ { name: "EXA_API_KEY", description: "Exa (enhanced web search)" },
26
+ {
27
+ name: "JINA_READER_API_KEY",
28
+ description: "Jina Reader (web content extraction)",
29
+ },
30
+ // Application Configuration
31
+ { name: "LOG_LEVEL", description: "Logging level" },
32
+ ];
33
+ // Check each environment variable
34
+ const envStatus = envVars.map((envVar) => {
35
+ const value = process.env[envVar.name];
36
+ const hasValue = value !== undefined && value !== null && value.trim() !== "";
37
+ const status = hasValue ? "✓ Set" : "✗ Not set";
38
+ return [envVar.name, status, envVar.description];
39
+ });
40
+ // Display the table
41
+ terminal.info("Environment Variables Status:");
42
+ terminal.table(envStatus, {
43
+ header: ["Variable", "Status", "Description"],
44
+ colWidths: [30, 15, 55],
45
+ });
46
+ // Count how many are set (derived from envStatus to avoid re-checking process.env)
47
+ const setCount = envStatus.filter((row) => row[1] === "✓ Set").length;
48
+ const totalCount = envVars.length;
49
+ terminal.info(`\nSummary: ${setCount}/${totalCount} environment variables are set`);
50
+ if (setCount === 0) {
51
+ terminal.warn("⚠️ No AI provider API keys are configured. The app may not function properly.");
52
+ }
53
+ else {
54
+ terminal.info("✓ At least one AI provider is configured.");
55
+ }
56
+ return Promise.resolve();
57
+ },
58
+ };
59
+ }
@@ -7,6 +7,7 @@ import { editPromptCommand } from "./edit-prompt-command.js";
7
7
  import { exitCommand } from "./exit-command.js";
8
8
  import { filesCommand } from "./files-command.js";
9
9
  import { generateRulesCommand } from "./generate-rules-command.js";
10
+ import { healthCommand } from "./health-command.js";
10
11
  import { helpCommand } from "./help-command.js";
11
12
  import { initCommand } from "./init-command.js";
12
13
  import { lastLogCommand } from "./last-log-command.js";
@@ -59,6 +60,7 @@ export class CommandManager {
59
60
  editPromptCommand(options),
60
61
  exitCommand(options),
61
62
  filesCommand(options),
63
+ healthCommand(options),
62
64
  initCommand(options),
63
65
  pasteCommand(options),
64
66
  promptCommand(options),
@@ -1,2 +1,2 @@
1
1
  import type { CommandOptions, ReplCommand } from "./types.ts";
2
- export declare const pasteCommand: ({ terminal, modelManager, promptManager, }: CommandOptions) => ReplCommand;
2
+ export declare const pasteCommand: ({ terminal, modelManager, promptManager, tokenCounter, }: CommandOptions) => ReplCommand;
@@ -1,8 +1,104 @@
1
1
  import Clipboard from "@crosscopy/clipboard";
2
2
  import { formatBlock } from "../formatting.js";
3
3
  import { logger } from "../logger.js";
4
- const base64UrlRegex = /^data:(.*?);base64,/;
5
- export const pasteCommand = ({ terminal, modelManager, promptManager, }) => {
4
+ function extractBase64Content(dataUrl) {
5
+ return dataUrl.replace(/^data:.*?;base64,/, "");
6
+ }
7
+ function isValidBase64(str) {
8
+ try {
9
+ // Remove data URL prefix if present
10
+ const base64Content = extractBase64Content(str);
11
+ // Try to decode the base64 string
12
+ const decoded = Buffer.from(base64Content, "base64");
13
+ // Re-encode to verify it's valid base64
14
+ const reEncoded = decoded.toString("base64");
15
+ // Remove padding for comparison
16
+ const normalizedOriginal = base64Content.replace(/=/g, "");
17
+ const normalizedReEncoded = reEncoded.replace(/=/g, "");
18
+ return normalizedOriginal === normalizedReEncoded;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ }
24
+ function detectImageFormatFromBase64(base64Content) {
25
+ try {
26
+ const buffer = Buffer.from(base64Content, "base64");
27
+ // Check for JPEG signature (FF D8 FF)
28
+ if (buffer.length >= 3 &&
29
+ buffer[0] === 0xff &&
30
+ buffer[1] === 0xd8 &&
31
+ buffer[2] === 0xff) {
32
+ return "image/jpeg";
33
+ }
34
+ // Check for PNG signature (89 50 4E 47 0D 0A 1A 0A)
35
+ if (buffer.length >= 8 &&
36
+ buffer[0] === 0x89 &&
37
+ buffer[1] === 0x50 &&
38
+ buffer[2] === 0x4e &&
39
+ buffer[3] === 0x47 &&
40
+ buffer[4] === 0x0d &&
41
+ buffer[5] === 0x0a &&
42
+ buffer[6] === 0x1a &&
43
+ buffer[7] === 0x0a) {
44
+ return "image/png";
45
+ }
46
+ // Check for GIF signature (GIF87a or GIF89a)
47
+ if (buffer.length >= 6 &&
48
+ ((buffer[0] === 0x47 &&
49
+ buffer[1] === 0x49 &&
50
+ buffer[2] === 0x46 &&
51
+ buffer[3] === 0x38 &&
52
+ buffer[4] === 0x37 &&
53
+ buffer[5] === 0x61) ||
54
+ (buffer[0] === 0x47 &&
55
+ buffer[1] === 0x49 &&
56
+ buffer[2] === 0x46 &&
57
+ buffer[3] === 0x38 &&
58
+ buffer[4] === 0x39 &&
59
+ buffer[5] === 0x61))) {
60
+ return "image/gif";
61
+ }
62
+ // Check for WebP signature (RIFF .... WEBP)
63
+ if (buffer.length >= 12 &&
64
+ buffer[0] === 0x52 &&
65
+ buffer[1] === 0x49 &&
66
+ buffer[2] === 0x46 &&
67
+ buffer[3] === 0x46 &&
68
+ buffer[8] === 0x57 &&
69
+ buffer[9] === 0x45 &&
70
+ buffer[10] === 0x42 &&
71
+ buffer[11] === 0x50) {
72
+ return "image/webp";
73
+ }
74
+ // Check for BMP signature (BM)
75
+ if (buffer.length >= 2 && buffer[0] === 0x42 && buffer[1] === 0x4d) {
76
+ return "image/bmp";
77
+ }
78
+ // Check for TIFF signatures (II* or MM*)
79
+ if (buffer.length >= 4 &&
80
+ ((buffer[0] === 0x49 &&
81
+ buffer[1] === 0x49 &&
82
+ buffer[2] === 0x2a &&
83
+ buffer[3] === 0x00) ||
84
+ (buffer[0] === 0x4d &&
85
+ buffer[1] === 0x4d &&
86
+ buffer[2] === 0x00 &&
87
+ buffer[3] === 0x2a))) {
88
+ return "image/tiff";
89
+ }
90
+ // If no known signature found, fall back to the data URL MIME type
91
+ return "unknown";
92
+ }
93
+ catch {
94
+ return "unknown";
95
+ }
96
+ }
97
+ function extractMimeTypeFromDataUrl(dataUrl) {
98
+ const match = dataUrl.match(/^data:([^;]+);base64,/);
99
+ return match?.[1] ? match[1] : "image/png";
100
+ }
101
+ export const pasteCommand = ({ terminal, modelManager, promptManager, tokenCounter, }) => {
6
102
  return {
7
103
  command: "/paste",
8
104
  description: "Pastes image or text content from the clipboard into the next prompt.",
@@ -12,13 +108,59 @@ export const pasteCommand = ({ terminal, modelManager, promptManager, }) => {
12
108
  try {
13
109
  if (Clipboard.hasImage()) {
14
110
  const base64DataUrl = await Clipboard.getImageBase64();
15
- const mimeTypeMatch = base64DataUrl.match(base64UrlRegex);
16
- const mimeType = mimeTypeMatch ? mimeTypeMatch[1] : "image/png";
17
- promptManager.addContext({
18
- type: "image",
19
- image: base64DataUrl,
20
- mediaType: mimeType,
21
- });
111
+ // Validate the base64 data
112
+ if (!isValidBase64(base64DataUrl)) {
113
+ terminal.error("Invalid base64 data in clipboard. The image data may be corrupted.");
114
+ return;
115
+ }
116
+ // Extract MIME type with better error handling and actual image format detection
117
+ let mimeType;
118
+ try {
119
+ // First, try to get MIME type from data URL
120
+ const dataUrlMimeType = extractMimeTypeFromDataUrl(base64DataUrl);
121
+ // Then, detect actual image format from base64 content
122
+ const base64Content = extractBase64Content(base64DataUrl);
123
+ const detectedFormat = detectImageFormatFromBase64(base64Content);
124
+ // Use detected format if available, otherwise fall back to data URL MIME type
125
+ if (detectedFormat !== "unknown") {
126
+ mimeType = detectedFormat;
127
+ // Log if there's a mismatch between data URL and actual format
128
+ if (dataUrlMimeType !== detectedFormat) {
129
+ logger.warn(`Clipboard library reported ${dataUrlMimeType} but actual image format is ${detectedFormat}. Using detected format.`);
130
+ }
131
+ }
132
+ else {
133
+ mimeType = dataUrlMimeType;
134
+ logger.warn(`Could not detect image format, using data URL MIME type: ${mimeType}`);
135
+ }
136
+ }
137
+ catch (error) {
138
+ logger.warn(`Failed to extract MIME type from clipboard image: ${error}`);
139
+ mimeType = "image/png";
140
+ }
141
+ // Ensure the data URL format is correct
142
+ if (!base64DataUrl.startsWith(`data:${mimeType};base64,`)) {
143
+ // Fix malformed data URLs
144
+ const base64Content = base64DataUrl.replace(/^data:.*?;base64,/, "");
145
+ const correctedDataUrl = `data:${mimeType};base64,${base64Content}`;
146
+ // Final validation
147
+ if (!isValidBase64(correctedDataUrl)) {
148
+ terminal.error("Failed to correct base64 data format. The image data may be corrupted.");
149
+ return;
150
+ }
151
+ promptManager.addContext({
152
+ type: "image",
153
+ image: correctedDataUrl,
154
+ mediaType: mimeType,
155
+ });
156
+ }
157
+ else {
158
+ promptManager.addContext({
159
+ type: "image",
160
+ image: base64DataUrl,
161
+ mediaType: mimeType,
162
+ });
163
+ }
22
164
  terminal.success("Image from clipboard will be added to your next prompt.");
23
165
  return;
24
166
  }
@@ -27,8 +169,10 @@ export const pasteCommand = ({ terminal, modelManager, promptManager, }) => {
27
169
  terminal.warn("Clipboard is empty.");
28
170
  return;
29
171
  }
30
- promptManager.addContext(formatBlock(clipboardContent, "clipboard", modelManager.getModelMetadata("repl").promptFormat));
31
- terminal.success("Clipboard content will be added to your next prompt.");
172
+ const content = formatBlock(clipboardContent, "clipboard", modelManager.getModelMetadata("repl").promptFormat);
173
+ promptManager.addContext(content);
174
+ const tokenCount = tokenCounter.count(content);
175
+ terminal.success(`Clipboard content will be added to your next prompt. (${tokenCount} tokens)`);
32
176
  }
33
177
  catch (error) {
34
178
  const message = error instanceof Error ? error.message : String(error);
@@ -1,6 +1,7 @@
1
1
  export const resetCommand = ({ terminal, messageHistory, }) => {
2
2
  return {
3
3
  command: "/reset",
4
+ aliases: ["/new"],
4
5
  description: "Saves the chat history and then resets it.",
5
6
  result: "continue",
6
7
  getSubCommands: () => Promise.resolve([]),
package/dist/index.js CHANGED
@@ -106,7 +106,7 @@ async function main() {
106
106
  terminal.setTitle(`acai: ${process.cwd()}`);
107
107
  const chosenModel = isSupportedModel(flags.model)
108
108
  ? flags.model
109
- : "openrouter:sonnet4";
109
+ : "openrouter:glm-4.5";
110
110
  const modelManager = new ModelManager({
111
111
  stateDir: await appDir.ensurePath("audit"),
112
112
  });
@@ -1,6 +1,7 @@
1
1
  import type { ModelMetadata } from "./providers.ts";
2
2
  declare const openrouterModels: {
3
3
  readonly "deepseek-v3": import("@ai-sdk/provider").LanguageModelV2;
4
+ readonly "deepseek-v3-1": import("@ai-sdk/provider").LanguageModelV2;
4
5
  readonly "deepseek-r1": import("@ai-sdk/provider").LanguageModelV2;
5
6
  readonly "deepseek-v3-free": import("@ai-sdk/provider").LanguageModelV2;
6
7
  readonly "deepseek-r1-free": import("@ai-sdk/provider").LanguageModelV2;
@@ -18,12 +19,14 @@ declare const openrouterModels: {
18
19
  readonly "glm-4.5": import("@ai-sdk/provider").LanguageModelV2;
19
20
  readonly "gpt-5": import("@ai-sdk/provider").LanguageModelV2;
20
21
  readonly "gpt-5-mini": import("@ai-sdk/provider").LanguageModelV2;
22
+ readonly "gpt-oss-120b": import("@ai-sdk/provider").LanguageModelV2;
23
+ readonly "grok-code-fast-1": import("@ai-sdk/provider").LanguageModelV2;
21
24
  };
22
25
  type ModelName = `openrouter:${keyof typeof openrouterModels}`;
23
26
  export declare const openrouterModelNames: ModelName[];
24
27
  export declare const openrouterProvider: {
25
28
  openrouter: import("@ai-sdk/provider").ProviderV2 & {
26
- languageModel(modelId: "gpt-5" | "gpt-5-mini" | "gpt-4.1" | "deepseek-v3" | "deepseek-r1" | "deepseek-v3-free" | "deepseek-r1-free" | "gemini-flash25" | "gemini-pro25" | "sonnet4" | "opus4" | "opus-4.1" | "kimi-k2" | "kimi-k2-free" | "devstral-medium" | "qwen3-coder" | "qwen3-coder-free" | "glm-4.5"): import("@ai-sdk/provider").LanguageModelV2;
29
+ languageModel(modelId: "gpt-5" | "gpt-5-mini" | "gpt-4.1" | "deepseek-v3" | "deepseek-v3-1" | "deepseek-r1" | "deepseek-v3-free" | "deepseek-r1-free" | "gemini-flash25" | "gemini-pro25" | "sonnet4" | "opus4" | "opus-4.1" | "kimi-k2" | "kimi-k2-free" | "devstral-medium" | "qwen3-coder" | "qwen3-coder-free" | "glm-4.5" | "gpt-oss-120b" | "grok-code-fast-1"): import("@ai-sdk/provider").LanguageModelV2;
27
30
  textEmbeddingModel(modelId: string): import("@ai-sdk/provider").EmbeddingModelV2<string>;
28
31
  imageModel(modelId: string): import("@ai-sdk/provider").ImageModelV2;
29
32
  transcriptionModel(modelId: string): import("@ai-sdk/provider").TranscriptionModelV2;
@@ -13,6 +13,7 @@ const openRouterClient = createOpenAICompatible({
13
13
  });
14
14
  const openrouterModels = {
15
15
  "deepseek-v3": openRouterClient("deepseek/deepseek-chat-v3-0324"),
16
+ "deepseek-v3-1": openRouterClient("deepseek/deepseek-chat-v3.1"),
16
17
  "deepseek-r1": openRouterClient("deepseek/deepseek-r1-0528"),
17
18
  "deepseek-v3-free": openRouterClient("deepseek/deepseek-chat-v3-0324:free"),
18
19
  "deepseek-r1-free": openRouterClient("deepseek/deepseek-r1-0528:free"),
@@ -30,6 +31,8 @@ const openrouterModels = {
30
31
  "glm-4.5": openRouterClient("z-ai/glm-4.5"),
31
32
  "gpt-5": openRouterClient("openai/gpt-5"),
32
33
  "gpt-5-mini": openRouterClient("openai/gpt-5-mini"),
34
+ "gpt-oss-120b": openRouterClient("openai/gpt-oss-120b"),
35
+ "grok-code-fast-1": openRouterClient("x-ai/grok-code-fast-1"),
33
36
  };
34
37
  export const openrouterModelNames = objectKeys(openrouterModels).map((key) => `openrouter:${key}`);
35
38
  export const openrouterProvider = {
@@ -78,6 +81,19 @@ export const openrouterModelRegistry = {
78
81
  costPerOutputToken: 0, // Assuming free tier or unknown cost
79
82
  category: "balanced",
80
83
  },
84
+ "openrouter:deepseek-v3-1": {
85
+ id: "openrouter:deepseek-v3-1",
86
+ provider: "openrouter",
87
+ contextWindow: 163840,
88
+ maxOutputTokens: 8000,
89
+ defaultTemperature: 0.3,
90
+ promptFormat: "bracket",
91
+ supportsReasoning: true,
92
+ supportsToolCalling: true,
93
+ costPerInputToken: 0.0000002,
94
+ costPerOutputToken: 0.0000008,
95
+ category: "balanced",
96
+ },
81
97
  "openrouter:deepseek-r1-free": {
82
98
  id: "openrouter:deepseek-r1-free",
83
99
  provider: "openrouter",
@@ -252,8 +268,8 @@ export const openrouterModelRegistry = {
252
268
  provider: "openrouter",
253
269
  contextWindow: 400000,
254
270
  maxOutputTokens: 128000,
255
- defaultTemperature: 0.3,
256
- promptFormat: "markdown",
271
+ defaultTemperature: 1.0,
272
+ promptFormat: "xml",
257
273
  supportsReasoning: true,
258
274
  supportsToolCalling: true,
259
275
  costPerInputToken: 0.00000125,
@@ -265,12 +281,38 @@ export const openrouterModelRegistry = {
265
281
  provider: "openrouter",
266
282
  contextWindow: 200000,
267
283
  maxOutputTokens: 64000,
268
- defaultTemperature: 0.3,
269
- promptFormat: "markdown",
284
+ defaultTemperature: 1.0,
285
+ promptFormat: "xml",
270
286
  supportsReasoning: true,
271
287
  supportsToolCalling: true,
272
288
  costPerInputToken: 0.00000015,
273
289
  costPerOutputToken: 0.0000006,
274
290
  category: "balanced",
275
291
  },
292
+ "openrouter:grok-code-fast-1": {
293
+ id: "openrouter:grok-code-fast-1",
294
+ provider: "openrouter",
295
+ contextWindow: 256000,
296
+ maxOutputTokens: 10000,
297
+ defaultTemperature: 0.5,
298
+ promptFormat: "markdown",
299
+ supportsReasoning: true,
300
+ supportsToolCalling: true,
301
+ costPerInputToken: 0.0000002,
302
+ costPerOutputToken: 0.0000015,
303
+ category: "fast",
304
+ },
305
+ "openrouter:gpt-oss-120b": {
306
+ id: "openrouter:gpt-oss-120b",
307
+ provider: "openrouter",
308
+ contextWindow: 131072,
309
+ maxOutputTokens: 64000,
310
+ defaultTemperature: 1.0,
311
+ promptFormat: "xml",
312
+ supportsReasoning: true,
313
+ supportsToolCalling: true,
314
+ costPerInputToken: 0.00000007256312,
315
+ costPerOutputToken: 0.0000002903936,
316
+ category: "fast",
317
+ },
276
318
  };
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const providers: readonly ["anthropic", "openai", "google", "deepseek", "openrouter", "xai"];
3
3
  export type ModelProvider = (typeof providers)[number];
4
- export declare const models: readonly ("anthropic:opus" | "anthropic:sonnet" | "anthropic:sonnet37" | "anthropic:sonnet37-token-efficient-tools" | "anthropic:sonnet37-128k" | "anthropic:sonnet35" | "anthropic:haiku" | "deepseek:deepseek-chat" | "deepseek:deepseek-reasoner" | "google:flash25lite" | "google:pro25" | "google:flash25" | "openai:o3" | "openai:gpt-4.1" | "openai:o4-mini" | "openai:codex-mini" | "openrouter:gpt-5" | "openrouter:gpt-5-mini" | "openrouter:gpt-4.1" | "openrouter:deepseek-v3" | "openrouter:deepseek-r1" | "openrouter:deepseek-v3-free" | "openrouter:deepseek-r1-free" | "openrouter:gemini-flash25" | "openrouter:gemini-pro25" | "openrouter:sonnet4" | "openrouter:opus4" | "openrouter:opus-4.1" | "openrouter:kimi-k2" | "openrouter:kimi-k2-free" | "openrouter:devstral-medium" | "openrouter:qwen3-coder" | "openrouter:qwen3-coder-free" | "openrouter:glm-4.5" | "xai:grok3" | "xai:grok3-mini")[];
4
+ export declare const models: readonly ("anthropic:opus" | "anthropic:sonnet" | "anthropic:sonnet37" | "anthropic:sonnet37-token-efficient-tools" | "anthropic:sonnet37-128k" | "anthropic:sonnet35" | "anthropic:haiku" | "deepseek:deepseek-chat" | "deepseek:deepseek-reasoner" | "google:flash25lite" | "google:pro25" | "google:flash25" | "openai:o3" | "openai:gpt-4.1" | "openai:o4-mini" | "openai:codex-mini" | "openrouter:gpt-5" | "openrouter:gpt-5-mini" | "openrouter:gpt-4.1" | "openrouter:deepseek-v3" | "openrouter:deepseek-v3-1" | "openrouter:deepseek-r1" | "openrouter:deepseek-v3-free" | "openrouter:deepseek-r1-free" | "openrouter:gemini-flash25" | "openrouter:gemini-pro25" | "openrouter:sonnet4" | "openrouter:opus4" | "openrouter:opus-4.1" | "openrouter:kimi-k2" | "openrouter:kimi-k2-free" | "openrouter:devstral-medium" | "openrouter:qwen3-coder" | "openrouter:qwen3-coder-free" | "openrouter:glm-4.5" | "openrouter:gpt-oss-120b" | "openrouter:grok-code-fast-1" | "xai:grok3" | "xai:grok3-mini")[];
5
5
  export type ModelName = (typeof models)[number] | (`xai:${string}` & {}) | (`openai:${string}` & {}) | (`anthropic:${string}` & {}) | (`google:${string}` & {}) | (`deepseek:${string}` & {}) | (`openrouter:${string}` & {});
6
6
  export declare function isSupportedModel(model: unknown): model is ModelName;
7
7
  export declare function languageModel(model: ModelName): import("@ai-sdk/provider").LanguageModelV2;
@@ -16,4 +16,5 @@ export declare class PromptManager {
16
16
  hasContext(): boolean;
17
17
  clearContext(): void;
18
18
  clearAll(): void;
19
+ getContextTokenCount(): number;
19
20
  }
@@ -68,4 +68,14 @@ export class PromptManager {
68
68
  this.clearContext();
69
69
  this.prompt = undefined;
70
70
  }
71
+ getContextTokenCount() {
72
+ let totalTokens = 0;
73
+ for (const item of this.context) {
74
+ if (typeof item === "string") {
75
+ totalTokens += this.tokenCounter.count(item);
76
+ }
77
+ // Skip ImagePart items as they don't contain countable text
78
+ }
79
+ return totalTokens;
80
+ }
71
81
  }
package/dist/prompts.js CHANGED
@@ -6,11 +6,13 @@ import { dedent } from "./dedent.js";
6
6
  import { AgentTool } from "./tools/agent.js";
7
7
  import { BashTool } from "./tools/bash.js";
8
8
  import { CodeInterpreterTool } from "./tools/code-interpreter.js";
9
+ import { DeleteFileTool } from "./tools/delete-file.js";
9
10
  import { DirectoryTreeTool } from "./tools/directory-tree.js";
10
11
  import { EditFileTool } from "./tools/edit-file.js";
11
12
  import { getCurrentBranch, inGitDirectory } from "./tools/git-utils.js";
12
13
  import { GrepTool } from "./tools/grep.js";
13
14
  import { ReadFileTool } from "./tools/read-file.js";
15
+ import { ReadMultipleFilesTool } from "./tools/read-multiple-files.js";
14
16
  import { SaveFileTool } from "./tools/save-file.js";
15
17
  import { ThinkTool } from "./tools/think.js";
16
18
  import { WebFetchTool } from "./tools/web-fetch.js";
@@ -65,17 +67,18 @@ function toolUsage() {
65
67
 
66
68
  ### Information Gathering
67
69
  - Use \`${DirectoryTreeTool.name}\` for project structure
68
- - Use \`${ReadFileTool.name}\` for file contents if filenames are provided in the prompt
70
+ - Use \`${ReadFileTool.name}\` or \`${ReadMultipleFilesTool.name}\` for file contents if filenames are provided in the prompt
69
71
  - Use \`${GrepTool.name}\` for code pattern searches
70
72
  - Use \`${WebFetchTool.name}\` for text-based URLs provided in the prompt
71
73
  - Use \`${WebSearchTool.name}\` for external research (e.g., libraries, errors)
72
- - Use \`${AgentTool.name}\` for iterative keyword/file searches
74
+ - Use \`${AgentTool.name}\` for iterative keyword/file searches. Use this if you need to explore the project fo find what you are looking for.
73
75
  - If file contents or URLs are provided in the prompt, use them directly without re-fetching
74
76
  - Always verify file contents before suggesting changes unless provided in the prompt
75
77
 
76
78
  ### Code Modification
77
- - Use \`${EditFileTool.name}\` for existing file edits (requires user approval)
78
- - Use \`${SaveFileTool.name}\` for new files only
79
+ - Use \`${EditFileTool.name}\` to edit existing files
80
+ - Use \`${SaveFileTool.name}\` to create new files only
81
+ - Use \`${DeleteFileTool.name}\` to delete files
79
82
 
80
83
  ### Planning & Complex Tasks
81
84
  - Use \`${ThinkTool.name}\` for structured reasoning on complex problems
@@ -85,8 +88,7 @@ function toolUsage() {
85
88
  - Execute bash commands within project directory only
86
89
  - Always specify absolute paths to avoid errors
87
90
  - You have access to the Github CLI
88
- - **Background Processes:** Use background processes (via \`&\`) for commands that are unlikely to stop on their own, e.g. \`node server.js &\`. If unsure, ask the user.
89
- - **Interactive Commands:** Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user.
91
+ - Try to avoid shell commands that are likely to require user interaction (e.g. \`git rebase -i\`). Use non-interactive versions of commands (e.g. \`npm init -y\` instead of \`npm init\`) when available, and otherwise remind the user that interactive shell commands are not supported and may cause hangs until canceled by the user.
90
92
 
91
93
  ### Code Interpreter (\`${CodeInterpreterTool.name}\`)
92
94
  - Executes JavaScript code in a separate Node.js process using Node's Permission Model