@travisennis/acai 0.0.6 → 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 +186 -17
- package/bin/acai-wrapper.js +26 -0
- package/dist/agent/index.d.ts +15 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +202 -174
- package/dist/api/exa/index.js +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -7
- package/dist/commands/add-directory-command.d.ts +1 -1
- package/dist/commands/add-directory-command.d.ts.map +1 -1
- package/dist/commands/add-directory-command.js +1 -32
- 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 +2 -38
- 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 +1 -5
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +0 -9
- package/dist/commands/context-command.d.ts +1 -1
- package/dist/commands/context-command.d.ts.map +1 -1
- package/dist/commands/context-command.js +13 -72
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +0 -19
- 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 +3 -49
- 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 +1 -26
- 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 +2 -18
- 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 +1 -54
- 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 +18 -60
- package/dist/commands/handoff-command.d.ts.map +1 -1
- package/dist/commands/handoff-command.js +0 -11
- 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 +8 -103
- 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 +6 -14
- package/dist/commands/history-command.d.ts +1 -1
- package/dist/commands/history-command.d.ts.map +1 -1
- package/dist/commands/history-command.js +30 -106
- 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 +4 -23
- 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 +1 -28
- package/dist/commands/list-directories-command.d.ts +1 -1
- package/dist/commands/list-directories-command.d.ts.map +1 -1
- package/dist/commands/list-directories-command.js +1 -14
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +55 -78
- package/dist/commands/manager.d.ts +1 -8
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +7 -42
- package/dist/commands/model-command.d.ts +0 -22
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +5 -126
- 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 +1 -79
- package/dist/commands/pickup-command.d.ts.map +1 -1
- package/dist/commands/pickup-command.js +3 -55
- 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 +172 -194
- package/dist/commands/remove-directory-command.d.ts +1 -1
- package/dist/commands/remove-directory-command.d.ts.map +1 -1
- package/dist/commands/remove-directory-command.js +1 -33
- 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 +3 -11
- 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 +1 -63
- 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 +1 -8
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +1 -48
- package/dist/commands/types.d.ts +0 -3
- 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 +5 -16
- package/dist/config.d.ts +17 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +86 -53
- 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 +19 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +54 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +212 -153
- package/dist/messages.d.ts +3 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +67 -3
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +0 -7
- 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/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +0 -4
- package/dist/models/openrouter-provider.d.ts +10 -9
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +82 -88
- 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 +9 -4
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +427 -99
- package/dist/repl/project-status-line.d.ts +1 -0
- package/dist/repl/project-status-line.d.ts.map +1 -1
- package/dist/repl/project-status-line.js +57 -27
- package/dist/repl-new.d.ts +0 -2
- package/dist/repl-new.d.ts.map +1 -1
- package/dist/repl-new.js +34 -54
- 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 -101
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +2 -464
- package/dist/terminal/markdown.js +7 -5
- 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 +6 -21
- package/dist/tokens/threshold.d.ts.map +1 -1
- package/dist/tokens/threshold.js +13 -31
- package/dist/tools/advanced-edit-file.d.ts.map +1 -1
- package/dist/tools/advanced-edit-file.js +5 -1
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +19 -5
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +204 -42
- 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.map +1 -1
- package/dist/tools/code-interpreter.js +25 -9
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +9 -2
- package/dist/tools/directory-tree.d.ts +0 -6
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +29 -18
- package/dist/tools/dynamic-tool-loader.d.ts +0 -4
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +2 -2
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +16 -3
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +24 -13
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +40 -25
- package/dist/tools/index.d.ts +17 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +43 -1
- package/dist/tools/llm-edit-fixer.d.ts +0 -1
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -1
- package/dist/tools/llm-edit-fixer.js +14 -28
- package/dist/tools/move-file.d.ts.map +1 -1
- package/dist/tools/move-file.js +8 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +32 -23
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +102 -45
- package/dist/tools/save-file.d.ts +4 -4
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +20 -2
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +7 -1
- package/dist/tools/types.d.ts +5 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +24 -9
- package/dist/tui/components/assistant-message.js +1 -1
- 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 +60 -5
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +577 -115
- package/dist/tui/components/footer.d.ts +0 -12
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +19 -7
- 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/loader.d.ts +5 -1
- package/dist/tui/components/loader.d.ts.map +1 -1
- package/dist/tui/components/loader.js +2 -2
- package/dist/tui/components/markdown.d.ts +26 -23
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +107 -54
- package/dist/tui/components/modal.d.ts +0 -11
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +0 -29
- 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 +2 -1
- package/dist/tui/components/prompt-status.d.ts.map +1 -1
- package/dist/tui/components/prompt-status.js +7 -2
- package/dist/tui/components/select-list.d.ts +27 -1
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +93 -29
- package/dist/tui/components/spacer.d.ts +1 -1
- package/dist/tui/components/spacer.d.ts.map +1 -1
- package/dist/tui/components/spacer.js +2 -2
- 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/thinking-block.d.ts.map +1 -1
- package/dist/tui/components/thinking-block.js +4 -1
- package/dist/tui/components/tool-execution.d.ts +8 -4
- package/dist/tui/components/tool-execution.d.ts.map +1 -1
- package/dist/tui/components/tool-execution.js +88 -80
- package/dist/tui/components/user-message.d.ts.map +1 -1
- package/dist/tui/components/user-message.js +6 -4
- package/dist/tui/index.d.ts +9 -5
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +5 -1
- package/dist/tui/terminal.d.ts +2 -1
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +28 -38
- package/dist/tui/tui.d.ts +2 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +53 -33
- package/dist/tui/utils.d.ts +5 -0
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +81 -1
- package/dist/{tools/bash-utils.d.ts → utils/bash.d.ts} +3 -3
- package/dist/utils/bash.d.ts.map +1 -0
- package/dist/{tools/bash-utils.js → utils/bash.js} +22 -11
- package/dist/utils/{filesystem.d.ts → filesystem/operations.d.ts} +1 -1
- package/dist/utils/filesystem/operations.d.ts.map +1 -0
- package/dist/{tools/filesystem-utils.d.ts → utils/filesystem/security.d.ts} +3 -2
- package/dist/utils/filesystem/security.d.ts.map +1 -0
- package/dist/{tools/filesystem-utils.js → utils/filesystem/security.js} +62 -4
- 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/{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/{zod-utils.d.ts → zod.d.ts} +1 -1
- package/dist/utils/zod.d.ts.map +1 -0
- package/package.json +17 -17
- package/dist/agent/manual-loop.d.ts +0 -41
- package/dist/agent/manual-loop.d.ts.map +0 -1
- package/dist/agent/manual-loop.js +0 -278
- 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 -58
- 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 -9
- package/dist/repl/prompt.d.ts +0 -21
- package/dist/repl/prompt.d.ts.map +0 -1
- package/dist/repl/prompt.js +0 -244
- package/dist/repl.d.ts +0 -29
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js +0 -218
- 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 -368
- 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 -17
- 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 -280
- 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/tools/bash-utils.d.ts.map +0 -1
- 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/read-file.js
CHANGED
|
@@ -2,8 +2,8 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import { isNumber } from "@travisennis/stdlib/typeguards";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import style from "../terminal/style.js";
|
|
5
|
-
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
6
|
-
import { joinWorkingDir, validatePath } from "
|
|
5
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
6
|
+
import { joinWorkingDir, validatePath } from "../utils/filesystem/security.js";
|
|
7
7
|
import { fileEncodingSchema } from "./types.js";
|
|
8
8
|
export const ReadFileTool = {
|
|
9
9
|
name: "readFile",
|
|
@@ -14,20 +14,17 @@ const inputSchema = z.object({
|
|
|
14
14
|
startLine: z.coerce
|
|
15
15
|
.number()
|
|
16
16
|
.nullable()
|
|
17
|
-
.describe("1-based line number to start reading from. Pass null to start at beginning of file"),
|
|
17
|
+
.describe("1-based line number to start reading from. Required but nullable. Pass null to start at beginning of file"),
|
|
18
18
|
lineCount: z.coerce
|
|
19
19
|
.number()
|
|
20
20
|
.nullable()
|
|
21
|
-
.describe("Maximum number of lines to read. Pass null to get all lines."),
|
|
21
|
+
.describe("Maximum number of lines to read. Required but nullable. Pass null to get all lines."),
|
|
22
22
|
});
|
|
23
23
|
export const createReadFileTool = async ({ workingDir, allowedDirs, tokenCounter, }) => {
|
|
24
24
|
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
25
25
|
return {
|
|
26
26
|
toolDef: {
|
|
27
|
-
description: "Read the complete contents of a file from the file system unless startLine and lineCount are given to read a file selection. "
|
|
28
|
-
"Handles various text encodings and provides detailed error messages " +
|
|
29
|
-
"if the file cannot be read. Use this tool when you need to examine " +
|
|
30
|
-
"the contents of a single file. Only works within allowed directories.",
|
|
27
|
+
description: "Read the complete contents of a file from the file system unless startLine and lineCount are given to read a file selection. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.",
|
|
31
28
|
inputSchema,
|
|
32
29
|
},
|
|
33
30
|
async *execute({ path: providedPath, encoding, startLine, lineCount, }, { toolCallId, abortSignal }) {
|
|
@@ -67,21 +64,33 @@ export const createReadFileTool = async ({ workingDir, allowedDirs, tokenCounter
|
|
|
67
64
|
const endIndex = Math.min(startIndex + count, totalLines);
|
|
68
65
|
file = lines.slice(startIndex, endIndex).join("\n");
|
|
69
66
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
67
|
+
try {
|
|
68
|
+
const result = await manageTokenLimit(file, tokenCounter, "ReadFile", isNumber(startLine) || isNumber(lineCount)
|
|
69
|
+
? "Consider adjusting startLine/lineCount or using grepFiles"
|
|
70
|
+
: "Use startLine and lineCount parameters to read specific portions, or use grepFiles for targeted access", encoding);
|
|
71
|
+
// Calculate line count for the returned content
|
|
72
|
+
const linesRead = result.content.split("\n").length;
|
|
73
|
+
yield {
|
|
74
|
+
name: ReadFileTool.name,
|
|
75
|
+
id: toolCallId,
|
|
76
|
+
event: "tool-completion",
|
|
77
|
+
data: `Read ${linesRead} lines (${result.tokenCount} tokens)`,
|
|
78
|
+
};
|
|
79
|
+
yield result.content;
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
if (error instanceof TokenLimitExceededError) {
|
|
83
|
+
yield {
|
|
84
|
+
name: ReadFileTool.name,
|
|
85
|
+
event: "tool-error",
|
|
86
|
+
id: toolCallId,
|
|
87
|
+
data: error.message,
|
|
88
|
+
};
|
|
89
|
+
yield error.message;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
85
94
|
}
|
|
86
95
|
catch (error) {
|
|
87
96
|
const errorMsg = `${error.message}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"read-multiple-files.d.ts","sourceRoot":"","sources":["../../source/tools/read-multiple-files.ts"],"names":[],"mappings":"AACA,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;
|
|
1
|
+
{"version":3,"file":"read-multiple-files.d.ts","sourceRoot":"","sources":["../../source/tools/read-multiple-files.ts"],"names":[],"mappings":"AACA,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;AAMzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,qBAAqB;;CAEjC,CAAC;AAEF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAEH,KAAK,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEhE,eAAO,MAAM,2BAA2B,GAAU,4CAI/C;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;uBAcgB,4BAA4B,+BACV,eAAe,GAC3C,cAAc,CAAC,UAAU,CAAC;EAsMhC,CAAC"}
|
|
@@ -2,8 +2,8 @@ import { readFile } from "node:fs/promises";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { formatFile } from "../formatting.js";
|
|
4
4
|
import style from "../terminal/style.js";
|
|
5
|
-
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
6
|
-
import { joinWorkingDir, validatePath } from "
|
|
5
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
6
|
+
import { joinWorkingDir, validatePath } from "../utils/filesystem/security.js";
|
|
7
7
|
export const ReadMultipleFilesTool = {
|
|
8
8
|
name: "readMultipleFiles",
|
|
9
9
|
};
|
|
@@ -54,56 +54,113 @@ export const createReadMultipleFilesTool = async ({ workingDir, allowedDirs, tok
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
// Apply token limit check to each file
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
+
};
|
|
66
|
+
}
|
|
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
|
+
}
|
|
65
79
|
}));
|
|
66
80
|
const formattedResults = processedResults.map((r) => r.content);
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
+
}
|
|
76
100
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
totalTokens
|
|
101
|
+
const parts = [];
|
|
102
|
+
if (filesReadCount > 0) {
|
|
103
|
+
parts.push(`Read ${filesReadCount} files successfully (${totalTokens} total tokens)`);
|
|
80
104
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
totalTokens += processedResult.tokenCount;
|
|
105
|
+
if (filesExceededLimitCount > 0) {
|
|
106
|
+
parts.push(`${filesExceededLimitCount} files exceeded token limit`);
|
|
84
107
|
}
|
|
108
|
+
if (filesErrorCount > 0) {
|
|
109
|
+
parts.push(`${filesErrorCount} files could not be read`);
|
|
110
|
+
}
|
|
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;
|
|
85
120
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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;
|
|
98
163
|
}
|
|
99
|
-
const completionMessage = `${parts.join(", ")}.`;
|
|
100
|
-
yield {
|
|
101
|
-
name: ReadMultipleFilesTool.name,
|
|
102
|
-
id: toolCallId,
|
|
103
|
-
event: "tool-completion",
|
|
104
|
-
data: completionMessage,
|
|
105
|
-
};
|
|
106
|
-
yield finalResult.content;
|
|
107
164
|
}
|
|
108
165
|
catch (error) {
|
|
109
166
|
const errorMsg = error.message;
|
|
@@ -7,7 +7,7 @@ export declare const SaveFileTool: {
|
|
|
7
7
|
declare const inputSchema: z.ZodObject<{
|
|
8
8
|
path: z.ZodString;
|
|
9
9
|
content: z.ZodString;
|
|
10
|
-
encoding: z.ZodEnum<{
|
|
10
|
+
encoding: z.ZodDefault<z.ZodEnum<{
|
|
11
11
|
utf8: "utf8";
|
|
12
12
|
ascii: "ascii";
|
|
13
13
|
"utf-8": "utf-8";
|
|
@@ -19,7 +19,7 @@ declare const inputSchema: z.ZodObject<{
|
|
|
19
19
|
latin1: "latin1";
|
|
20
20
|
binary: "binary";
|
|
21
21
|
hex: "hex";
|
|
22
|
-
}
|
|
22
|
+
}>>;
|
|
23
23
|
}, z.core.$strip>;
|
|
24
24
|
type SaveFileInputSchema = z.infer<typeof inputSchema>;
|
|
25
25
|
export declare const createSaveFileTool: ({ workingDir, allowedDirs, }: {
|
|
@@ -31,7 +31,7 @@ export declare const createSaveFileTool: ({ workingDir, allowedDirs, }: {
|
|
|
31
31
|
inputSchema: z.ZodObject<{
|
|
32
32
|
path: z.ZodString;
|
|
33
33
|
content: z.ZodString;
|
|
34
|
-
encoding: z.ZodEnum<{
|
|
34
|
+
encoding: z.ZodDefault<z.ZodEnum<{
|
|
35
35
|
utf8: "utf8";
|
|
36
36
|
ascii: "ascii";
|
|
37
37
|
"utf-8": "utf-8";
|
|
@@ -43,7 +43,7 @@ export declare const createSaveFileTool: ({ workingDir, allowedDirs, }: {
|
|
|
43
43
|
latin1: "latin1";
|
|
44
44
|
binary: "binary";
|
|
45
45
|
hex: "hex";
|
|
46
|
-
}
|
|
46
|
+
}>>;
|
|
47
47
|
}, z.core.$strip>;
|
|
48
48
|
};
|
|
49
49
|
execute({ path: userPath, content, encoding }: SaveFileInputSchema, { toolCallId, abortSignal }: ToolCallOptions): AsyncGenerator<ToolResult>;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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,8 +1,10 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { config } from "../config.js";
|
|
5
|
+
import { clearProjectStatusCache } from "../repl/project-status-line.js";
|
|
4
6
|
import style from "../terminal/style.js";
|
|
5
|
-
import { joinWorkingDir, validatePath } from "
|
|
7
|
+
import { joinWorkingDir, validateFileNotReadOnly, validatePath, } from "../utils/filesystem/security.js";
|
|
6
8
|
import { fileEncodingSchema } from "./types.js";
|
|
7
9
|
export const SaveFileTool = {
|
|
8
10
|
name: "saveFile",
|
|
@@ -10,7 +12,9 @@ export const SaveFileTool = {
|
|
|
10
12
|
const inputSchema = z.object({
|
|
11
13
|
path: z.string().describe("Absolute path to file to save to"),
|
|
12
14
|
content: z.string().describe("Content to save in the file"),
|
|
13
|
-
encoding: fileEncodingSchema
|
|
15
|
+
encoding: fileEncodingSchema
|
|
16
|
+
.describe('Encoding format for saving the file. Use "utf-8" as default for text files')
|
|
17
|
+
.default("utf-8"),
|
|
14
18
|
});
|
|
15
19
|
export const createSaveFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
16
20
|
const allowedDirectory = allowedDirs ?? [workingDir];
|
|
@@ -34,6 +38,18 @@ export const createSaveFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
|
34
38
|
data: `${style.cyan(userPath)}`,
|
|
35
39
|
};
|
|
36
40
|
const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory, { requireExistence: false, abortSignal });
|
|
41
|
+
// Check if file is read-only (only if it exists)
|
|
42
|
+
try {
|
|
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;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
37
53
|
// Check if path exists and is a directory
|
|
38
54
|
try {
|
|
39
55
|
const stat = await fs.stat(filePath);
|
|
@@ -67,6 +83,8 @@ export const createSaveFileTool = async ({ workingDir, allowedDirs, }) => {
|
|
|
67
83
|
id: toolCallId,
|
|
68
84
|
data: `Saved ${lines} lines, ${bytes} bytes`,
|
|
69
85
|
};
|
|
86
|
+
// Clear project status cache since file operations change git status
|
|
87
|
+
clearProjectStatusCache();
|
|
70
88
|
yield `File saved successfully: ${filePath}`;
|
|
71
89
|
}
|
|
72
90
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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
|
@@ -32,7 +32,13 @@ export const createThinkTool = () => {
|
|
|
32
32
|
name: ThinkTool.name,
|
|
33
33
|
event: "tool-init",
|
|
34
34
|
id: toolCallId,
|
|
35
|
-
data:
|
|
35
|
+
data: "Logging thought",
|
|
36
|
+
};
|
|
37
|
+
yield {
|
|
38
|
+
name: ThinkTool.name,
|
|
39
|
+
event: "tool-update",
|
|
40
|
+
id: toolCallId,
|
|
41
|
+
data: `${formattedThought}`,
|
|
36
42
|
};
|
|
37
43
|
yield {
|
|
38
44
|
name: ThinkTool.name,
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -21,6 +21,10 @@ interface ToolInitMessage extends BaseMessage {
|
|
|
21
21
|
event: "tool-init";
|
|
22
22
|
data: string;
|
|
23
23
|
}
|
|
24
|
+
interface ToolUpdateMessage extends BaseMessage {
|
|
25
|
+
event: "tool-update";
|
|
26
|
+
data: string;
|
|
27
|
+
}
|
|
24
28
|
interface ToolErrorMessage extends BaseMessage {
|
|
25
29
|
event: "tool-error";
|
|
26
30
|
data: string;
|
|
@@ -29,7 +33,7 @@ interface ToolCompletionMessage extends BaseMessage {
|
|
|
29
33
|
event: "tool-completion";
|
|
30
34
|
data: string;
|
|
31
35
|
}
|
|
32
|
-
|
|
36
|
+
type Message = ToolInitMessage | ToolUpdateMessage | ToolErrorMessage | ToolCompletionMessage;
|
|
33
37
|
export type ToolResult = Message | string;
|
|
34
38
|
export declare function isToolMessage(value: unknown): value is Message;
|
|
35
39
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAgB,SAAQ,WAAW;IAC3C,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAiB,SAAQ,WAAW;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,qBAAsB,SAAQ,WAAW;IACjD,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../source/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;EAY7B,CAAC;AAEH,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,eAAgB,SAAQ,WAAW;IAC3C,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,iBAAkB,SAAQ,WAAW;IAC7C,KAAK,EAAE,aAAa,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,gBAAiB,SAAQ,WAAW;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,qBAAsB,SAAQ,WAAW;IACjD,KAAK,EAAE,iBAAiB,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,OAAO,GACR,eAAe,GACf,iBAAiB,GACjB,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAc9D"}
|
package/dist/tools/web-fetch.js
CHANGED
|
@@ -22,7 +22,7 @@ export const createWebFetchTool = (options) => {
|
|
|
22
22
|
id: toolCallId,
|
|
23
23
|
data: `${style.cyan(url)}`,
|
|
24
24
|
};
|
|
25
|
-
logger.info(
|
|
25
|
+
logger.info(`${style.cyan(url)}`);
|
|
26
26
|
const result = await readUrl(url, abortSignal);
|
|
27
27
|
const urlContent = result.data;
|
|
28
28
|
const tokenCount = options.tokenCounter.count(urlContent);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAE1C,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,aAAa;;CAEzB,CAAC;AAEF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAEH,eAAO,MAAM,mBAAmB,GAAI,mBAEjC;IACD,YAAY,EAAE,YAAY,CAAC;CAC5B;;;;;;;yBAQc,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,+BACT,eAAe,KAC3C,cAAc,CAAC,UAAU,CAAC;CAwE9B,CAAC"}
|
package/dist/tools/web-search.js
CHANGED
|
@@ -2,7 +2,7 @@ import { SafeSearchType, search } from "duck-duck-scrape";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import Exa from "../api/exa/index.js";
|
|
4
4
|
import style from "../terminal/style.js";
|
|
5
|
-
import { manageTokenLimit } from "../tokens/threshold.js";
|
|
5
|
+
import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
|
|
6
6
|
export const WebSearchTool = {
|
|
7
7
|
name: "webSearch",
|
|
8
8
|
};
|
|
@@ -32,14 +32,29 @@ export const createWebSearchTool = ({ tokenCounter, }) => {
|
|
|
32
32
|
const result = await performSearch(query, abortSignal);
|
|
33
33
|
const sources = result.results.map((source) => `## ${source.title}\nURL: ${source.url}\n\n${source.text}`);
|
|
34
34
|
const resultText = `# Search Results:\n\n${sources.join("\n\n")}`;
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
try {
|
|
36
|
+
const searchResult = await manageTokenLimit(resultText, tokenCounter, "WebSearch", "Use more specific search queries or reduce number of results");
|
|
37
|
+
yield {
|
|
38
|
+
name: WebSearchTool.name,
|
|
39
|
+
event: "tool-completion",
|
|
40
|
+
id: toolCallId,
|
|
41
|
+
data: `Found ${result.results.length} results (${searchResult.tokenCount} tokens)`,
|
|
42
|
+
};
|
|
43
|
+
yield searchResult.content;
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (error instanceof TokenLimitExceededError) {
|
|
47
|
+
yield {
|
|
48
|
+
name: WebSearchTool.name,
|
|
49
|
+
event: "tool-error",
|
|
50
|
+
id: toolCallId,
|
|
51
|
+
data: error.message,
|
|
52
|
+
};
|
|
53
|
+
yield error.message;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
throw error;
|
|
57
|
+
}
|
|
43
58
|
}
|
|
44
59
|
catch (error) {
|
|
45
60
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -24,6 +24,6 @@ export class AssistantMessageComponent extends Container {
|
|
|
24
24
|
const content = message.content;
|
|
25
25
|
// Assistant text messages with no background - trim the text
|
|
26
26
|
// Set paddingY=0 to avoid extra spacing before tool executions
|
|
27
|
-
this.contentContainer.addChild(new Markdown(content.trim(),
|
|
27
|
+
this.contentContainer.addChild(new Markdown(content.trim(), { paddingX: 1, paddingY: 0 }));
|
|
28
28
|
}
|
|
29
29
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Component } from "../tui.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Box component - displays content in a bordered box with header
|
|
4
|
+
*/
|
|
5
|
+
export declare class BoxComponent implements Component {
|
|
6
|
+
private header;
|
|
7
|
+
private content;
|
|
8
|
+
private width;
|
|
9
|
+
private cachedOutput?;
|
|
10
|
+
private cachedHeader?;
|
|
11
|
+
private cachedContent?;
|
|
12
|
+
private cachedWidth?;
|
|
13
|
+
constructor(header: string, content: string, width?: number);
|
|
14
|
+
setHeader(header: string): void;
|
|
15
|
+
setContent(content: string): void;
|
|
16
|
+
setWidth(width: number): void;
|
|
17
|
+
private invalidateCache;
|
|
18
|
+
render(width: number): string[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=box.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../source/tui/components/box.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IAGtB,OAAO,CAAC,YAAY,CAAC,CAAW;IAChC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAM3D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,eAAe;IAOvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAuDhC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { getTerminalSize } from "../../terminal/control.js";
|
|
2
|
+
import { applyMarkdown } from "../../terminal/markdown.js";
|
|
3
|
+
import stripAnsi from "../../terminal/strip-ansi.js";
|
|
4
|
+
import wrapAnsi from "../../terminal/wrap-ansi.js";
|
|
5
|
+
/**
|
|
6
|
+
* Box component - displays content in a bordered box with header
|
|
7
|
+
*/
|
|
8
|
+
export class BoxComponent {
|
|
9
|
+
header;
|
|
10
|
+
content;
|
|
11
|
+
width;
|
|
12
|
+
// Cache for rendered output
|
|
13
|
+
cachedOutput;
|
|
14
|
+
cachedHeader;
|
|
15
|
+
cachedContent;
|
|
16
|
+
cachedWidth;
|
|
17
|
+
constructor(header, content, width) {
|
|
18
|
+
this.header = header;
|
|
19
|
+
this.content = content;
|
|
20
|
+
this.width = width || 0;
|
|
21
|
+
}
|
|
22
|
+
setHeader(header) {
|
|
23
|
+
this.header = header;
|
|
24
|
+
this.invalidateCache();
|
|
25
|
+
}
|
|
26
|
+
setContent(content) {
|
|
27
|
+
this.content = content;
|
|
28
|
+
this.invalidateCache();
|
|
29
|
+
}
|
|
30
|
+
setWidth(width) {
|
|
31
|
+
this.width = width;
|
|
32
|
+
this.invalidateCache();
|
|
33
|
+
}
|
|
34
|
+
invalidateCache() {
|
|
35
|
+
this.cachedOutput = undefined;
|
|
36
|
+
this.cachedHeader = undefined;
|
|
37
|
+
this.cachedContent = undefined;
|
|
38
|
+
this.cachedWidth = undefined;
|
|
39
|
+
}
|
|
40
|
+
render(width) {
|
|
41
|
+
// Use provided width if specified, otherwise use component width or terminal size
|
|
42
|
+
let renderWidth = width || this.width;
|
|
43
|
+
if (renderWidth === 0) {
|
|
44
|
+
const { columns } = getTerminalSize();
|
|
45
|
+
const cols = columns > 0 ? columns : 80;
|
|
46
|
+
renderWidth = Math.max(4, cols - 4);
|
|
47
|
+
}
|
|
48
|
+
// Check cache
|
|
49
|
+
if (this.cachedOutput &&
|
|
50
|
+
this.cachedHeader === this.header &&
|
|
51
|
+
this.cachedContent === this.content &&
|
|
52
|
+
this.cachedWidth === renderWidth) {
|
|
53
|
+
return this.cachedOutput;
|
|
54
|
+
}
|
|
55
|
+
const paddedHeader = ` ${this.header} `;
|
|
56
|
+
const headerVisibleLen = stripAnsi(paddedHeader).length;
|
|
57
|
+
const headerStartPos = 1;
|
|
58
|
+
// Top border with header (use visible header length)
|
|
59
|
+
const leftDashes = headerStartPos;
|
|
60
|
+
const rightDashes = Math.max(0, renderWidth - leftDashes - headerVisibleLen);
|
|
61
|
+
const topBorder = `┌${"─".repeat(leftDashes)}${paddedHeader}${"─".repeat(rightDashes)}┐`;
|
|
62
|
+
// Prepare inner content: format markdown first, then wrap to inner width
|
|
63
|
+
const innerWidth = Math.max(1, renderWidth - 2);
|
|
64
|
+
const formatted = applyMarkdown(this.content);
|
|
65
|
+
const wrapped = wrapAnsi(formatted, innerWidth, { trim: false });
|
|
66
|
+
const contentLines = wrapped.split("\n").map((line) => {
|
|
67
|
+
const visibleLen = stripAnsi(line).length;
|
|
68
|
+
const padCount = Math.max(0, innerWidth - visibleLen);
|
|
69
|
+
return `│ ${line}${" ".repeat(padCount)} │`;
|
|
70
|
+
});
|
|
71
|
+
// Bottom border
|
|
72
|
+
const bottomBorder = `└${"─".repeat(renderWidth)}┘`;
|
|
73
|
+
const result = [topBorder, ...contentLines, bottomBorder];
|
|
74
|
+
// Update cache
|
|
75
|
+
this.cachedOutput = result;
|
|
76
|
+
this.cachedHeader = this.header;
|
|
77
|
+
this.cachedContent = this.content;
|
|
78
|
+
this.cachedWidth = renderWidth;
|
|
79
|
+
return result;
|
|
80
|
+
}
|
|
81
|
+
}
|