@travisennis/acai 0.0.8 → 0.0.10
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 +48 -729
- package/bin/acai +52 -0
- package/dist/agent/index.d.ts +12 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +378 -168
- package/dist/agent/sub-agent.d.ts +23 -0
- package/dist/agent/sub-agent.d.ts.map +1 -0
- package/dist/agent/sub-agent.js +109 -0
- package/dist/cli/index.d.ts +26 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/{cli.js → cli/index.js} +84 -76
- package/dist/cli/stdin.d.ts +9 -0
- package/dist/cli/stdin.d.ts.map +1 -0
- package/dist/cli/stdin.js +37 -0
- package/dist/commands/copy/index.js +2 -2
- package/dist/commands/copy/utils.d.ts.map +1 -1
- package/dist/commands/copy/utils.js +15 -13
- package/dist/commands/generate-rules/index.d.ts +1 -1
- package/dist/commands/generate-rules/index.d.ts.map +1 -1
- package/dist/commands/generate-rules/index.js +16 -100
- package/dist/commands/generate-rules/service.d.ts +21 -0
- package/dist/commands/generate-rules/service.d.ts.map +1 -0
- package/dist/commands/generate-rules/service.js +103 -0
- package/dist/commands/handoff/index.js +2 -2
- package/dist/commands/health/index.js +1 -1
- package/dist/commands/health/utils.d.ts.map +1 -1
- package/dist/commands/health/utils.js +6 -0
- package/dist/commands/history/index.d.ts +1 -1
- package/dist/commands/history/index.d.ts.map +1 -1
- package/dist/commands/history/index.js +17 -18
- package/dist/commands/history/types.d.ts +38 -0
- package/dist/commands/history/types.d.ts.map +1 -1
- package/dist/commands/history/utils.d.ts.map +1 -1
- package/dist/commands/history/utils.js +63 -58
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +3 -8
- package/dist/commands/init-project/index.d.ts.map +1 -1
- package/dist/commands/init-project/index.js +3 -3
- package/dist/commands/init-project/utils.d.ts.map +1 -1
- package/dist/commands/init-project/utils.js +10 -2
- package/dist/commands/list-tools/index.d.ts.map +1 -1
- package/dist/commands/list-tools/index.js +7 -31
- package/dist/commands/manager.d.ts +2 -2
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +57 -33
- package/dist/commands/model/index.d.ts.map +1 -1
- package/dist/commands/model/index.js +20 -151
- package/dist/commands/model/model-panel.d.ts +4 -0
- package/dist/commands/model/model-panel.d.ts.map +1 -0
- package/dist/commands/model/model-panel.js +144 -0
- package/dist/commands/paste/index.d.ts.map +1 -1
- package/dist/commands/paste/index.js +59 -62
- package/dist/commands/paste/utils.d.ts.map +1 -1
- package/dist/commands/paste/utils.js +88 -58
- package/dist/commands/pickup/index.d.ts.map +1 -1
- package/dist/commands/pickup/index.js +6 -3
- package/dist/commands/pickup/utils.js +3 -3
- package/dist/commands/resources/index.d.ts.map +1 -1
- package/dist/commands/resources/index.js +33 -50
- package/dist/commands/review/index.d.ts.map +1 -1
- package/dist/commands/review/index.js +3 -117
- package/dist/commands/review/review-panel.d.ts +3 -0
- package/dist/commands/review/review-panel.d.ts.map +1 -0
- package/dist/commands/review/review-panel.js +186 -0
- package/dist/commands/review/utils.d.ts +9 -0
- package/dist/commands/review/utils.d.ts.map +1 -1
- package/dist/commands/review/utils.js +127 -68
- package/dist/commands/session/index.d.ts +1 -1
- package/dist/commands/session/index.d.ts.map +1 -1
- package/dist/commands/session/index.js +134 -112
- package/dist/commands/session/types.d.ts +7 -0
- package/dist/commands/session/types.d.ts.map +1 -1
- package/dist/commands/share/html-renderer.d.ts +25 -0
- package/dist/commands/share/html-renderer.d.ts.map +1 -0
- package/dist/commands/share/html-renderer.js +384 -0
- package/dist/commands/share/index.d.ts +3 -0
- package/dist/commands/share/index.d.ts.map +1 -0
- package/dist/commands/share/index.js +122 -0
- package/dist/commands/shell/index.d.ts.map +1 -1
- package/dist/commands/shell/index.js +16 -1
- package/dist/commands/types.d.ts +2 -2
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/{config.d.ts → config/index.d.ts} +20 -9
- package/dist/config/index.d.ts.map +1 -0
- package/dist/{config.js → config/index.js} +43 -42
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +75 -55
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +170 -127
- package/dist/middleware/cache.d.ts.map +1 -1
- package/dist/middleware/cache.js +18 -36
- package/dist/models/ai-config.d.ts +1 -0
- package/dist/models/ai-config.d.ts.map +1 -1
- package/dist/models/ai-config.js +4 -3
- package/dist/models/anthropic-provider.d.ts +2 -5
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +3 -70
- package/dist/models/deepseek-provider.d.ts +1 -0
- package/dist/models/deepseek-provider.d.ts.map +1 -1
- package/dist/models/google-provider.d.ts +2 -3
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +0 -26
- package/dist/models/groq-provider.d.ts +1 -0
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/manager.d.ts +13 -2
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +20 -8
- package/dist/models/openai-provider.d.ts +5 -5
- package/dist/models/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +27 -40
- package/dist/models/opencode-zen-provider.d.ts +8 -3
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +68 -11
- package/dist/models/openrouter-provider.d.ts +24 -30
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +92 -177
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/xai-provider.d.ts +4 -3
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +18 -18
- package/dist/modes/manager.d.ts +23 -0
- package/dist/modes/manager.d.ts.map +1 -0
- package/dist/modes/manager.js +77 -0
- package/dist/modes/prompts.d.ts +2 -0
- package/dist/modes/prompts.d.ts.map +1 -0
- package/dist/modes/prompts.js +143 -0
- package/dist/prompts/mentions.d.ts +11 -0
- package/dist/prompts/mentions.d.ts.map +1 -0
- package/dist/{mentions.js → prompts/mentions.js} +21 -80
- package/dist/prompts/system-prompt.d.ts +26 -0
- package/dist/prompts/system-prompt.d.ts.map +1 -0
- package/dist/{prompts.js → prompts/system-prompt.js} +50 -22
- package/dist/repl/index.d.ts +174 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/{repl-new.js → repl/index.js} +399 -76
- package/dist/repl/project-status.d.ts +1 -0
- package/dist/repl/project-status.d.ts.map +1 -1
- package/dist/repl/project-status.js +4 -1
- package/dist/sessions/manager.d.ts +93 -1
- package/dist/sessions/manager.d.ts.map +1 -1
- package/dist/sessions/manager.js +264 -9
- package/dist/sessions/summary.d.ts +4 -0
- package/dist/sessions/summary.d.ts.map +1 -0
- package/dist/sessions/summary.js +30 -0
- package/dist/{skills.d.ts → skills/index.d.ts} +14 -2
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +294 -0
- package/dist/subagents/index.d.ts +15 -0
- package/dist/subagents/index.d.ts.map +1 -0
- package/dist/subagents/index.js +231 -0
- package/dist/terminal/control.d.ts +1 -1
- package/dist/terminal/control.d.ts.map +1 -1
- package/dist/terminal/control.js +30 -9
- package/dist/terminal/east-asian-width.d.ts.map +1 -1
- package/dist/terminal/east-asian-width.js +404 -351
- package/dist/terminal/keys.d.ts +17 -0
- package/dist/terminal/keys.d.ts.map +1 -1
- package/dist/terminal/keys.js +37 -0
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +24 -12
- package/dist/terminal/string-width.d.ts.map +1 -1
- package/dist/terminal/string-width.js +25 -27
- package/dist/terminal/style.d.ts.map +1 -1
- package/dist/terminal/style.js +4 -7
- package/dist/terminal/supports-color.d.ts.map +1 -1
- package/dist/terminal/supports-color.js +41 -27
- package/dist/terminal/table/cell.d.ts +12 -0
- package/dist/terminal/table/cell.d.ts.map +1 -1
- package/dist/terminal/table/cell.js +40 -25
- package/dist/terminal/table/layout-manager.d.ts.map +1 -1
- package/dist/terminal/table/layout-manager.js +100 -68
- package/dist/terminal/table/utils.d.ts.map +1 -1
- package/dist/terminal/table/utils.js +17 -10
- package/dist/terminal/wrap-ansi.d.ts.map +1 -1
- package/dist/terminal/wrap-ansi.js +172 -103
- package/dist/tokens/tracker.d.ts +1 -0
- package/dist/tokens/tracker.d.ts.map +1 -1
- package/dist/tokens/tracker.js +3 -0
- package/dist/tools/agent.d.ts +27 -0
- package/dist/tools/agent.d.ts.map +1 -0
- package/dist/tools/agent.js +81 -0
- package/dist/tools/bash.d.ts +4 -3
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +343 -121
- package/dist/tools/code-search.d.ts +41 -0
- package/dist/tools/code-search.d.ts.map +1 -0
- package/dist/tools/code-search.js +195 -0
- package/dist/tools/directory-tree.d.ts +3 -3
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +8 -5
- package/dist/tools/dynamic-tool-loader.d.ts +2 -5
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +20 -4
- package/dist/tools/edit-file.d.ts +7 -7
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +164 -66
- package/dist/tools/glob.d.ts +6 -6
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +95 -55
- package/dist/tools/grep.d.ts +15 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +300 -192
- package/dist/tools/index.d.ts +143 -5
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +39 -24
- package/dist/tools/ls.d.ts +2 -2
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +7 -5
- package/dist/tools/read-file.d.ts +3 -3
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +74 -34
- package/dist/tools/save-file.d.ts +3 -3
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +11 -11
- package/dist/tools/skill.d.ts +23 -0
- package/dist/tools/skill.d.ts.map +1 -0
- package/dist/tools/skill.js +65 -0
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +2 -9
- package/dist/tools/utils.d.ts +2 -0
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +12 -0
- package/dist/tools/web-fetch.d.ts +62 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +429 -0
- package/dist/tools/web-search.d.ts +62 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +226 -0
- package/dist/tui/autocomplete/attachment-provider.d.ts +3 -6
- package/dist/tui/autocomplete/attachment-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/attachment-provider.js +25 -78
- package/dist/tui/autocomplete/base-provider.d.ts +1 -0
- package/dist/tui/autocomplete/base-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/combined-provider.d.ts +1 -4
- package/dist/tui/autocomplete/combined-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/combined-provider.js +3 -17
- package/dist/tui/autocomplete/command-provider.d.ts +1 -0
- package/dist/tui/autocomplete/command-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/command-provider.js +3 -0
- package/dist/tui/autocomplete/file-search-provider.d.ts +2 -1
- package/dist/tui/autocomplete/file-search-provider.d.ts.map +1 -1
- package/dist/tui/autocomplete/file-search-provider.js +36 -16
- package/dist/tui/autocomplete/skill-provider.d.ts +17 -0
- package/dist/tui/autocomplete/skill-provider.d.ts.map +1 -0
- package/dist/tui/autocomplete/skill-provider.js +49 -0
- package/dist/tui/autocomplete.d.ts +2 -2
- package/dist/tui/autocomplete.d.ts.map +1 -1
- package/dist/tui/autocomplete.js +3 -5
- package/dist/tui/components/assistant-message.d.ts.map +1 -1
- package/dist/tui/components/assistant-message.js +0 -4
- package/dist/tui/components/editor.d.ts +21 -2
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +228 -236
- package/dist/tui/components/footer.d.ts +6 -4
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +49 -25
- package/dist/tui/components/markdown.d.ts +8 -5
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +57 -39
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +35 -33
- package/dist/tui/components/notification.d.ts +13 -2
- package/dist/tui/components/notification.d.ts.map +1 -1
- package/dist/tui/components/notification.js +37 -2
- package/dist/tui/components/progress-bar.js +1 -1
- package/dist/tui/components/select-list.d.ts +1 -0
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +14 -11
- package/dist/tui/components/text.d.ts +16 -0
- package/dist/tui/components/text.d.ts.map +1 -1
- package/dist/tui/components/text.js +72 -57
- package/dist/tui/components/thinking-block.d.ts +9 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -1
- package/dist/tui/components/thinking-block.js +43 -11
- package/dist/tui/components/tool-execution.d.ts +5 -1
- package/dist/tui/components/tool-execution.d.ts.map +1 -1
- package/dist/tui/components/tool-execution.js +19 -10
- package/dist/tui/components/user-message.d.ts.map +1 -1
- package/dist/tui/components/user-message.js +0 -3
- package/dist/tui/components/welcome.js +2 -2
- package/dist/tui/editor-launcher.d.ts +13 -0
- package/dist/tui/editor-launcher.d.ts.map +1 -0
- package/dist/tui/editor-launcher.js +39 -0
- package/dist/tui/index.d.ts +3 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +1 -0
- package/dist/tui/terminal.d.ts +27 -0
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +144 -15
- package/dist/tui/tui.d.ts +43 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +172 -41
- package/dist/utils/bash/parse.d.ts +19 -0
- package/dist/utils/bash/parse.d.ts.map +1 -0
- package/dist/utils/bash/parse.js +223 -0
- package/dist/utils/bash/quote.d.ts +6 -0
- package/dist/utils/bash/quote.d.ts.map +1 -0
- package/dist/utils/bash/quote.js +23 -0
- package/dist/utils/bash.d.ts.map +1 -1
- package/dist/utils/bash.js +211 -126
- package/dist/utils/command-protection.d.ts +28 -0
- package/dist/utils/command-protection.d.ts.map +1 -0
- package/dist/utils/command-protection.js +324 -0
- package/dist/utils/dedent.d.ts.map +1 -0
- package/dist/utils/env-expand.d.ts +2 -0
- package/dist/utils/env-expand.d.ts.map +1 -0
- package/dist/utils/env-expand.js +8 -0
- package/dist/utils/filesystem/path-display.d.ts +11 -0
- package/dist/utils/filesystem/path-display.d.ts.map +1 -0
- package/dist/utils/filesystem/path-display.js +32 -0
- package/dist/utils/filesystem/security.d.ts +2 -2
- package/dist/utils/filesystem/security.d.ts.map +1 -1
- package/dist/utils/filesystem/security.js +32 -31
- package/dist/utils/formatting.d.ts.map +1 -0
- package/dist/{formatting.js → utils/formatting.js} +1 -1
- package/dist/utils/git.d.ts +4 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +30 -0
- package/dist/utils/glob.d.ts +1 -1
- package/dist/utils/glob.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/{logger.js → utils/logger.js} +1 -1
- package/dist/utils/parsing.d.ts.map +1 -0
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +90 -37
- package/dist/utils/templates.d.ts +2 -0
- package/dist/utils/templates.d.ts.map +1 -0
- package/dist/utils/templates.js +24 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/{version.js → utils/version.js} +1 -1
- package/package.json +34 -25
- package/dist/cli.d.ts +0 -23
- package/dist/cli.d.ts.map +0 -1
- package/dist/commands/exit/index.d.ts +0 -10
- package/dist/commands/exit/index.d.ts.map +0 -1
- package/dist/commands/exit/index.js +0 -21
- package/dist/commands/exit/types.d.ts +0 -8
- package/dist/commands/exit/types.d.ts.map +0 -1
- package/dist/commands/exit/types.js +0 -1
- package/dist/commands/exit/utils.d.ts +0 -2
- package/dist/commands/exit/utils.d.ts.map +0 -1
- package/dist/commands/exit/utils.js +0 -13
- package/dist/commands/prompt/index.d.ts +0 -5
- package/dist/commands/prompt/index.d.ts.map +0 -1
- package/dist/commands/prompt/index.js +0 -126
- package/dist/commands/prompt/types.d.ts +0 -15
- package/dist/commands/prompt/types.d.ts.map +0 -1
- package/dist/commands/prompt/types.js +0 -1
- package/dist/commands/prompt/utils.d.ts +0 -12
- package/dist/commands/prompt/utils.d.ts.map +0 -1
- package/dist/commands/prompt/utils.js +0 -107
- package/dist/commands/reset/index.d.ts +0 -3
- package/dist/commands/reset/index.d.ts.map +0 -1
- package/dist/commands/reset/index.js +0 -25
- package/dist/commands/reset/types.d.ts +0 -1
- package/dist/commands/reset/types.d.ts.map +0 -1
- package/dist/commands/reset/types.js +0 -3
- package/dist/commands/save/index.d.ts +0 -3
- package/dist/commands/save/index.d.ts.map +0 -1
- package/dist/commands/save/index.js +0 -19
- package/dist/config.d.ts.map +0 -1
- package/dist/dedent.d.ts.map +0 -1
- package/dist/formatting.d.ts.map +0 -1
- package/dist/logger.d.ts.map +0 -1
- package/dist/mentions.d.ts +0 -14
- package/dist/mentions.d.ts.map +0 -1
- package/dist/parsing.d.ts.map +0 -1
- package/dist/prompts.d.ts +0 -10
- package/dist/prompts.d.ts.map +0 -1
- package/dist/repl-new.d.ts +0 -62
- package/dist/repl-new.d.ts.map +0 -1
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js +0 -233
- package/dist/tui/autocomplete/path-provider.d.ts +0 -21
- package/dist/tui/autocomplete/path-provider.d.ts.map +0 -1
- package/dist/tui/autocomplete/path-provider.js +0 -164
- package/dist/version.d.ts.map +0 -1
- /package/dist/{dedent.d.ts → utils/dedent.d.ts} +0 -0
- /package/dist/{dedent.js → utils/dedent.js} +0 -0
- /package/dist/{formatting.d.ts → utils/formatting.d.ts} +0 -0
- /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
- /package/dist/{parsing.d.ts → utils/parsing.d.ts} +0 -0
- /package/dist/{parsing.js → utils/parsing.js} +0 -0
- /package/dist/{version.d.ts → utils/version.d.ts} +0 -0
package/dist/agent/index.js
CHANGED
|
@@ -1,41 +1,44 @@
|
|
|
1
|
-
import { generateText, InvalidToolInputError, NoOutputGeneratedError, NoSuchToolError, Output, streamText,
|
|
2
|
-
import { config } from "../config.js";
|
|
3
|
-
import { logger } from "../logger.js";
|
|
1
|
+
import { generateText, InvalidToolInputError, NoOutputGeneratedError, NoSuchToolError, Output, streamText, } from "ai";
|
|
4
2
|
import { AiConfig } from "../models/ai-config.js";
|
|
3
|
+
import { toAiSdkTools } from "../tools/utils.js";
|
|
4
|
+
import { logger } from "../utils/logger.js";
|
|
5
5
|
export class Agent {
|
|
6
6
|
opts;
|
|
7
|
+
config;
|
|
7
8
|
_state;
|
|
8
9
|
abortController;
|
|
9
10
|
constructor(opts) {
|
|
10
11
|
this.opts = opts;
|
|
12
|
+
this.config = opts.config;
|
|
11
13
|
this.abortController = new AbortController();
|
|
12
14
|
this._state = this.resetState();
|
|
13
15
|
}
|
|
16
|
+
setConfig(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
14
19
|
get state() {
|
|
15
20
|
return this._state;
|
|
16
21
|
}
|
|
17
22
|
get abortSignal() {
|
|
18
23
|
return this.abortController.signal;
|
|
19
24
|
}
|
|
25
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: will be refactored in a future task
|
|
20
26
|
async *run(args) {
|
|
21
|
-
|
|
27
|
+
yield {
|
|
28
|
+
type: "agent-start",
|
|
29
|
+
};
|
|
30
|
+
const { systemPrompt, input, tools, activeTools, abortSignal } = args;
|
|
22
31
|
this.resetState();
|
|
23
32
|
this._state.timestamps.start = performance.now();
|
|
24
|
-
const {
|
|
33
|
+
const { modelManager, sessionManager, tokenTracker } = this.opts;
|
|
34
|
+
const maxIterations = args.maxIterations ?? this.config.loop.maxIterations ?? 200;
|
|
35
|
+
const maxRetries = args.maxRetries ?? 2;
|
|
25
36
|
const langModel = modelManager.getModel("repl");
|
|
26
37
|
const modelConfig = modelManager.getModelMetadata("repl");
|
|
27
38
|
const aiConfig = new AiConfig({
|
|
28
39
|
modelMetadata: modelConfig,
|
|
29
40
|
prompt: input,
|
|
30
41
|
});
|
|
31
|
-
yield {
|
|
32
|
-
type: "agent-start",
|
|
33
|
-
};
|
|
34
|
-
yield {
|
|
35
|
-
type: "message",
|
|
36
|
-
role: "user",
|
|
37
|
-
content: input,
|
|
38
|
-
};
|
|
39
42
|
let iter = 0;
|
|
40
43
|
let consecutiveErrors = 0;
|
|
41
44
|
let hasEmittedTerminalEvent = false;
|
|
@@ -57,18 +60,18 @@ export class Agent {
|
|
|
57
60
|
if (abortSignal?.aborted) {
|
|
58
61
|
throw new Error("Agent aborted before streamText");
|
|
59
62
|
}
|
|
63
|
+
const messages = sessionManager.get();
|
|
64
|
+
const aiSdkTools = toAiSdkTools(tools, false);
|
|
60
65
|
const result = streamText({
|
|
61
66
|
model: langModel,
|
|
62
67
|
maxOutputTokens: aiConfig.maxOutputTokens(),
|
|
63
68
|
system: systemPrompt,
|
|
64
|
-
messages
|
|
69
|
+
messages,
|
|
65
70
|
temperature: aiConfig.temperature(),
|
|
66
71
|
topP: aiConfig.topP(),
|
|
67
72
|
maxRetries: 2,
|
|
68
73
|
providerOptions: aiConfig.providerOptions(),
|
|
69
|
-
tools:
|
|
70
|
-
// biome-ignore lint/suspicious/noExplicitAny: temporary
|
|
71
|
-
Object.entries(tools).map((t) => [t[0], tool(t[1].toolDef)])),
|
|
74
|
+
tools: aiSdkTools,
|
|
72
75
|
activeTools,
|
|
73
76
|
// biome-ignore lint/style/useNamingConvention: third-party controlled
|
|
74
77
|
experimental_repairToolCall: toolCallRepair(modelManager),
|
|
@@ -98,164 +101,58 @@ export class Agent {
|
|
|
98
101
|
toolCalls: thisStepToolCalls,
|
|
99
102
|
toolResults: thisStepToolResults,
|
|
100
103
|
});
|
|
101
|
-
const
|
|
104
|
+
const pendingToolCalls = [];
|
|
102
105
|
for await (const chunk of result.fullStream) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
else if (chunk.type === "reasoning-end") {
|
|
117
|
-
yield {
|
|
118
|
-
type: "thinking-end",
|
|
119
|
-
content: accumulatedReasoning,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
else if (chunk.type === "text-start") {
|
|
123
|
-
yield {
|
|
124
|
-
type: "message-start",
|
|
125
|
-
role: "assistant",
|
|
126
|
-
content: "",
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
else if (chunk.type === "text-delta") {
|
|
130
|
-
accumulatedText += chunk.text;
|
|
131
|
-
yield {
|
|
132
|
-
type: "message",
|
|
133
|
-
role: "assistant",
|
|
134
|
-
content: accumulatedText,
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
else if (chunk.type === "text-end") {
|
|
138
|
-
yield {
|
|
139
|
-
type: "message-end",
|
|
140
|
-
role: "assistant",
|
|
141
|
-
content: accumulatedText,
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
else if (chunk.type === "tool-call") {
|
|
145
|
-
const call = chunk;
|
|
146
|
-
const toolName = call.toolName;
|
|
147
|
-
const iTool = tools[toolName];
|
|
148
|
-
yield this.processToolEvent(toolsCalled, {
|
|
149
|
-
type: "tool-call-start",
|
|
150
|
-
name: toolName,
|
|
151
|
-
toolCallId: call.toolCallId,
|
|
152
|
-
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
153
|
-
msg: iTool ? iTool.display(call.input) : "",
|
|
154
|
-
args: call.input,
|
|
155
|
-
});
|
|
156
|
-
if (call.invalid) {
|
|
157
|
-
yield this.processToolEvent(toolsCalled, {
|
|
158
|
-
type: "tool-call-error",
|
|
159
|
-
name: call.toolName,
|
|
160
|
-
toolCallId: call.toolCallId,
|
|
161
|
-
msg: String(call.error),
|
|
162
|
-
args: call.input,
|
|
163
|
-
});
|
|
164
|
-
continue;
|
|
165
|
-
}
|
|
166
|
-
let resultOutput = "Unknown result.";
|
|
167
|
-
try {
|
|
168
|
-
thisStepToolCalls.push({ toolName });
|
|
169
|
-
thisStepToolResults.push({ toolName });
|
|
170
|
-
const iTool = tools[toolName];
|
|
171
|
-
if (!iTool) {
|
|
172
|
-
resultOutput = `No executor for tool ${toolName}`;
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
const toolExec = iTool.execute;
|
|
176
|
-
try {
|
|
177
|
-
const output = await toolExec(call.input, {
|
|
178
|
-
toolCallId: call.toolCallId,
|
|
179
|
-
messages: sessionManager.get(),
|
|
180
|
-
abortSignal,
|
|
181
|
-
});
|
|
182
|
-
resultOutput = formatToolResult(output);
|
|
183
|
-
yield this.processToolEvent(toolsCalled, {
|
|
184
|
-
type: "tool-call-end",
|
|
185
|
-
name: call.toolName,
|
|
186
|
-
toolCallId: call.toolCallId,
|
|
187
|
-
msg: resultOutput,
|
|
188
|
-
args: call.input,
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
catch (err) {
|
|
192
|
-
resultOutput = `Tool error: ${err instanceof Error ? err.message : String(err)}`;
|
|
193
|
-
yield this.processToolEvent(toolsCalled, {
|
|
194
|
-
type: "tool-call-error",
|
|
195
|
-
name: toolName,
|
|
196
|
-
toolCallId: call.toolCallId,
|
|
197
|
-
msg: resultOutput,
|
|
198
|
-
args: null,
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
resultOutput = `Tool error: ${error instanceof Error ? error.message : String(error)}`;
|
|
205
|
-
yield this.processToolEvent(toolsCalled, {
|
|
206
|
-
type: "tool-call-error",
|
|
207
|
-
name: toolName,
|
|
208
|
-
toolCallId: call.toolCallId,
|
|
209
|
-
msg: resultOutput,
|
|
210
|
-
args: null,
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
toolMessages.push({
|
|
214
|
-
role: "tool",
|
|
215
|
-
content: [
|
|
216
|
-
{
|
|
217
|
-
type: "tool-result",
|
|
218
|
-
toolName,
|
|
219
|
-
toolCallId: call.toolCallId,
|
|
220
|
-
output: {
|
|
221
|
-
type: "text",
|
|
222
|
-
value: resultOutput,
|
|
223
|
-
},
|
|
224
|
-
},
|
|
225
|
-
],
|
|
226
|
-
});
|
|
106
|
+
const event = this.handleStreamChunk(chunk, {
|
|
107
|
+
accumulatedText,
|
|
108
|
+
accumulatedReasoning,
|
|
109
|
+
toolsCalled,
|
|
110
|
+
tools,
|
|
111
|
+
pendingToolCalls,
|
|
112
|
+
});
|
|
113
|
+
if (event) {
|
|
114
|
+
accumulatedText = event.accumulatedText;
|
|
115
|
+
accumulatedReasoning = event.accumulatedReasoning;
|
|
116
|
+
yield event.agentEvent;
|
|
227
117
|
}
|
|
228
118
|
}
|
|
119
|
+
// ============================================================
|
|
120
|
+
// PARALLEL TOOL EXECUTION
|
|
121
|
+
// ============================================================
|
|
122
|
+
const { collectedEvents, parallelToolMessages } = await this.executeToolsInParallel({
|
|
123
|
+
pendingToolCalls,
|
|
124
|
+
abortSignal,
|
|
125
|
+
toolsCalled,
|
|
126
|
+
stepToolCalls: thisStepToolCalls,
|
|
127
|
+
stepToolResults: thisStepToolResults,
|
|
128
|
+
});
|
|
129
|
+
// Yield all collected events in order
|
|
130
|
+
for (const event of collectedEvents) {
|
|
131
|
+
yield event;
|
|
132
|
+
}
|
|
229
133
|
// Get response and tool calls
|
|
230
134
|
const response = await result.response;
|
|
231
135
|
const responseMessages = response.messages;
|
|
232
|
-
|
|
136
|
+
// Filter out tool-result messages from responseMessages since we manually
|
|
137
|
+
// execute tools and add their results via appendToolMessages below.
|
|
138
|
+
// The AI SDK may include tool-result messages in response.messages even
|
|
139
|
+
// when tools don't have an execute function.
|
|
140
|
+
const nonToolMessages = responseMessages.filter((msg) => msg.role !== "tool");
|
|
141
|
+
sessionManager.appendResponseMessages(nonToolMessages);
|
|
233
142
|
const stepUsage = await result.usage;
|
|
234
|
-
this.
|
|
235
|
-
this._state.usage.outputTokens = stepUsage.outputTokens ?? 0;
|
|
236
|
-
this._state.usage.totalTokens = stepUsage.totalTokens ?? 0;
|
|
237
|
-
this._state.usage.cachedInputTokens =
|
|
238
|
-
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
239
|
-
this._state.usage.reasoningTokens =
|
|
240
|
-
stepUsage.outputTokenDetails.reasoningTokens ?? 0;
|
|
241
|
-
sessionManager.setContextWindow(stepUsage.totalTokens ?? 0);
|
|
242
|
-
this._state.totalUsage.inputTokens += stepUsage.inputTokens ?? 0;
|
|
243
|
-
this._state.totalUsage.outputTokens += stepUsage.outputTokens ?? 0;
|
|
244
|
-
this._state.totalUsage.totalTokens += stepUsage.totalTokens ?? 0;
|
|
245
|
-
this._state.totalUsage.cachedInputTokens +=
|
|
246
|
-
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
247
|
-
this._state.totalUsage.reasoningTokens +=
|
|
248
|
-
stepUsage.outputTokenDetails.reasoningTokens ?? 0;
|
|
143
|
+
this.updateUsageStats(stepUsage, sessionManager);
|
|
249
144
|
// If finishReason is not tool-calls, break
|
|
250
145
|
const finishReason = await result.finishReason;
|
|
251
146
|
if (finishReason !== "tool-calls") {
|
|
147
|
+
// Track aggregate usage before yielding agent-stop so footer can display it
|
|
148
|
+
tokenTracker.trackUsage("repl", this._state.totalUsage);
|
|
252
149
|
yield {
|
|
253
150
|
type: "agent-stop",
|
|
254
151
|
};
|
|
255
152
|
hasEmittedTerminalEvent = true;
|
|
256
153
|
break;
|
|
257
154
|
}
|
|
258
|
-
sessionManager.appendToolMessages(
|
|
155
|
+
sessionManager.appendToolMessages(parallelToolMessages);
|
|
259
156
|
// Consume the rest of the team if necessary
|
|
260
157
|
// await result.consumeStream();
|
|
261
158
|
yield {
|
|
@@ -276,8 +173,30 @@ export class Agent {
|
|
|
276
173
|
// Continue loop to allow user to provide corrected input
|
|
277
174
|
}
|
|
278
175
|
else {
|
|
279
|
-
|
|
280
|
-
|
|
176
|
+
// Extract additional error context for better debugging
|
|
177
|
+
const err = error;
|
|
178
|
+
const errorContext = {
|
|
179
|
+
modelId: modelConfig?.id ?? langModel.modelId ?? "unknown",
|
|
180
|
+
sessionId: sessionManager.getSessionId(),
|
|
181
|
+
messageCount: sessionManager.get().length,
|
|
182
|
+
attempt: consecutiveErrors,
|
|
183
|
+
maxRetries,
|
|
184
|
+
};
|
|
185
|
+
// Add response info if available (common for Bad Request errors from AI SDK)
|
|
186
|
+
if (err.cause) {
|
|
187
|
+
const cause = err.cause;
|
|
188
|
+
if (cause.response) {
|
|
189
|
+
errorContext["responseStatus"] = cause.response.status;
|
|
190
|
+
errorContext["responseStatusText"] = cause.response.statusText;
|
|
191
|
+
// Add body snippet if available (truncated to avoid log bloat)
|
|
192
|
+
if (cause.response.body &&
|
|
193
|
+
typeof cause.response.body === "object") {
|
|
194
|
+
const body = cause.response.body;
|
|
195
|
+
errorContext["responseBody"] = JSON.stringify(body).slice(0, 500);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
logger.error({ ...errorContext, error: err }, `Error on manual agent loop streamText (attempt ${consecutiveErrors}/${maxRetries + 1})`);
|
|
281
200
|
const errorMsg = error.message.length > 100
|
|
282
201
|
? `${error.message.slice(0, 100)}...`
|
|
283
202
|
: error.message;
|
|
@@ -306,12 +225,12 @@ export class Agent {
|
|
|
306
225
|
}
|
|
307
226
|
// Emit agent-stop if loop ended without emitting a terminal event (maxIterations reached)
|
|
308
227
|
if (!hasEmittedTerminalEvent) {
|
|
228
|
+
// Track aggregate usage before yielding agent-stop so footer can display it
|
|
229
|
+
tokenTracker.trackUsage("repl", this._state.totalUsage);
|
|
309
230
|
yield {
|
|
310
231
|
type: "agent-stop",
|
|
311
232
|
};
|
|
312
233
|
}
|
|
313
|
-
// Track aggregate usage across all steps when available
|
|
314
|
-
tokenTracker.trackUsage("repl", this._state.totalUsage);
|
|
315
234
|
}
|
|
316
235
|
abort() {
|
|
317
236
|
this.abortController.abort();
|
|
@@ -365,6 +284,122 @@ export class Agent {
|
|
|
365
284
|
};
|
|
366
285
|
return this._state;
|
|
367
286
|
}
|
|
287
|
+
handleStreamChunk(
|
|
288
|
+
// biome-ignore lint/suspicious/noExplicitAny: chunk type from AI SDK fullStream is a complex discriminated union
|
|
289
|
+
chunk, ctx) {
|
|
290
|
+
if (chunk.type === "reasoning-start") {
|
|
291
|
+
return {
|
|
292
|
+
agentEvent: { type: "thinking-start", content: "" },
|
|
293
|
+
accumulatedText: ctx.accumulatedText,
|
|
294
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
if (chunk.type === "reasoning-delta") {
|
|
298
|
+
const accumulatedReasoning = ctx.accumulatedReasoning + chunk.text;
|
|
299
|
+
return {
|
|
300
|
+
agentEvent: { type: "thinking", content: accumulatedReasoning },
|
|
301
|
+
accumulatedText: ctx.accumulatedText,
|
|
302
|
+
accumulatedReasoning,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
if (chunk.type === "reasoning-end") {
|
|
306
|
+
return {
|
|
307
|
+
agentEvent: {
|
|
308
|
+
type: "thinking-end",
|
|
309
|
+
content: ctx.accumulatedReasoning,
|
|
310
|
+
},
|
|
311
|
+
accumulatedText: ctx.accumulatedText,
|
|
312
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
if (chunk.type === "text-start") {
|
|
316
|
+
return {
|
|
317
|
+
agentEvent: { type: "message-start", role: "assistant", content: "" },
|
|
318
|
+
accumulatedText: ctx.accumulatedText,
|
|
319
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
if (chunk.type === "text-delta") {
|
|
323
|
+
const accumulatedText = ctx.accumulatedText + chunk.text;
|
|
324
|
+
return {
|
|
325
|
+
agentEvent: {
|
|
326
|
+
type: "message",
|
|
327
|
+
role: "assistant",
|
|
328
|
+
content: accumulatedText,
|
|
329
|
+
},
|
|
330
|
+
accumulatedText,
|
|
331
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (chunk.type === "text-end") {
|
|
335
|
+
return {
|
|
336
|
+
agentEvent: {
|
|
337
|
+
type: "message-end",
|
|
338
|
+
role: "assistant",
|
|
339
|
+
content: ctx.accumulatedText,
|
|
340
|
+
},
|
|
341
|
+
accumulatedText: ctx.accumulatedText,
|
|
342
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
if (chunk.type === "tool-call") {
|
|
346
|
+
const call = chunk;
|
|
347
|
+
const toolName = call.toolName;
|
|
348
|
+
const iTool = ctx.tools[toolName];
|
|
349
|
+
const agentEvent = this.processToolEvent(ctx.toolsCalled, {
|
|
350
|
+
type: "tool-call-start",
|
|
351
|
+
name: toolName,
|
|
352
|
+
toolCallId: call.toolCallId,
|
|
353
|
+
// biome-ignore lint/suspicious/noExplicitAny: unknown
|
|
354
|
+
msg: iTool ? iTool.display(call.input) : "",
|
|
355
|
+
args: call.input,
|
|
356
|
+
});
|
|
357
|
+
ctx.pendingToolCalls.push({ call, toolName, iTool });
|
|
358
|
+
return {
|
|
359
|
+
agentEvent,
|
|
360
|
+
accumulatedText: ctx.accumulatedText,
|
|
361
|
+
accumulatedReasoning: ctx.accumulatedReasoning,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
updateUsageStats(stepUsage, sessionManager) {
|
|
367
|
+
this._state.usage.inputTokens = stepUsage.inputTokens ?? 0;
|
|
368
|
+
this._state.usage.outputTokens = stepUsage.outputTokens ?? 0;
|
|
369
|
+
this._state.usage.totalTokens = stepUsage.totalTokens ?? 0;
|
|
370
|
+
this._state.usage.cachedInputTokens =
|
|
371
|
+
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
372
|
+
this._state.usage.inputTokenDetails.cacheReadTokens =
|
|
373
|
+
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
374
|
+
this._state.usage.reasoningTokens =
|
|
375
|
+
stepUsage.outputTokenDetails.reasoningTokens ?? 0;
|
|
376
|
+
sessionManager.setContextWindow(stepUsage.totalTokens ?? 0);
|
|
377
|
+
this._state.totalUsage.inputTokens += stepUsage.inputTokens ?? 0;
|
|
378
|
+
this._state.totalUsage.outputTokens += stepUsage.outputTokens ?? 0;
|
|
379
|
+
this._state.totalUsage.totalTokens += stepUsage.totalTokens ?? 0;
|
|
380
|
+
this._state.totalUsage.cachedInputTokens +=
|
|
381
|
+
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
382
|
+
this._state.totalUsage.inputTokenDetails.cacheReadTokens +=
|
|
383
|
+
stepUsage.inputTokenDetails.cacheReadTokens ?? 0;
|
|
384
|
+
this._state.totalUsage.reasoningTokens +=
|
|
385
|
+
stepUsage.outputTokenDetails.reasoningTokens ?? 0;
|
|
386
|
+
sessionManager.recordTurnUsage({
|
|
387
|
+
inputTokens: stepUsage.inputTokens ?? 0,
|
|
388
|
+
outputTokens: stepUsage.outputTokens ?? 0,
|
|
389
|
+
totalTokens: stepUsage.totalTokens ?? 0,
|
|
390
|
+
cachedInputTokens: stepUsage.inputTokenDetails.cacheReadTokens ?? 0,
|
|
391
|
+
reasoningTokens: stepUsage.outputTokenDetails.reasoningTokens ?? 0,
|
|
392
|
+
inputTokenDetails: {
|
|
393
|
+
noCacheTokens: stepUsage.inputTokenDetails.noCacheTokens ?? 0,
|
|
394
|
+
cacheReadTokens: stepUsage.inputTokenDetails.cacheReadTokens ?? 0,
|
|
395
|
+
cacheWriteTokens: stepUsage.inputTokenDetails.cacheWriteTokens ?? 0,
|
|
396
|
+
},
|
|
397
|
+
outputTokenDetails: {
|
|
398
|
+
textTokens: stepUsage.outputTokenDetails.textTokens ?? 0,
|
|
399
|
+
reasoningTokens: stepUsage.outputTokenDetails.reasoningTokens ?? 0,
|
|
400
|
+
},
|
|
401
|
+
});
|
|
402
|
+
}
|
|
368
403
|
processToolEvent(toolsCalled, event) {
|
|
369
404
|
const toolCallId = event.toolCallId;
|
|
370
405
|
let events;
|
|
@@ -389,6 +424,172 @@ export class Agent {
|
|
|
389
424
|
events,
|
|
390
425
|
};
|
|
391
426
|
}
|
|
427
|
+
async executeToolsInParallel({ pendingToolCalls, abortSignal, toolsCalled, stepToolCalls, stepToolResults, }) {
|
|
428
|
+
const results = new Array(pendingToolCalls.length);
|
|
429
|
+
const collectedEvents = [];
|
|
430
|
+
// Phase 2a: Validate all inputs first (before any execution)
|
|
431
|
+
const validationErrors = this.validateToolInputs(pendingToolCalls);
|
|
432
|
+
// Emit validation errors and mark those tools as failed
|
|
433
|
+
for (const { index, error } of validationErrors) {
|
|
434
|
+
const { call, toolName } = pendingToolCalls[index];
|
|
435
|
+
const event = this.processToolEvent(toolsCalled, {
|
|
436
|
+
type: "tool-call-error",
|
|
437
|
+
name: toolName,
|
|
438
|
+
toolCallId: call.toolCallId,
|
|
439
|
+
msg: error,
|
|
440
|
+
args: null,
|
|
441
|
+
});
|
|
442
|
+
collectedEvents.push(event);
|
|
443
|
+
results[index] = {
|
|
444
|
+
toolCallId: call.toolCallId,
|
|
445
|
+
toolName,
|
|
446
|
+
resultOutput: error,
|
|
447
|
+
success: false,
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
// Phase 2b: Execute valid tools in parallel
|
|
451
|
+
const sessionManager = this.opts.sessionManager;
|
|
452
|
+
const executionPromises = pendingToolCalls.map(async (pending, index) => {
|
|
453
|
+
if (validationErrors.some((e) => e.index === index)) {
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
await this.executeSingleTool({
|
|
457
|
+
pending,
|
|
458
|
+
index,
|
|
459
|
+
sessionManager,
|
|
460
|
+
abortSignal,
|
|
461
|
+
toolsCalled,
|
|
462
|
+
collectedEvents,
|
|
463
|
+
results,
|
|
464
|
+
stepToolCalls,
|
|
465
|
+
stepToolResults,
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
// Wait for all executions to complete
|
|
469
|
+
await Promise.allSettled(executionPromises);
|
|
470
|
+
// Phase 2c: Build toolMessages in original call order
|
|
471
|
+
const parallelToolMessages = this.buildToolMessages(results);
|
|
472
|
+
return { collectedEvents, parallelToolMessages };
|
|
473
|
+
}
|
|
474
|
+
validateToolInputs(pendingToolCalls) {
|
|
475
|
+
const validationErrors = [];
|
|
476
|
+
for (let i = 0; i < pendingToolCalls.length; i++) {
|
|
477
|
+
const { call } = pendingToolCalls[i];
|
|
478
|
+
// Check for invalid call from AI SDK
|
|
479
|
+
if (call.invalid) {
|
|
480
|
+
validationErrors.push({
|
|
481
|
+
index: i,
|
|
482
|
+
error: String(call.error),
|
|
483
|
+
});
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
// Validate JSON input
|
|
487
|
+
if (typeof call.input === "string") {
|
|
488
|
+
try {
|
|
489
|
+
JSON.parse(call.input);
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
validationErrors.push({
|
|
493
|
+
index: i,
|
|
494
|
+
error: `Invalid tool input: malformed JSON. Received: "${call.input.slice(0, 50)}${call.input.length > 50 ? "..." : ""}". Expected a JSON object.`,
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
else if (call.input === null || call.input === undefined) {
|
|
499
|
+
validationErrors.push({
|
|
500
|
+
index: i,
|
|
501
|
+
error: "Invalid tool input: received null/undefined. Expected a JSON object matching the schema.",
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return validationErrors;
|
|
506
|
+
}
|
|
507
|
+
async executeSingleTool({ pending, index, sessionManager, abortSignal, toolsCalled, collectedEvents, results, stepToolCalls, stepToolResults, }) {
|
|
508
|
+
const { call, toolName, iTool } = pending;
|
|
509
|
+
// Track in step stats
|
|
510
|
+
stepToolCalls.push({ toolName });
|
|
511
|
+
stepToolResults.push({ toolName });
|
|
512
|
+
if (!iTool) {
|
|
513
|
+
const errorMsg = `No executor for tool ${toolName}`;
|
|
514
|
+
const event = this.processToolEvent(toolsCalled, {
|
|
515
|
+
type: "tool-call-error",
|
|
516
|
+
name: toolName,
|
|
517
|
+
toolCallId: call.toolCallId,
|
|
518
|
+
msg: errorMsg,
|
|
519
|
+
args: null,
|
|
520
|
+
});
|
|
521
|
+
collectedEvents.push(event);
|
|
522
|
+
results[index] = {
|
|
523
|
+
toolCallId: call.toolCallId,
|
|
524
|
+
toolName,
|
|
525
|
+
resultOutput: errorMsg,
|
|
526
|
+
success: false,
|
|
527
|
+
};
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
const toolExec = iTool.execute;
|
|
531
|
+
try {
|
|
532
|
+
const output = await toolExec(call.input, {
|
|
533
|
+
toolCallId: call.toolCallId,
|
|
534
|
+
messages: sessionManager.get(),
|
|
535
|
+
abortSignal,
|
|
536
|
+
});
|
|
537
|
+
const resultOutput = formatToolResult(output);
|
|
538
|
+
const event = this.processToolEvent(toolsCalled, {
|
|
539
|
+
type: "tool-call-end",
|
|
540
|
+
name: call.toolName,
|
|
541
|
+
toolCallId: call.toolCallId,
|
|
542
|
+
msg: resultOutput,
|
|
543
|
+
args: call.input,
|
|
544
|
+
});
|
|
545
|
+
collectedEvents.push(event);
|
|
546
|
+
results[index] = {
|
|
547
|
+
toolCallId: call.toolCallId,
|
|
548
|
+
toolName,
|
|
549
|
+
resultOutput,
|
|
550
|
+
success: true,
|
|
551
|
+
};
|
|
552
|
+
}
|
|
553
|
+
catch (err) {
|
|
554
|
+
const resultOutput = `Tool error: ${err instanceof Error ? err.message : String(err)}`;
|
|
555
|
+
const event = this.processToolEvent(toolsCalled, {
|
|
556
|
+
type: "tool-call-error",
|
|
557
|
+
name: toolName,
|
|
558
|
+
toolCallId: call.toolCallId,
|
|
559
|
+
msg: resultOutput,
|
|
560
|
+
args: null,
|
|
561
|
+
});
|
|
562
|
+
collectedEvents.push(event);
|
|
563
|
+
results[index] = {
|
|
564
|
+
toolCallId: call.toolCallId,
|
|
565
|
+
toolName,
|
|
566
|
+
resultOutput,
|
|
567
|
+
success: false,
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
buildToolMessages(results) {
|
|
572
|
+
const parallelToolMessages = [];
|
|
573
|
+
for (const result of results) {
|
|
574
|
+
if (!result)
|
|
575
|
+
continue; // Skip if somehow undefined
|
|
576
|
+
parallelToolMessages.push({
|
|
577
|
+
role: "tool",
|
|
578
|
+
content: [
|
|
579
|
+
{
|
|
580
|
+
type: "tool-result",
|
|
581
|
+
toolName: result.toolName,
|
|
582
|
+
toolCallId: result.toolCallId,
|
|
583
|
+
output: {
|
|
584
|
+
type: "text",
|
|
585
|
+
value: result.resultOutput,
|
|
586
|
+
},
|
|
587
|
+
},
|
|
588
|
+
],
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
return parallelToolMessages;
|
|
592
|
+
}
|
|
392
593
|
}
|
|
393
594
|
function formatToolResult(value) {
|
|
394
595
|
if (typeof value === "string") {
|
|
@@ -419,6 +620,7 @@ const toolCallRepair = (modelManager) => {
|
|
|
419
620
|
if (NoSuchToolError.isInstance(error)) {
|
|
420
621
|
return null; // do not attempt to fix invalid tool names
|
|
421
622
|
}
|
|
623
|
+
logger.error(`Attemping to repair tool call: ${toolCall.toolName} - ${toolCall.input}`);
|
|
422
624
|
const tool = tools[toolCall.toolName];
|
|
423
625
|
try {
|
|
424
626
|
const { output: repairedArgs } = await generateText({
|
|
@@ -427,11 +629,19 @@ const toolCallRepair = (modelManager) => {
|
|
|
427
629
|
schema: tool.inputSchema,
|
|
428
630
|
}),
|
|
429
631
|
prompt: [
|
|
430
|
-
`The model tried to call the tool "${toolCall.toolName}"
|
|
431
|
-
|
|
432
|
-
"
|
|
433
|
-
JSON.stringify(
|
|
434
|
-
"
|
|
632
|
+
`The model tried to call the tool "${toolCall.toolName}" but the input did not match the expected schema.`,
|
|
633
|
+
"",
|
|
634
|
+
"<invalid_input>",
|
|
635
|
+
JSON.stringify(toolCall.input, null, 2),
|
|
636
|
+
"</invalid_input>",
|
|
637
|
+
"",
|
|
638
|
+
"<expected_schema>",
|
|
639
|
+
JSON.stringify(await inputSchema({ toolName: toolCall.toolName }), null, 2),
|
|
640
|
+
"</expected_schema>",
|
|
641
|
+
"",
|
|
642
|
+
"If any field is missing or undefined in the corrected input, you MUST explicitly set its value to null. Do NOT omit fields - every field in the schema must be present, even if with a null value.",
|
|
643
|
+
"",
|
|
644
|
+
"Return a corrected version of the input that conforms to the expected schema.",
|
|
435
645
|
].join("\n"),
|
|
436
646
|
});
|
|
437
647
|
return { ...toolCall, args: JSON.stringify(repairedArgs) };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WorkspaceContext } from "../index.ts";
|
|
2
|
+
import type { ModelName } from "../models/providers.ts";
|
|
3
|
+
export declare class SubAgent {
|
|
4
|
+
workspace: WorkspaceContext;
|
|
5
|
+
constructor(options: {
|
|
6
|
+
workspace: WorkspaceContext;
|
|
7
|
+
});
|
|
8
|
+
execute({ model, system, prompt, abortSignal, allowedTools, timeout, }: {
|
|
9
|
+
model: ModelName;
|
|
10
|
+
system: string;
|
|
11
|
+
prompt: string;
|
|
12
|
+
abortSignal?: AbortSignal;
|
|
13
|
+
allowedTools?: string[];
|
|
14
|
+
timeout?: number;
|
|
15
|
+
}): Promise<string>;
|
|
16
|
+
private prepareExecution;
|
|
17
|
+
private filterTools;
|
|
18
|
+
private createTimeoutSignal;
|
|
19
|
+
private combineAbortSignals;
|
|
20
|
+
private runGenerateText;
|
|
21
|
+
private transformError;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=sub-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sub-agent.d.ts","sourceRoot":"","sources":["../../source/agent/sub-agent.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAGpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAKxD,qBAAa,QAAQ;IACnB,SAAS,EAAE,gBAAgB,CAAC;gBAEhB,OAAO,EAAE;QACnB,SAAS,EAAE,gBAAgB,CAAC;KAC7B;IAIK,OAAO,CAAC,EACZ,KAAK,EACL,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,OAAO,GACR,EAAE;QACD,KAAK,EAAE,SAAS,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB;YAgCa,gBAAgB;IA2B9B,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,mBAAmB;YAmBb,eAAe;IAmC7B,OAAO,CAAC,cAAc;CASvB"}
|