@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
|
@@ -1,91 +1,178 @@
|
|
|
1
1
|
import { readFile } from "node:fs/promises";
|
|
2
|
-
import { tool } from "ai";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import { config } from "../config.js";
|
|
5
3
|
import { formatFile } from "../formatting.js";
|
|
6
4
|
import style from "../terminal/style.js";
|
|
7
|
-
import {
|
|
5
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
6
|
+
import { joinWorkingDir, validatePath } from "../utils/filesystem/security.js";
|
|
8
7
|
export const ReadMultipleFilesTool = {
|
|
9
8
|
name: "readMultipleFiles",
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
const inputSchema = z.object({
|
|
11
|
+
paths: z.array(z.string()),
|
|
12
|
+
});
|
|
13
|
+
export const createReadMultipleFilesTool = async ({ workingDir, allowedDirs, tokenCounter, }) => {
|
|
14
|
+
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
13
15
|
return {
|
|
14
|
-
|
|
16
|
+
toolDef: {
|
|
15
17
|
description: "Read the contents of multiple files simultaneously. This is more " +
|
|
16
18
|
"efficient than reading files one by one when you need to analyze " +
|
|
17
19
|
"or compare multiple files. Each file's content is returned with its " +
|
|
18
20
|
"path as a reference. Failed reads for individual files won't stop " +
|
|
19
21
|
"the entire operation. Only works within allowed directories.",
|
|
20
|
-
inputSchema
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
inputSchema,
|
|
23
|
+
},
|
|
24
|
+
async *execute({ paths }, { toolCallId, abortSignal }) {
|
|
25
|
+
try {
|
|
24
26
|
// Check if execution has been aborted
|
|
25
27
|
if (abortSignal?.aborted) {
|
|
26
28
|
throw new Error("Multiple file reading aborted");
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
yield {
|
|
31
|
+
name: ReadMultipleFilesTool.name,
|
|
29
32
|
id: toolCallId,
|
|
30
33
|
event: "tool-init",
|
|
31
|
-
data:
|
|
32
|
-
}
|
|
34
|
+
data: `${paths.map((p) => style.cyan(p)).join(", ")}`,
|
|
35
|
+
};
|
|
33
36
|
if (abortSignal?.aborted) {
|
|
34
37
|
throw new Error("Multiple file reading aborted before reading files");
|
|
35
38
|
}
|
|
36
|
-
const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
|
|
37
39
|
const results = await Promise.all(paths.map(async (filePath) => {
|
|
38
40
|
if (abortSignal?.aborted) {
|
|
39
41
|
throw new Error("Multiple file reading aborted during file processing");
|
|
40
42
|
}
|
|
41
43
|
const fileResult = await validateAndReadFile(filePath, workingDir, allowedDirectory);
|
|
42
|
-
return
|
|
44
|
+
return fileResult;
|
|
43
45
|
}));
|
|
44
|
-
|
|
45
|
-
let filesReadCount = 0;
|
|
46
|
-
let filesExceededLimitCount = 0;
|
|
47
|
-
let filesErrorCount = 0;
|
|
48
|
-
const formattedResults = results.map((result) => {
|
|
46
|
+
const processedResults = await Promise.all(results.map(async (result) => {
|
|
49
47
|
if (result.error) {
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
return {
|
|
49
|
+
path: result.path,
|
|
50
|
+
content: `${result.path}: Error - ${result.error}`,
|
|
51
|
+
tokenCount: 0,
|
|
52
|
+
error: result.error,
|
|
53
|
+
truncated: false,
|
|
54
|
+
};
|
|
52
55
|
}
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
// Apply token limit check to each file
|
|
57
|
+
try {
|
|
58
|
+
const managedResult = await manageTokenLimit(result.content ?? "", tokenCounter, "ReadMultipleFiles", "Use readFile with startLine/lineCount or grepFiles for targeted access");
|
|
59
|
+
return {
|
|
60
|
+
path: result.path,
|
|
61
|
+
content: formatFile(result.path, managedResult.content, "markdown"),
|
|
62
|
+
tokenCount: managedResult.tokenCount,
|
|
63
|
+
error: null,
|
|
64
|
+
exceededLimit: false,
|
|
65
|
+
};
|
|
56
66
|
}
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
catch (error) {
|
|
68
|
+
if (error instanceof TokenLimitExceededError) {
|
|
69
|
+
return {
|
|
70
|
+
path: result.path,
|
|
71
|
+
content: error.message,
|
|
72
|
+
tokenCount: 0,
|
|
73
|
+
error: null,
|
|
74
|
+
exceededLimit: true,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
}));
|
|
80
|
+
const formattedResults = processedResults.map((r) => r.content);
|
|
81
|
+
try {
|
|
82
|
+
const finalResult = await manageTokenLimit(formattedResults.join("\n---\n"), tokenCounter, "ReadMultipleFiles", "Reduce number of files or use more specific paths");
|
|
83
|
+
// Aggregate results with detailed breakdown
|
|
84
|
+
let totalTokens = 0;
|
|
85
|
+
let filesReadCount = 0;
|
|
86
|
+
let filesExceededLimitCount = 0;
|
|
87
|
+
let filesErrorCount = 0;
|
|
88
|
+
for (const processedResult of processedResults) {
|
|
89
|
+
if (processedResult.error) {
|
|
90
|
+
filesErrorCount++;
|
|
91
|
+
}
|
|
92
|
+
else if (processedResult.exceededLimit) {
|
|
93
|
+
filesExceededLimitCount++;
|
|
94
|
+
totalTokens += processedResult.tokenCount;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
filesReadCount++;
|
|
98
|
+
totalTokens += processedResult.tokenCount;
|
|
99
|
+
}
|
|
59
100
|
}
|
|
60
|
-
totalTokens += result.tokenCount; // Add the token count (will be 0 for skipped files)
|
|
61
|
-
// Return content (or max token message)
|
|
62
|
-
return formatFile(result.path, result.content ?? "", "markdown");
|
|
63
|
-
});
|
|
64
|
-
let completionMessage;
|
|
65
|
-
if (filesReadCount === paths.length) {
|
|
66
|
-
completionMessage = `Read ${paths.length} files successfully (${totalTokens} total tokens).`;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
101
|
const parts = [];
|
|
70
102
|
if (filesReadCount > 0) {
|
|
71
103
|
parts.push(`Read ${filesReadCount} files successfully (${totalTokens} total tokens)`);
|
|
72
104
|
}
|
|
73
105
|
if (filesExceededLimitCount > 0) {
|
|
74
|
-
parts.push(`${filesExceededLimitCount} files exceeded token limit
|
|
106
|
+
parts.push(`${filesExceededLimitCount} files exceeded token limit`);
|
|
75
107
|
}
|
|
76
108
|
if (filesErrorCount > 0) {
|
|
77
109
|
parts.push(`${filesErrorCount} files could not be read`);
|
|
78
110
|
}
|
|
79
|
-
|
|
111
|
+
// Note: If we reach here, finalResult succeeded (no TokenLimitExceededError thrown)
|
|
112
|
+
const completionMessage = `${parts.join(", ")}.`;
|
|
113
|
+
yield {
|
|
114
|
+
name: ReadMultipleFilesTool.name,
|
|
115
|
+
id: toolCallId,
|
|
116
|
+
event: "tool-completion",
|
|
117
|
+
data: completionMessage,
|
|
118
|
+
};
|
|
119
|
+
yield finalResult.content;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof TokenLimitExceededError) {
|
|
123
|
+
// Combined output exceeded limit
|
|
124
|
+
const parts = [];
|
|
125
|
+
let totalTokens = 0;
|
|
126
|
+
let filesReadCount = 0;
|
|
127
|
+
let filesExceededLimitCount = 0;
|
|
128
|
+
let filesErrorCount = 0;
|
|
129
|
+
for (const processedResult of processedResults) {
|
|
130
|
+
if (processedResult.error) {
|
|
131
|
+
filesErrorCount++;
|
|
132
|
+
}
|
|
133
|
+
else if (processedResult.exceededLimit) {
|
|
134
|
+
filesExceededLimitCount++;
|
|
135
|
+
totalTokens += processedResult.tokenCount;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
filesReadCount++;
|
|
139
|
+
totalTokens += processedResult.tokenCount;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (filesReadCount > 0) {
|
|
143
|
+
parts.push(`Read ${filesReadCount} files successfully (${totalTokens} total tokens)`);
|
|
144
|
+
}
|
|
145
|
+
if (filesExceededLimitCount > 0) {
|
|
146
|
+
parts.push(`${filesExceededLimitCount} files exceeded token limit`);
|
|
147
|
+
}
|
|
148
|
+
if (filesErrorCount > 0) {
|
|
149
|
+
parts.push(`${filesErrorCount} files could not be read`);
|
|
150
|
+
}
|
|
151
|
+
parts.push(`Combined output exceeded token limit. ${error.message}`);
|
|
152
|
+
const completionMessage = `${parts.join(", ")}.`;
|
|
153
|
+
yield {
|
|
154
|
+
name: ReadMultipleFilesTool.name,
|
|
155
|
+
event: "tool-error",
|
|
156
|
+
id: toolCallId,
|
|
157
|
+
data: completionMessage,
|
|
158
|
+
};
|
|
159
|
+
yield error.message;
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
throw error;
|
|
80
163
|
}
|
|
81
|
-
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
const errorMsg = error.message;
|
|
167
|
+
yield {
|
|
168
|
+
name: ReadMultipleFilesTool.name,
|
|
82
169
|
id: toolCallId,
|
|
83
|
-
event: "tool-
|
|
84
|
-
data:
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
}
|
|
170
|
+
event: "tool-error",
|
|
171
|
+
data: errorMsg,
|
|
172
|
+
};
|
|
173
|
+
yield errorMsg;
|
|
174
|
+
}
|
|
175
|
+
},
|
|
89
176
|
};
|
|
90
177
|
};
|
|
91
178
|
async function validateAndReadFile(filePath, workingDir, allowedDirectory) {
|
|
@@ -107,30 +194,3 @@ async function validateAndReadFile(filePath, workingDir, allowedDirectory) {
|
|
|
107
194
|
};
|
|
108
195
|
}
|
|
109
196
|
}
|
|
110
|
-
async function countTokensAndCheckLimit(fileResult, tokenCounter, maxTokens) {
|
|
111
|
-
if (fileResult.error || fileResult.content === null) {
|
|
112
|
-
return {
|
|
113
|
-
path: fileResult.path,
|
|
114
|
-
content: null,
|
|
115
|
-
tokenCount: 0,
|
|
116
|
-
error: fileResult.error,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
let tokenCount = 0;
|
|
120
|
-
try {
|
|
121
|
-
tokenCount = tokenCounter.count(fileResult.content);
|
|
122
|
-
}
|
|
123
|
-
catch (tokenError) {
|
|
124
|
-
console.error("Error calculating token count:", tokenError);
|
|
125
|
-
// Handle token calculation error if needed
|
|
126
|
-
}
|
|
127
|
-
const maxTokenMessage = `File content (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}). Use readFile with startLine/lineCount or grepFiles for targeted access.`;
|
|
128
|
-
const finalContent = tokenCount > maxTokens ? maxTokenMessage : fileResult.content;
|
|
129
|
-
const actualTokenCount = tokenCount > maxTokens ? 0 : tokenCount; // Don't count tokens for skipped files
|
|
130
|
-
return {
|
|
131
|
-
path: fileResult.path,
|
|
132
|
-
content: finalContent,
|
|
133
|
-
tokenCount: actualTokenCount,
|
|
134
|
-
error: null,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
@@ -1,19 +1,52 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
3
|
-
import { type
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { type ToolResult } from "./types.ts";
|
|
4
4
|
export declare const SaveFileTool: {
|
|
5
5
|
name: "saveFile";
|
|
6
6
|
};
|
|
7
|
-
|
|
7
|
+
declare const inputSchema: z.ZodObject<{
|
|
8
|
+
path: z.ZodString;
|
|
9
|
+
content: z.ZodString;
|
|
10
|
+
encoding: z.ZodDefault<z.ZodEnum<{
|
|
11
|
+
utf8: "utf8";
|
|
12
|
+
ascii: "ascii";
|
|
13
|
+
"utf-8": "utf-8";
|
|
14
|
+
utf16le: "utf16le";
|
|
15
|
+
ucs2: "ucs2";
|
|
16
|
+
"ucs-2": "ucs-2";
|
|
17
|
+
base64: "base64";
|
|
18
|
+
base64url: "base64url";
|
|
19
|
+
latin1: "latin1";
|
|
20
|
+
binary: "binary";
|
|
21
|
+
hex: "hex";
|
|
22
|
+
}>>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
type SaveFileInputSchema = z.infer<typeof inputSchema>;
|
|
25
|
+
export declare const createSaveFileTool: ({ workingDir, allowedDirs, }: {
|
|
8
26
|
workingDir: string;
|
|
9
|
-
|
|
10
|
-
sendData?: SendData;
|
|
11
|
-
toolExecutor?: ToolExecutor;
|
|
27
|
+
allowedDirs?: string[];
|
|
12
28
|
}) => Promise<{
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
29
|
+
toolDef: {
|
|
30
|
+
description: string;
|
|
31
|
+
inputSchema: z.ZodObject<{
|
|
32
|
+
path: z.ZodString;
|
|
33
|
+
content: z.ZodString;
|
|
34
|
+
encoding: z.ZodDefault<z.ZodEnum<{
|
|
35
|
+
utf8: "utf8";
|
|
36
|
+
ascii: "ascii";
|
|
37
|
+
"utf-8": "utf-8";
|
|
38
|
+
utf16le: "utf16le";
|
|
39
|
+
ucs2: "ucs2";
|
|
40
|
+
"ucs-2": "ucs-2";
|
|
41
|
+
base64: "base64";
|
|
42
|
+
base64url: "base64url";
|
|
43
|
+
latin1: "latin1";
|
|
44
|
+
binary: "binary";
|
|
45
|
+
hex: "hex";
|
|
46
|
+
}>>;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
};
|
|
49
|
+
execute({ path: userPath, content, encoding }: SaveFileInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
18
50
|
}>;
|
|
51
|
+
export {};
|
|
19
52
|
//# sourceMappingURL=save-file.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save-file.d.ts","sourceRoot":"","sources":["../../source/tools/save-file.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"save-file.d.ts","sourceRoot":"","sources":["../../source/tools/save-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,OAAO,EAAsB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAEjE,eAAO,MAAM,YAAY;;CAExB,CAAC;AAEF,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;iBAQf,CAAC;AAEH,KAAK,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEvD,eAAO,MAAM,kBAAkB,GAAU,8BAGtC;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;;;;;;;;;;;;;;;;;;;;;mDAa4C,mBAAmB,+BAC7B,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EAuFhC,CAAC"}
|
package/dist/tools/save-file.js
CHANGED
|
@@ -1,126 +1,101 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import { tool } from "ai";
|
|
4
3
|
import { z } from "zod";
|
|
5
|
-
import {
|
|
4
|
+
import { config } from "../config.js";
|
|
5
|
+
import { clearProjectStatusCache } from "../repl/project-status-line.js";
|
|
6
6
|
import style from "../terminal/style.js";
|
|
7
|
-
import { joinWorkingDir, validatePath } from "
|
|
7
|
+
import { joinWorkingDir, validateFileNotReadOnly, validatePath, } from "../utils/filesystem/security.js";
|
|
8
8
|
import { fileEncodingSchema } from "./types.js";
|
|
9
9
|
export const SaveFileTool = {
|
|
10
10
|
name: "saveFile",
|
|
11
11
|
};
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const inputSchema = z.object({
|
|
13
|
+
path: z.string().describe("Absolute path to file to save to"),
|
|
14
|
+
content: z.string().describe("Content to save in the file"),
|
|
15
|
+
encoding: fileEncodingSchema
|
|
16
|
+
.describe('Encoding format for saving the file. Use "utf-8" as default for text files')
|
|
17
|
+
.default("utf-8"),
|
|
18
|
+
});
|
|
19
|
+
export const createSaveFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
20
|
+
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
14
21
|
return {
|
|
15
|
-
|
|
22
|
+
toolDef: {
|
|
16
23
|
description: "Create a new file or completely overwrite an existing file with new content. " +
|
|
17
24
|
"Automatically creates all missing parent directories. " +
|
|
18
25
|
"Use with caution as it will overwrite existing files without warning. " +
|
|
19
26
|
"Handles text content with proper encoding. Only works within allowed directories.",
|
|
20
|
-
inputSchema
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}),
|
|
25
|
-
execute: async ({ path: userPath, content, encoding, }, { toolCallId, abortSignal }) => {
|
|
26
|
-
// Check if execution has been aborted
|
|
27
|
+
inputSchema,
|
|
28
|
+
},
|
|
29
|
+
async *execute({ path: userPath, content, encoding }, { toolCallId, abortSignal }) {
|
|
30
|
+
try {
|
|
27
31
|
if (abortSignal?.aborted) {
|
|
28
32
|
throw new Error("File saving aborted");
|
|
29
33
|
}
|
|
30
|
-
|
|
31
|
-
|
|
34
|
+
yield {
|
|
35
|
+
name: SaveFileTool.name,
|
|
32
36
|
event: "tool-init",
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
id: toolCallId,
|
|
38
|
+
data: `${style.cyan(userPath)}`,
|
|
39
|
+
};
|
|
40
|
+
const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory, { requireExistence: false, abortSignal });
|
|
41
|
+
// Check if file is read-only (only if it exists)
|
|
35
42
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Determine overwrite status for display
|
|
45
|
-
let overwriteMessage = "";
|
|
46
|
-
try {
|
|
47
|
-
const stat = await fs.stat(filePath);
|
|
48
|
-
if (stat.isFile()) {
|
|
49
|
-
overwriteMessage = style.yellow("(Will overwrite existing file)");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
catch {
|
|
53
|
-
overwriteMessage = style.green("(Will create new file)");
|
|
54
|
-
}
|
|
55
|
-
let userResponse;
|
|
56
|
-
if (toolExecutor) {
|
|
57
|
-
const ctx = {
|
|
58
|
-
toolName: SaveFileTool.name,
|
|
59
|
-
toolCallId,
|
|
60
|
-
message: `What would you like to do with this save? ${overwriteMessage}`,
|
|
61
|
-
choices: {
|
|
62
|
-
accept: "Accept this save",
|
|
63
|
-
acceptAll: "Accept all future saves (including this)",
|
|
64
|
-
reject: "Reject this save",
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
try {
|
|
68
|
-
userResponse = await toolExecutor.ask(ctx, { abortSignal });
|
|
69
|
-
}
|
|
70
|
-
catch (e) {
|
|
71
|
-
if (e.name === "AbortError") {
|
|
72
|
-
throw new Error("File saving aborted during user input");
|
|
73
|
-
}
|
|
74
|
-
throw e;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
const { result: userChoice, reason } = userResponse ?? {
|
|
78
|
-
result: "accept",
|
|
79
|
-
};
|
|
80
|
-
terminal.lineBreak();
|
|
81
|
-
if (userChoice === "accept-all") {
|
|
82
|
-
terminal.writeln(style.yellow("✓ Auto-accept mode enabled for all saves"));
|
|
83
|
-
terminal.lineBreak();
|
|
84
|
-
}
|
|
85
|
-
if (userChoice === "reject") {
|
|
86
|
-
terminal.lineBreak();
|
|
87
|
-
const rejectionReason = reason || "No reason provided";
|
|
88
|
-
sendData?.({
|
|
89
|
-
id: toolCallId,
|
|
90
|
-
event: "tool-completion",
|
|
91
|
-
data: `Save rejected by user. Reason: ${rejectionReason}`,
|
|
92
|
-
});
|
|
93
|
-
return `The user rejected this save. Reason: ${rejectionReason}`;
|
|
94
|
-
}
|
|
95
|
-
// If accepted, proceed to write file
|
|
43
|
+
await fs.stat(filePath);
|
|
44
|
+
const projectConfig = await config.getConfig();
|
|
45
|
+
validateFileNotReadOnly(filePath, projectConfig, workingDir);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// File doesn't exist, so it's not read-only
|
|
49
|
+
if (error.code !== "ENOENT") {
|
|
50
|
+
throw error;
|
|
96
51
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
52
|
+
}
|
|
53
|
+
// Check if path exists and is a directory
|
|
54
|
+
try {
|
|
55
|
+
const stat = await fs.stat(filePath);
|
|
56
|
+
if (stat.isDirectory()) {
|
|
57
|
+
throw new Error(`Cannot save file - path is a directory: ${filePath}`);
|
|
100
58
|
}
|
|
101
|
-
// Ensure parent directory exists (create missing parents)
|
|
102
|
-
const parentDir = path.dirname(filePath);
|
|
103
|
-
await fs.mkdir(parentDir, { recursive: true });
|
|
104
|
-
await fs.writeFile(filePath, content, {
|
|
105
|
-
encoding,
|
|
106
|
-
signal: abortSignal,
|
|
107
|
-
});
|
|
108
|
-
sendData?.({
|
|
109
|
-
id: toolCallId,
|
|
110
|
-
event: "tool-completion",
|
|
111
|
-
data: `File saved successfully: ${userPath}`,
|
|
112
|
-
});
|
|
113
|
-
return `File saved successfully: ${filePath}`;
|
|
114
59
|
}
|
|
115
60
|
catch (error) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}
|
|
121
|
-
|
|
61
|
+
// Only re-throw if it's our directory error, otherwise continue (file doesn't exist)
|
|
62
|
+
if (error instanceof Error &&
|
|
63
|
+
error.message.includes("is a directory")) {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Pre-side-effect check
|
|
68
|
+
if (abortSignal?.aborted) {
|
|
69
|
+
throw new Error("File saving aborted before writing");
|
|
122
70
|
}
|
|
123
|
-
|
|
124
|
-
|
|
71
|
+
// Ensure parent directory exists (create missing parents)
|
|
72
|
+
const parentDir = path.dirname(filePath);
|
|
73
|
+
await fs.mkdir(parentDir, { recursive: true });
|
|
74
|
+
await fs.writeFile(filePath, content, {
|
|
75
|
+
encoding,
|
|
76
|
+
signal: abortSignal,
|
|
77
|
+
});
|
|
78
|
+
const lines = content.split("\n").length;
|
|
79
|
+
const bytes = Buffer.byteLength(content, encoding);
|
|
80
|
+
yield {
|
|
81
|
+
name: SaveFileTool.name,
|
|
82
|
+
event: "tool-completion",
|
|
83
|
+
id: toolCallId,
|
|
84
|
+
data: `Saved ${lines} lines, ${bytes} bytes`,
|
|
85
|
+
};
|
|
86
|
+
// Clear project status cache since file operations change git status
|
|
87
|
+
clearProjectStatusCache();
|
|
88
|
+
yield `File saved successfully: ${filePath}`;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
yield {
|
|
92
|
+
name: SaveFileTool.name,
|
|
93
|
+
event: "tool-error",
|
|
94
|
+
id: toolCallId,
|
|
95
|
+
data: error.message,
|
|
96
|
+
};
|
|
97
|
+
yield `Failed to save file: ${error.message}`;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
125
100
|
};
|
|
126
101
|
};
|
package/dist/tools/think.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolCallOptions } from "ai";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ToolResult } from "./types.ts";
|
|
2
4
|
export declare const ThinkTool: {
|
|
3
5
|
name: "think";
|
|
4
6
|
};
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
declare const inputSchema: z.ZodObject<{
|
|
8
|
+
thought: z.ZodString;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
export declare const createThinkTool: () => {
|
|
11
|
+
toolDef: {
|
|
12
|
+
description: string;
|
|
13
|
+
inputSchema: z.ZodObject<{
|
|
14
|
+
thought: z.ZodString;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
};
|
|
17
|
+
execute({ thought }: z.infer<typeof inputSchema>, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
11
18
|
};
|
|
19
|
+
export {};
|
|
12
20
|
//# sourceMappingURL=think.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,SAAS;;CAErB,CAAC;AAWF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;yBAOT,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACX,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;CA4ChC,CAAC"}
|
package/dist/tools/think.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { tool } from "ai";
|
|
2
1
|
import { z } from "zod";
|
|
3
2
|
export const ThinkTool = {
|
|
4
3
|
name: "think",
|
|
@@ -11,39 +10,54 @@ Common use cases:
|
|
|
11
10
|
4. When designing a new feature, use this tool to think through architecture decisions and implementation details
|
|
12
11
|
5. When debugging a complex issue, use this tool to organize your thoughts and hypotheses
|
|
13
12
|
The tool simply logs your thought process for better transparency and does not execute any code or make changes.`;
|
|
13
|
+
const inputSchema = z.object({
|
|
14
|
+
thought: z.string().describe("Your thought"),
|
|
15
|
+
});
|
|
14
16
|
// This is a no-op tool that logs a thought. It is inspired by the tau-bench think tool.
|
|
15
|
-
export const createThinkTool = (
|
|
16
|
-
const { sendData } = options;
|
|
17
|
+
export const createThinkTool = () => {
|
|
17
18
|
return {
|
|
18
|
-
|
|
19
|
+
toolDef: {
|
|
19
20
|
description: toolDescription,
|
|
20
|
-
inputSchema
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
inputSchema,
|
|
22
|
+
},
|
|
23
|
+
async *execute({ thought }, { toolCallId, abortSignal }) {
|
|
24
|
+
try {
|
|
24
25
|
// Check if execution has been aborted
|
|
25
26
|
if (abortSignal?.aborted) {
|
|
26
27
|
throw new Error("Thinking process aborted");
|
|
27
28
|
}
|
|
28
29
|
// Replace literal '\\n' with actual newline characters
|
|
29
30
|
const formattedThought = thought.replace(/\\n/g, "\n");
|
|
30
|
-
|
|
31
|
+
yield {
|
|
32
|
+
name: ThinkTool.name,
|
|
31
33
|
event: "tool-init",
|
|
32
34
|
id: toolCallId,
|
|
33
|
-
data: "Logging
|
|
34
|
-
}
|
|
35
|
-
|
|
35
|
+
data: "Logging thought",
|
|
36
|
+
};
|
|
37
|
+
yield {
|
|
38
|
+
name: ThinkTool.name,
|
|
36
39
|
event: "tool-update",
|
|
37
40
|
id: toolCallId,
|
|
38
|
-
data: {
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
+
data: `${formattedThought}`,
|
|
42
|
+
};
|
|
43
|
+
yield {
|
|
44
|
+
name: ThinkTool.name,
|
|
41
45
|
event: "tool-completion",
|
|
42
46
|
id: toolCallId,
|
|
43
|
-
data: "
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
|
|
47
|
+
data: "Thought logged",
|
|
48
|
+
};
|
|
49
|
+
yield "Your thought has been logged.";
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
53
|
+
yield {
|
|
54
|
+
name: ThinkTool.name,
|
|
55
|
+
event: "tool-error",
|
|
56
|
+
id: toolCallId,
|
|
57
|
+
data: errorMessage,
|
|
58
|
+
};
|
|
59
|
+
yield errorMessage;
|
|
60
|
+
}
|
|
61
|
+
},
|
|
48
62
|
};
|
|
49
63
|
};
|