@travisennis/acai 0.0.5 → 0.0.7
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 +190 -19
- package/bin/acai-wrapper.js +26 -0
- package/dist/agent/index.d.ts +132 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +434 -0
- package/dist/api/exa/index.js +1 -1
- package/dist/cli.d.ts +4 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +67 -40
- 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 +54 -0
- package/dist/commands/application-log-command.d.ts +1 -1
- package/dist/commands/application-log-command.d.ts.map +1 -1
- package/dist/commands/application-log-command.js +18 -20
- package/dist/commands/clear-command.d.ts +1 -1
- package/dist/commands/clear-command.d.ts.map +1 -1
- package/dist/commands/clear-command.js +7 -3
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +9 -5
- 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 +124 -0
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +14 -5
- package/dist/commands/edit-command.d.ts +1 -1
- package/dist/commands/edit-command.d.ts.map +1 -1
- package/dist/commands/edit-command.js +21 -34
- package/dist/commands/edit-prompt-command.d.ts +1 -1
- package/dist/commands/edit-prompt-command.d.ts.map +1 -1
- package/dist/commands/edit-prompt-command.js +18 -15
- package/dist/commands/exit-command.d.ts +1 -4
- package/dist/commands/exit-command.d.ts.map +1 -1
- package/dist/commands/exit-command.js +9 -5
- package/dist/commands/files-command.d.ts +1 -1
- package/dist/commands/files-command.d.ts.map +1 -1
- package/dist/commands/files-command.js +20 -16
- package/dist/commands/generate-rules-command.d.ts +1 -1
- package/dist/commands/generate-rules-command.d.ts.map +1 -1
- package/dist/commands/generate-rules-command.js +307 -39
- 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 +191 -0
- package/dist/commands/health-command.d.ts +1 -1
- package/dist/commands/health-command.d.ts.map +1 -1
- package/dist/commands/health-command.js +49 -27
- package/dist/commands/help-command.d.ts +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +25 -5
- 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 +458 -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 +40 -22
- package/dist/commands/last-log-command.d.ts +1 -1
- package/dist/commands/last-log-command.d.ts.map +1 -1
- package/dist/commands/last-log-command.js +15 -15
- 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 +35 -0
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +61 -21
- package/dist/commands/manager.d.ts +9 -4
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +64 -39
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +201 -66
- package/dist/commands/paste-command.d.ts +1 -1
- package/dist/commands/paste-command.d.ts.map +1 -1
- package/dist/commands/paste-command.js +23 -9
- 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 +109 -0
- package/dist/commands/prompt-command.d.ts +19 -1
- package/dist/commands/prompt-command.d.ts.map +1 -1
- package/dist/commands/prompt-command.js +191 -98
- 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 +55 -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 +8 -5
- package/dist/commands/rules-command.d.ts +1 -1
- package/dist/commands/rules-command.d.ts.map +1 -1
- package/dist/commands/rules-command.js +25 -22
- package/dist/commands/save-command.d.ts +1 -1
- package/dist/commands/save-command.d.ts.map +1 -1
- package/dist/commands/save-command.js +8 -3
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +45 -24
- package/dist/commands/types.d.ts +9 -7
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/usage-command.d.ts +1 -1
- package/dist/commands/usage-command.d.ts.map +1 -1
- package/dist/commands/usage-command.js +18 -7
- package/dist/config.d.ts +21 -11
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +90 -63
- package/dist/execution/index.d.ts +17 -2
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +62 -20
- package/dist/formatting.d.ts +127 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +201 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +263 -102
- 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 +11 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +122 -21
- 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 -67
- package/dist/models/deepseek-provider.d.ts.map +1 -1
- package/dist/models/deepseek-provider.js +0 -2
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +0 -3
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/groq-provider.js +0 -1
- 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/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +0 -4
- package/dist/models/openrouter-provider.d.ts +16 -22
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +175 -236
- package/dist/models/providers.d.ts +4 -14
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +1 -57
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +0 -2
- package/dist/prompts.d.ts +10 -4
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +447 -70
- package/dist/repl/project-status-line.d.ts +3 -0
- package/dist/repl/project-status-line.d.ts.map +1 -0
- package/dist/repl/project-status-line.js +61 -0
- 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 +51 -0
- package/dist/repl-new.d.ts.map +1 -0
- package/dist/repl-new.js +354 -0
- package/dist/skills.d.ts +20 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +192 -0
- package/dist/terminal/control.d.ts +55 -0
- package/dist/terminal/control.d.ts.map +1 -0
- package/dist/terminal/control.js +109 -0
- package/dist/terminal/default-theme.d.ts +1 -1
- package/dist/terminal/default-theme.d.ts.map +1 -1
- package/dist/terminal/default-theme.js +24 -28
- package/dist/terminal/formatting.d.ts +23 -25
- package/dist/terminal/formatting.d.ts.map +1 -1
- package/dist/terminal/formatting.js +35 -52
- package/dist/terminal/highlight/index.d.ts.map +1 -1
- package/dist/terminal/highlight/index.js +3 -6
- package/dist/terminal/highlight/theme.d.ts.map +1 -1
- package/dist/terminal/highlight/theme.js +2 -6
- package/dist/terminal/index.d.ts +2 -94
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +2 -370
- package/dist/terminal/markdown.js +10 -5
- 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/terminal/strip-ansi.js +4 -4
- package/dist/terminal/table/cell.d.ts +114 -0
- package/dist/terminal/table/cell.d.ts.map +1 -0
- package/dist/terminal/table/cell.js +407 -0
- package/dist/terminal/table/debug.d.ts +15 -0
- package/dist/terminal/table/debug.d.ts.map +1 -0
- package/dist/terminal/table/debug.js +32 -0
- package/dist/terminal/table/index.d.ts +3 -0
- package/dist/terminal/table/index.d.ts.map +1 -0
- package/dist/terminal/table/index.js +2 -0
- package/dist/terminal/table/layout-manager.d.ts +27 -0
- package/dist/terminal/table/layout-manager.d.ts.map +1 -0
- package/dist/terminal/table/layout-manager.js +257 -0
- package/dist/terminal/table/table.d.ts +9 -0
- package/dist/terminal/table/table.d.ts.map +1 -0
- package/dist/terminal/table/table.js +97 -0
- package/dist/terminal/table/utils.d.ts +63 -0
- package/dist/terminal/table/utils.d.ts.map +1 -0
- package/dist/terminal/table/utils.js +326 -0
- package/dist/tokens/threshold.d.ts +20 -0
- package/dist/tokens/threshold.d.ts.map +1 -0
- package/dist/tokens/threshold.js +67 -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 +285 -0
- package/dist/tools/agent.d.ts +16 -5
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +86 -59
- package/dist/tools/bash.d.ts +23 -12
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +243 -128
- package/dist/tools/batch.d.ts +34 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +174 -0
- 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 +151 -134
- 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 +60 -97
- package/dist/tools/directory-tree.d.ts +17 -12
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +57 -48
- package/dist/tools/dynamic-tool-loader.d.ts +16 -10
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +122 -130
- 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 +127 -114
- package/dist/tools/glob.d.ts +36 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +154 -0
- package/dist/tools/grep.d.ts +73 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +425 -165
- package/dist/tools/index.d.ts +220 -126
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +284 -135
- package/dist/tools/llm-edit-fixer.d.ts +24 -0
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
- package/dist/tools/llm-edit-fixer.js +136 -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 +48 -34
- 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 +84 -70
- 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 +132 -72
- 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 +76 -101
- package/dist/tools/think.d.ts +15 -7
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +34 -20
- package/dist/tools/types.d.ts +8 -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 +64 -31
- 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/box.d.ts +20 -0
- package/dist/tui/components/box.d.ts.map +1 -0
- package/dist/tui/components/box.js +81 -0
- package/dist/tui/components/editor.d.ts +106 -0
- package/dist/tui/components/editor.d.ts.map +1 -0
- package/dist/tui/components/editor.js +1220 -0
- package/dist/tui/components/footer.d.ts +12 -0
- package/dist/tui/components/footer.d.ts.map +1 -0
- package/dist/tui/components/footer.js +209 -0
- package/dist/tui/components/header.d.ts +21 -0
- package/dist/tui/components/header.d.ts.map +1 -0
- package/dist/tui/components/header.js +63 -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 +23 -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 +106 -0
- package/dist/tui/components/markdown.d.ts.map +1 -0
- package/dist/tui/components/markdown.js +586 -0
- package/dist/tui/components/modal.d.ts +29 -0
- package/dist/tui/components/modal.d.ts.map +1 -0
- package/dist/tui/components/modal.js +263 -0
- package/dist/tui/components/progress-bar.d.ts +19 -0
- package/dist/tui/components/progress-bar.d.ts.map +1 -0
- package/dist/tui/components/progress-bar.js +78 -0
- package/dist/tui/components/prompt-status.d.ts +17 -0
- package/dist/tui/components/prompt-status.d.ts.map +1 -0
- package/dist/tui/components/prompt-status.js +26 -0
- package/dist/tui/components/select-list.d.ts +48 -0
- package/dist/tui/components/select-list.d.ts.map +1 -0
- package/dist/tui/components/select-list.js +207 -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/table.d.ts +27 -0
- package/dist/tui/components/table.d.ts.map +1 -0
- package/dist/tui/components/table.js +125 -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 +33 -0
- package/dist/tui/components/tool-execution.d.ts +21 -0
- package/dist/tui/components/tool-execution.d.ts.map +1 -0
- package/dist/tui/components/tool-execution.js +161 -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 +23 -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 +18 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +22 -0
- package/dist/tui/terminal.d.ts +38 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +94 -0
- package/dist/tui/tui.d.ts +69 -0
- package/dist/tui/tui.d.ts.map +1 -0
- package/dist/tui/tui.js +204 -0
- package/dist/tui/utils.d.ts +24 -0
- package/dist/tui/utils.d.ts.map +1 -0
- package/dist/tui/utils.js +111 -0
- package/dist/utils/bash.d.ts +7 -0
- package/dist/utils/bash.d.ts.map +1 -0
- package/dist/{tools/bash-utils.js → utils/bash.js} +31 -12
- package/dist/utils/{filesystem.d.ts → filesystem/operations.d.ts} +1 -1
- package/dist/utils/filesystem/operations.d.ts.map +1 -0
- package/dist/utils/filesystem/security.d.ts +9 -0
- package/dist/utils/filesystem/security.d.ts.map +1 -0
- package/dist/{tools/filesystem-utils.js → utils/filesystem/security.js} +93 -21
- package/dist/utils/funcs.d.ts +6 -0
- package/dist/utils/funcs.d.ts.map +1 -0
- package/dist/utils/funcs.js +6 -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/{tools/git-utils.d.ts → utils/git.d.ts} +1 -1
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/{tools/git-utils.js → utils/git.js} +0 -6
- package/dist/utils/glob.js +1 -1
- 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/dist/utils/{zod-utils.d.ts → zod.d.ts} +1 -1
- package/dist/utils/zod.d.ts.map +1 -0
- package/package.json +21 -21
- 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/display-tool-messages.d.ts +0 -4
- package/dist/repl/display-tool-messages.d.ts.map +0 -1
- package/dist/repl/display-tool-messages.js +0 -55
- package/dist/repl/display-tool-use.d.ts +0 -14
- package/dist/repl/display-tool-use.d.ts.map +0 -1
- package/dist/repl/display-tool-use.js +0 -63
- package/dist/repl/get-prompt-header.d.ts +0 -8
- package/dist/repl/get-prompt-header.d.ts.map +0 -1
- package/dist/repl/get-prompt-header.js +0 -38
- package/dist/repl-prompt.d.ts +0 -15
- package/dist/repl-prompt.d.ts.map +0 -1
- package/dist/repl-prompt.js +0 -147
- package/dist/repl.d.ts +0 -31
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js +0 -310
- package/dist/terminal/checkbox-prompt.d.ts +0 -36
- package/dist/terminal/checkbox-prompt.d.ts.map +0 -1
- package/dist/terminal/checkbox-prompt.js +0 -362
- package/dist/terminal/editor-prompt.d.ts +0 -10
- package/dist/terminal/editor-prompt.d.ts.map +0 -1
- package/dist/terminal/editor-prompt.js +0 -61
- package/dist/terminal/errors.d.ts +0 -19
- package/dist/terminal/errors.d.ts.map +0 -1
- package/dist/terminal/errors.js +0 -37
- package/dist/terminal/input-prompt.d.ts +0 -16
- package/dist/terminal/input-prompt.d.ts.map +0 -1
- package/dist/terminal/input-prompt.js +0 -181
- package/dist/terminal/search-prompt.d.ts +0 -20
- package/dist/terminal/search-prompt.d.ts.map +0 -1
- package/dist/terminal/search-prompt.js +0 -279
- package/dist/terminal/types.d.ts +0 -35
- package/dist/terminal/types.d.ts.map +0 -1
- package/dist/terminal/types.js +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/bash-utils.d.ts +0 -7
- package/dist/tools/bash-utils.d.ts.map +0 -1
- package/dist/tools/file-editing-utils.d.ts +0 -2
- package/dist/tools/file-editing-utils.d.ts.map +0 -1
- package/dist/tools/file-editing-utils.js +0 -135
- package/dist/tools/filesystem-utils.d.ts +0 -7
- package/dist/tools/filesystem-utils.d.ts.map +0 -1
- package/dist/tools/git-utils.d.ts.map +0 -1
- package/dist/utils/filesystem.d.ts.map +0 -1
- package/dist/utils/zod-utils.d.ts.map +0 -1
- /package/dist/utils/{filesystem.js → filesystem/operations.js} +0 -0
- /package/dist/utils/{zod-utils.js → zod.js} +0 -0
package/dist/tools/bash.js
CHANGED
|
@@ -1,113 +1,117 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
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";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
7
|
+
import { isMutatingCommand, resolveCwd, validatePaths } from "../utils/bash.js";
|
|
9
8
|
export const BashTool = {
|
|
10
9
|
name: "bash",
|
|
11
10
|
};
|
|
11
|
+
const installedTools = getInstalledTools();
|
|
12
|
+
const toolDescription = `Execute commands in a shell. Commands can execute only within the allowed directories. Always use absolute paths.
|
|
13
|
+
|
|
14
|
+
Tools available:
|
|
15
|
+
${installedTools}`;
|
|
12
16
|
// Command execution timeout in milliseconds
|
|
13
17
|
const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
|
|
14
|
-
|
|
18
|
+
const inputSchema = z.object({
|
|
19
|
+
command: z.string().describe("Full CLI command to execute."),
|
|
20
|
+
cwd: z
|
|
21
|
+
.string()
|
|
22
|
+
.nullable()
|
|
23
|
+
.describe("Working directory file path (default: project root). Must be within the project directory. Required but nullable."),
|
|
24
|
+
timeout: z.coerce
|
|
25
|
+
.number()
|
|
26
|
+
.nullable()
|
|
27
|
+
.describe(`Command execution timeout in milliseconds. Required but nullable. If null, the default value is ${DEFAULT_TIMEOUT}ms`),
|
|
28
|
+
background: z
|
|
29
|
+
.boolean()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Run command in background. If true, command will run until program exit."),
|
|
32
|
+
});
|
|
33
|
+
export const createBashTool = async ({ baseDir, allowedDirs, tokenCounter, }) => {
|
|
15
34
|
const execEnv = await initExecutionEnvironment();
|
|
35
|
+
const allowedDirectories = allowedDirs ?? [baseDir];
|
|
16
36
|
return {
|
|
17
|
-
|
|
18
|
-
description:
|
|
19
|
-
inputSchema
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
toolDef: {
|
|
38
|
+
description: toolDescription,
|
|
39
|
+
inputSchema,
|
|
40
|
+
},
|
|
41
|
+
async *execute({ command, cwd, timeout, background }, { toolCallId, abortSignal }) {
|
|
42
|
+
try {
|
|
43
|
+
if (abortSignal?.aborted) {
|
|
44
|
+
throw new Error("Command execution aborted");
|
|
45
|
+
}
|
|
46
|
+
// grok doesn't follow my instructions
|
|
47
|
+
const safeCwd = cwd === "null" ? null : cwd;
|
|
48
|
+
const resolvedCwd = resolveCwd(safeCwd, baseDir, allowedDirectories);
|
|
49
|
+
const safeTimeout = timeout ?? DEFAULT_TIMEOUT;
|
|
50
|
+
// Safety warning for potentially mutating commands
|
|
51
|
+
const isMutating = isMutatingCommand(command);
|
|
52
|
+
yield {
|
|
53
|
+
name: BashTool.name,
|
|
54
|
+
event: "tool-init",
|
|
55
|
+
id: toolCallId,
|
|
56
|
+
data: `${style.cyan(command)}`,
|
|
57
|
+
};
|
|
58
|
+
const pathValidation = validatePaths(command, allowedDirectories, resolvedCwd);
|
|
59
|
+
if (!pathValidation.isValid) {
|
|
60
|
+
yield {
|
|
61
|
+
name: BashTool.name,
|
|
62
|
+
event: "tool-error",
|
|
41
63
|
id: toolCallId,
|
|
42
|
-
data:
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
|
|
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
|
-
}
|
|
64
|
+
data: pathValidation.error ?? "Unknown error.",
|
|
65
|
+
};
|
|
66
|
+
yield pathValidation.error ?? "Unknown error.";
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (abortSignal?.aborted) {
|
|
70
|
+
throw new Error("Command execution aborted before running the command");
|
|
71
|
+
}
|
|
72
|
+
// Handle background execution
|
|
73
|
+
if (background) {
|
|
74
|
+
// Strip any existing & from command to avoid double backgrounding
|
|
75
|
+
let processedCommand = command.trim();
|
|
76
|
+
if (processedCommand.endsWith("&")) {
|
|
77
|
+
logger.warn(`Stripping '&' from command since background=true: ${command}`);
|
|
78
|
+
processedCommand = processedCommand.slice(0, -1).trim();
|
|
105
79
|
}
|
|
106
|
-
|
|
107
|
-
|
|
80
|
+
// Fix rg commands that don't have an explicit path
|
|
81
|
+
processedCommand = fixRgCommand(processedCommand);
|
|
82
|
+
const backgroundProcess = execEnv.executeCommandInBackground(processedCommand, {
|
|
83
|
+
cwd: resolvedCwd,
|
|
84
|
+
abortSignal,
|
|
85
|
+
onOutput: (output) => {
|
|
86
|
+
logger.debug({ output }, "Background command output:");
|
|
87
|
+
},
|
|
88
|
+
onError: (error) => {
|
|
89
|
+
logger.debug({ error }, "Background command error:");
|
|
90
|
+
},
|
|
91
|
+
onExit: (code) => {
|
|
92
|
+
logger.debug(`Background command exited with code ${code}`);
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
yield {
|
|
96
|
+
name: BashTool.name,
|
|
97
|
+
event: "tool-completion",
|
|
98
|
+
id: toolCallId,
|
|
99
|
+
data: `Background process started with PID: ${backgroundProcess.pid}`,
|
|
100
|
+
};
|
|
101
|
+
yield `Background process started with PID: ${backgroundProcess.pid}`;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Handle regular synchronous execution
|
|
105
|
+
// Strip & if present to ensure synchronous behavior
|
|
106
|
+
let processedCommand = command.trim();
|
|
107
|
+
if (processedCommand.endsWith("&")) {
|
|
108
|
+
logger.warn(`Stripping '&' from command since background=false: ${command}`);
|
|
109
|
+
processedCommand = processedCommand.slice(0, -1).trim();
|
|
108
110
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
// Fix rg commands that don't have an explicit path
|
|
112
|
+
// rg hangs when stdin is a socket and no path is given
|
|
113
|
+
processedCommand = fixRgCommand(processedCommand);
|
|
114
|
+
const { output, exitCode } = await execEnv.executeCommand(processedCommand, {
|
|
111
115
|
cwd: resolvedCwd,
|
|
112
116
|
timeout: safeTimeout,
|
|
113
117
|
abortSignal,
|
|
@@ -115,41 +119,152 @@ export const createBashTool = async ({ baseDir, sendData, tokenCounter, terminal
|
|
|
115
119
|
captureStderr: true,
|
|
116
120
|
throwOnError: false,
|
|
117
121
|
});
|
|
118
|
-
sendData?.({
|
|
119
|
-
event: "tool-update",
|
|
120
|
-
id: toolCallId,
|
|
121
|
-
data: {
|
|
122
|
-
primary: "Result",
|
|
123
|
-
secondary: output.trim().split("\n").slice(-20),
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
let tokenCount = 0;
|
|
127
122
|
try {
|
|
128
|
-
|
|
123
|
+
const result = await manageTokenLimit(output, tokenCounter, "Bash", "Adjust command to return more specific results");
|
|
124
|
+
const statusText = exitCode === 0 ? "success" : "error";
|
|
125
|
+
yield {
|
|
126
|
+
name: BashTool.name,
|
|
127
|
+
event: "tool-completion",
|
|
128
|
+
id: toolCallId,
|
|
129
|
+
data: `${statusText}${isMutating ? " *" : ""} (${result.tokenCount} tokens)`,
|
|
130
|
+
};
|
|
131
|
+
yield result.content;
|
|
129
132
|
}
|
|
130
|
-
catch (
|
|
131
|
-
|
|
133
|
+
catch (error) {
|
|
134
|
+
if (error instanceof TokenLimitExceededError) {
|
|
135
|
+
yield {
|
|
136
|
+
name: BashTool.name,
|
|
137
|
+
event: "tool-error",
|
|
138
|
+
id: toolCallId,
|
|
139
|
+
data: error.message,
|
|
140
|
+
};
|
|
141
|
+
yield error.message;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
throw error;
|
|
132
145
|
}
|
|
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",
|
|
138
|
-
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;
|
|
145
|
-
}
|
|
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;
|
|
151
146
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
logger.error(error, "Bash Tool Error:");
|
|
150
|
+
yield {
|
|
151
|
+
name: BashTool.name,
|
|
152
|
+
event: "tool-error",
|
|
153
|
+
id: toolCallId,
|
|
154
|
+
data: error.message,
|
|
155
|
+
};
|
|
156
|
+
yield error.message;
|
|
157
|
+
}
|
|
158
|
+
},
|
|
154
159
|
};
|
|
155
160
|
};
|
|
161
|
+
function getInstalledTools() {
|
|
162
|
+
// Check for required bash tools
|
|
163
|
+
const tools = [
|
|
164
|
+
{
|
|
165
|
+
name: "git",
|
|
166
|
+
command: "git --version",
|
|
167
|
+
description: "Version control system - used for cloning repositories, checking out branches, committing changes, viewing history, and managing code versions",
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: "gh",
|
|
171
|
+
command: "gh --version",
|
|
172
|
+
description: "GitHub CLI - used for creating pull requests, managing issues, interacting with GitHub API, and automating GitHub workflows",
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
name: "rg",
|
|
176
|
+
command: "rg --version",
|
|
177
|
+
description: "ripgrep - fast text search tool for searching code patterns, file contents, and regular expressions across the codebase (use this instead of grep)",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: "fd",
|
|
181
|
+
command: "fd --version",
|
|
182
|
+
description: "Fast file finder - alternative to find command, used for finding files by name, pattern, or type with intuitive syntax (use this instead of find)",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: "ast-grep",
|
|
186
|
+
command: "ast-grep --version",
|
|
187
|
+
description: "AST-based code search - used for structural code search, refactoring, finding patterns in abstract syntax trees, and code transformations",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
name: "jq",
|
|
191
|
+
command: "jq --version",
|
|
192
|
+
description: "JSON processor - used for parsing, filtering, and manipulating JSON output from APIs, commands, and configuration files",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "yq",
|
|
196
|
+
command: "yq --version",
|
|
197
|
+
description: "YAML processor - used for parsing and manipulating YAML files (configs, CI/CD pipelines, Kubernetes manifests) with jq-like syntax",
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
const toolStatus = tools
|
|
201
|
+
.map((tool) => {
|
|
202
|
+
let status = false;
|
|
203
|
+
try {
|
|
204
|
+
execSync(tool.command, { stdio: "ignore", timeout: 5000 });
|
|
205
|
+
status = true;
|
|
206
|
+
}
|
|
207
|
+
catch (_error) {
|
|
208
|
+
// Ignore error, tool is not installed
|
|
209
|
+
}
|
|
210
|
+
return { name: tool.name, description: tool.description, status };
|
|
211
|
+
})
|
|
212
|
+
.filter((tool) => tool.status)
|
|
213
|
+
.map((tool) => `- **${tool.name}**: ${tool.description}`)
|
|
214
|
+
.join("\n");
|
|
215
|
+
return toolStatus;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Fix rg commands that don't have an explicit path
|
|
219
|
+
* rg hangs when stdin is a socket and no path is given
|
|
220
|
+
* See: https://github.com/BurntSushi/ripgrep/discussions/2047
|
|
221
|
+
*/
|
|
222
|
+
function fixRgCommand(command) {
|
|
223
|
+
const trimmed = command.trim();
|
|
224
|
+
// Check if command starts with rg
|
|
225
|
+
if (!trimmed.startsWith("rg ") && !trimmed.startsWith("rg\\")) {
|
|
226
|
+
return command;
|
|
227
|
+
}
|
|
228
|
+
// Check if command already has stdin redirection or piping
|
|
229
|
+
// Don't modify commands like: cat file.txt | rg pattern
|
|
230
|
+
// or rg pattern < input.txt
|
|
231
|
+
if (trimmed.includes("|") || trimmed.includes("<") || trimmed.includes(">")) {
|
|
232
|
+
return command;
|
|
233
|
+
}
|
|
234
|
+
// Simple heuristic: if last token starts with -, add .
|
|
235
|
+
// This handles cases like: rg -l pattern --type ts --type js
|
|
236
|
+
const tokens = trimmed.split(/\\s+/);
|
|
237
|
+
const lastToken = tokens[tokens.length - 1];
|
|
238
|
+
if (lastToken?.startsWith("-")) {
|
|
239
|
+
// Command ends with an option, need to add path
|
|
240
|
+
logger.debug(`Adding '.' to rg command: ${command}`);
|
|
241
|
+
return `${command} .`;
|
|
242
|
+
}
|
|
243
|
+
// Last token doesn't start with -, could be a path or pattern
|
|
244
|
+
if (lastToken) {
|
|
245
|
+
// If it's ., ./, /, or contains /, assume it's a path
|
|
246
|
+
if (lastToken === "." ||
|
|
247
|
+
lastToken.startsWith("./") ||
|
|
248
|
+
lastToken.startsWith("/") ||
|
|
249
|
+
lastToken.includes("/") ||
|
|
250
|
+
lastToken === "..") {
|
|
251
|
+
// Already has a path
|
|
252
|
+
return command;
|
|
253
|
+
}
|
|
254
|
+
// Check if it's a simple pattern (no special chars that would make it a path)
|
|
255
|
+
// If it's just alphanumeric with maybe some regex chars, it's probably a pattern
|
|
256
|
+
// Common pattern chars: ., *, +, ?, [, ], ^, $, (, ), |, \\
|
|
257
|
+
// But we want to be conservative - if it looks like a filename without path, add .
|
|
258
|
+
if (!lastToken.includes("/") && !lastToken.includes("*")) {
|
|
259
|
+
// Doesn't look like a path with glob or directory, likely a pattern
|
|
260
|
+
// Need to add path
|
|
261
|
+
logger.debug(`Adding '.' to rg command: ${command}`);
|
|
262
|
+
return `${command} .`;
|
|
263
|
+
}
|
|
264
|
+
// Complex case with * or other chars, could be a glob pattern
|
|
265
|
+
// Default to adding . to be safe
|
|
266
|
+
}
|
|
267
|
+
// No last token or complex case, add . to be safe
|
|
268
|
+
logger.debug(`Adding '.' to rg command: ${command}`);
|
|
269
|
+
return `${command} .`;
|
|
270
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
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";
|
|
5
|
+
export declare const BatchTool: {
|
|
6
|
+
name: "batch";
|
|
7
|
+
};
|
|
8
|
+
declare const inputSchema: z.ZodObject<{
|
|
9
|
+
calls: z.ZodArray<z.ZodObject<{
|
|
10
|
+
tool: z.ZodString;
|
|
11
|
+
arguments: z.ZodRecord<z.ZodAny, z.ZodAny>;
|
|
12
|
+
id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, z.core.$strip>>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
type BatchInputSchema = z.infer<typeof inputSchema>;
|
|
16
|
+
type ToolExecutor = (args: Record<string, unknown>, options: ToolCallOptions) => AsyncGenerator<ToolResult> | Promise<string>;
|
|
17
|
+
export declare const createBatchTool: ({ tokenCounter, executors, }: {
|
|
18
|
+
tokenCounter: TokenCounter;
|
|
19
|
+
executors: Map<string, ToolExecutor>;
|
|
20
|
+
}) => Promise<{
|
|
21
|
+
toolDef: {
|
|
22
|
+
description: string;
|
|
23
|
+
inputSchema: z.ZodObject<{
|
|
24
|
+
calls: z.ZodArray<z.ZodObject<{
|
|
25
|
+
tool: z.ZodString;
|
|
26
|
+
arguments: z.ZodRecord<z.ZodAny, z.ZodAny>;
|
|
27
|
+
id: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
};
|
|
31
|
+
execute({ calls }: BatchInputSchema, { toolCallId, messages, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
32
|
+
}>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=batch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batch.d.ts","sourceRoot":"","sources":["../../source/tools/batch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,SAAS;;CAErB,CAAC;AAaF,QAAA,MAAM,WAAW;;;;;;iBAMf,CAAC;AAEH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AACpD,KAAK,YAAY,GAAG,CAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,eAAe,KACrB,cAAc,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAElD,eAAO,MAAM,eAAe,GAAU,8BAGnC;IACD,YAAY,EAAE,YAAY,CAAC;IAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtC;;;;;;;;;;;uBAQgB,gBAAgB,yCACY,eAAe,GACrD,cAAc,CAAC,UAAU,CAAC;EAkLhC,CAAC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { logger } from "../logger.js";
|
|
3
|
+
import style from "../terminal/style.js";
|
|
4
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
5
|
+
export const BatchTool = {
|
|
6
|
+
name: "batch",
|
|
7
|
+
};
|
|
8
|
+
const toolCallSchema = z.object({
|
|
9
|
+
tool: z.string().describe("Name of the tool to execute"),
|
|
10
|
+
arguments: z
|
|
11
|
+
.record(z.any(), z.any())
|
|
12
|
+
.describe("Arguments to pass to the tool"),
|
|
13
|
+
id: z
|
|
14
|
+
.string()
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Optional ID for tracking this specific call"),
|
|
17
|
+
});
|
|
18
|
+
const inputSchema = z.object({
|
|
19
|
+
calls: z
|
|
20
|
+
.array(toolCallSchema)
|
|
21
|
+
.min(1)
|
|
22
|
+
.max(10)
|
|
23
|
+
.describe("Array of tool calls to execute in sequence"),
|
|
24
|
+
});
|
|
25
|
+
export const createBatchTool = async ({ tokenCounter, executors, }) => {
|
|
26
|
+
return {
|
|
27
|
+
toolDef: {
|
|
28
|
+
description: "Execute multiple tool calls in a single request. Reduces roundtrips by batching operations. Tools are executed sequentially in the order provided.",
|
|
29
|
+
inputSchema,
|
|
30
|
+
},
|
|
31
|
+
async *execute({ calls }, { toolCallId, messages, abortSignal }) {
|
|
32
|
+
try {
|
|
33
|
+
if (abortSignal?.aborted) {
|
|
34
|
+
throw new Error("Batch execution aborted");
|
|
35
|
+
}
|
|
36
|
+
const totalCalls = calls.length;
|
|
37
|
+
yield {
|
|
38
|
+
name: BatchTool.name,
|
|
39
|
+
event: "tool-init",
|
|
40
|
+
id: toolCallId,
|
|
41
|
+
data: `Starting batch execution of ${totalCalls} tool calls`,
|
|
42
|
+
};
|
|
43
|
+
const results = [];
|
|
44
|
+
for (let i = 0; i < calls.length; i++) {
|
|
45
|
+
const call = calls[i];
|
|
46
|
+
const { tool: toolName, arguments: args, id: callId } = call;
|
|
47
|
+
const callNumber = i + 1;
|
|
48
|
+
if (abortSignal?.aborted) {
|
|
49
|
+
results.push({
|
|
50
|
+
tool: toolName,
|
|
51
|
+
id: callId,
|
|
52
|
+
status: "error",
|
|
53
|
+
error: "Batch execution aborted",
|
|
54
|
+
});
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const executor = executors.get(toolName);
|
|
58
|
+
if (!executor) {
|
|
59
|
+
results.push({
|
|
60
|
+
tool: toolName,
|
|
61
|
+
id: callId,
|
|
62
|
+
status: "error",
|
|
63
|
+
error: `Unknown tool '${toolName}'`,
|
|
64
|
+
});
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
yield {
|
|
68
|
+
name: BatchTool.name,
|
|
69
|
+
event: "tool-update",
|
|
70
|
+
id: toolCallId,
|
|
71
|
+
data: `[${callNumber}/${totalCalls}] ${style.cyan(toolName)}${callId ? ` (${callId})` : ""} ${style.dim(JSON.stringify(args).slice(0, 60))}...`,
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
const executorResult = executor(args, {
|
|
75
|
+
toolCallId: callId || `${toolCallId}-${i}`,
|
|
76
|
+
messages,
|
|
77
|
+
abortSignal,
|
|
78
|
+
});
|
|
79
|
+
let toolOutput = "";
|
|
80
|
+
// Handle both async generators and regular async functions
|
|
81
|
+
if (typeof executorResult[Symbol.asyncIterator] === "function") {
|
|
82
|
+
// It's an async generator
|
|
83
|
+
const generator = executorResult;
|
|
84
|
+
for await (const chunk of generator) {
|
|
85
|
+
if (typeof chunk === "string") {
|
|
86
|
+
toolOutput += chunk;
|
|
87
|
+
}
|
|
88
|
+
else if (chunk.event === "tool-completion") {
|
|
89
|
+
// Capture completion message
|
|
90
|
+
toolOutput += chunk.data;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
// It's a regular async function returning a string
|
|
96
|
+
toolOutput = await executorResult;
|
|
97
|
+
}
|
|
98
|
+
results.push({
|
|
99
|
+
tool: toolName,
|
|
100
|
+
id: callId,
|
|
101
|
+
status: "success",
|
|
102
|
+
result: toolOutput,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
107
|
+
logger.error({ error, toolName, args }, "Batch tool execution failed");
|
|
108
|
+
results.push({
|
|
109
|
+
tool: toolName,
|
|
110
|
+
id: callId,
|
|
111
|
+
status: "error",
|
|
112
|
+
error: errorMessage,
|
|
113
|
+
});
|
|
114
|
+
// Yield update for failed command
|
|
115
|
+
yield {
|
|
116
|
+
name: BatchTool.name,
|
|
117
|
+
event: "tool-update",
|
|
118
|
+
id: toolCallId,
|
|
119
|
+
data: `[${callNumber}/${totalCalls}] ${style.red("✗")} ${style.cyan(toolName)} failed: ${errorMessage.slice(0, 100)}`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Format results as JSON
|
|
124
|
+
const jsonResults = JSON.stringify(results, null, 2);
|
|
125
|
+
try {
|
|
126
|
+
const result = await manageTokenLimit(jsonResults, tokenCounter, "Batch", "Consider reducing the number of calls or using more specific tool calls");
|
|
127
|
+
// Create a more informative completion message
|
|
128
|
+
const successful = results.filter((r) => r.status === "success").length;
|
|
129
|
+
const failed = results.filter((r) => r.status === "error").length;
|
|
130
|
+
let completionMessage = `Batch execution completed: ${successful}/${totalCalls} successful`;
|
|
131
|
+
if (failed > 0) {
|
|
132
|
+
const failedTools = results
|
|
133
|
+
.filter((r) => r.status === "error")
|
|
134
|
+
.map((r) => `${r.tool}${r.id ? ` (${r.id})` : ""}`)
|
|
135
|
+
.join(", ");
|
|
136
|
+
completionMessage += `, ${failed} failed: ${failedTools}`;
|
|
137
|
+
}
|
|
138
|
+
completionMessage += ` (${result.tokenCount} tokens)`;
|
|
139
|
+
yield {
|
|
140
|
+
name: BatchTool.name,
|
|
141
|
+
event: "tool-completion",
|
|
142
|
+
id: toolCallId,
|
|
143
|
+
data: completionMessage,
|
|
144
|
+
};
|
|
145
|
+
yield result.content;
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
if (error instanceof TokenLimitExceededError) {
|
|
149
|
+
yield {
|
|
150
|
+
name: BatchTool.name,
|
|
151
|
+
event: "tool-error",
|
|
152
|
+
id: toolCallId,
|
|
153
|
+
data: error.message,
|
|
154
|
+
};
|
|
155
|
+
yield error.message;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
163
|
+
logger.error({ error }, "Batch tool failed");
|
|
164
|
+
yield {
|
|
165
|
+
name: BatchTool.name,
|
|
166
|
+
event: "tool-error",
|
|
167
|
+
id: toolCallId,
|
|
168
|
+
data: errorMessage,
|
|
169
|
+
};
|
|
170
|
+
yield errorMessage;
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
};
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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":"
|
|
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;AAKzD,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;EAoL9B,CAAC"}
|