@travisennis/acai 0.0.9 → 0.0.11
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 +51 -760
- 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 +380 -199
- 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 -77
- package/dist/{stdin.d.ts → cli/stdin.d.ts} +2 -1
- package/dist/cli/stdin.d.ts.map +1 -0
- package/dist/{stdin.js → cli/stdin.js} +11 -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 -101
- package/dist/commands/generate-rules/service.d.ts +22 -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 +3 -2
- 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 +2 -1
- 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 +55 -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 +15 -1
- 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 +124 -135
- 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 +148 -141
- 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 +2 -5
- package/dist/models/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +0 -52
- package/dist/models/opencode-go-provider.d.ts +25 -0
- package/dist/models/opencode-go-provider.d.ts.map +1 -0
- package/dist/models/opencode-go-provider.js +78 -0
- package/dist/models/opencode-zen-provider.d.ts +7 -3
- package/dist/models/opencode-zen-provider.d.ts.map +1 -1
- package/dist/models/opencode-zen-provider.js +49 -10
- package/dist/models/openrouter-provider.d.ts +27 -31
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +121 -180
- package/dist/models/providers.d.ts +3 -3
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +6 -0
- 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 +24 -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 +142 -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} +55 -85
- package/dist/{prompts.d.ts → prompts/system-prompt.d.ts} +7 -2
- package/dist/prompts/system-prompt.d.ts.map +1 -0
- package/dist/{prompts.js → prompts/system-prompt.js} +31 -16
- 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} +397 -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 +92 -0
- package/dist/sessions/manager.d.ts.map +1 -1
- package/dist/sessions/manager.js +262 -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/index.d.ts +29 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +294 -0
- package/dist/subagents/index.d.ts +16 -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 +3 -3
- 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 +1 -1
- 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 +174 -105
- 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/apply-patch.d.ts +62 -0
- package/dist/tools/apply-patch.d.ts.map +1 -0
- package/dist/tools/apply-patch.js +377 -0
- package/dist/tools/bash.d.ts +4 -3
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +349 -141
- 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 +3 -6
- 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 +292 -85
- package/dist/tools/glob.d.ts +6 -6
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +110 -63
- package/dist/tools/grep.d.ts +15 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +315 -193
- package/dist/tools/index.d.ts +114 -9
- 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 +4 -6
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +84 -39
- 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 +36 -31
- 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 +50 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +446 -0
- package/dist/tools/web-search.d.ts +44 -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 +37 -17
- 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/utils.d.ts +2 -1
- package/dist/tui/autocomplete/utils.d.ts.map +1 -1
- package/dist/tui/autocomplete/utils.js +25 -23
- 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 +18 -3
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +211 -237
- 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 +10 -7
- 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 +36 -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.d.ts +2 -1
- package/dist/tui/components/welcome.d.ts.map +1 -1
- package/dist/tui/components/welcome.js +2 -2
- package/dist/tui/editor-launcher.d.ts +3 -2
- package/dist/tui/editor-launcher.d.ts.map +1 -1
- package/dist/tui/index.d.ts +0 -1
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +10 -2
- package/dist/tui/tui.d.ts +43 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +166 -41
- package/dist/tui/utils.d.ts +1 -5
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +271 -44
- 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 +28 -30
- 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 +35 -26
- package/dist/cli.d.ts +0 -23
- package/dist/cli.d.ts.map +0 -1
- package/dist/commands/add-directory/types.d.ts +0 -6
- package/dist/commands/add-directory/types.d.ts.map +0 -1
- package/dist/commands/add-directory/types.js +0 -1
- package/dist/commands/copy/types.d.ts +0 -3
- package/dist/commands/copy/types.d.ts.map +0 -1
- package/dist/commands/copy/types.js +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 -122
- 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/review/types.d.ts +0 -12
- package/dist/commands/review/types.d.ts.map +0 -1
- package/dist/commands/review/types.js +0 -1
- 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.map +0 -1
- package/dist/repl-new.d.ts +0 -65
- package/dist/repl-new.d.ts.map +0 -1
- package/dist/skills.d.ts +0 -16
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js +0 -233
- package/dist/stdin.d.ts.map +0 -1
- 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/utils/iterables.d.ts +0 -2
- package/dist/utils/iterables.d.ts.map +0 -1
- package/dist/utils/iterables.js +0 -6
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-status.d.ts","sourceRoot":"","sources":["../../source/repl/project-status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-status.d.ts","sourceRoot":"","sources":["../../source/repl/project-status.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,SAAS,EAAE;QACT,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAwFD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAEnE;AAID,wBAAgB,uBAAuB,IAAI,IAAI,CAE9C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getCurrentBranch, getDiffStat, getGitStatus, inGitDirectory, } from "../utils/git.js";
|
|
1
|
+
import { getCurrentBranch, getDiffStat, getGitStatus, getUnpushedCommitsCount, inGitDirectory, } from "../utils/git.js";
|
|
2
2
|
// Cache for project status to prevent excessive Git operations
|
|
3
3
|
class ProjectStatus {
|
|
4
4
|
cachedStatus = null;
|
|
@@ -31,6 +31,7 @@ class ProjectStatus {
|
|
|
31
31
|
deletions: 0,
|
|
32
32
|
},
|
|
33
33
|
hasChanges: false,
|
|
34
|
+
unpushedCommits: 0,
|
|
34
35
|
};
|
|
35
36
|
if (await inGitDirectory()) {
|
|
36
37
|
// Generate fresh status
|
|
@@ -40,11 +41,13 @@ class ProjectStatus {
|
|
|
40
41
|
fileChanges.deleted > 0 ||
|
|
41
42
|
fileChanges.modified > 0;
|
|
42
43
|
const stats = await getDiffStat();
|
|
44
|
+
const unpushedCommits = await getUnpushedCommitsCount();
|
|
43
45
|
status = {
|
|
44
46
|
path: currentDir,
|
|
45
47
|
isGitRepository: true,
|
|
46
48
|
branch: branch ?? undefined,
|
|
47
49
|
hasChanges,
|
|
50
|
+
unpushedCommits,
|
|
48
51
|
fileChanges: {
|
|
49
52
|
added: fileChanges.added,
|
|
50
53
|
modified: fileChanges.modified,
|
|
@@ -5,11 +5,60 @@ import type { ModelManager } from "../models/manager.ts";
|
|
|
5
5
|
import type { TokenTracker } from "../tokens/tracker.ts";
|
|
6
6
|
export type UserMessageContentItem = string | ImagePart;
|
|
7
7
|
export declare function createUserMessage(contentItems: UserMessageContentItem[], prompt?: string): UserModelMessage;
|
|
8
|
+
export declare function sanitizeResponseMessages(messages: ResponseMessage[]): ResponseMessage[];
|
|
8
9
|
/**
|
|
9
10
|
A message that was generated during the generation process.
|
|
10
11
|
It can be either an assistant message or a tool message.
|
|
11
12
|
*/
|
|
12
13
|
type ResponseMessage = AssistantModelMessage | ToolModelMessage;
|
|
14
|
+
/**
|
|
15
|
+
* Compact token usage stored in session files.
|
|
16
|
+
* Only stores total aggregated usage and last turn's usage
|
|
17
|
+
* to minimize session file size while maintaining necessary information.
|
|
18
|
+
*/
|
|
19
|
+
type SessionTokenUsage = {
|
|
20
|
+
/** Aggregated total for entire session */
|
|
21
|
+
total: {
|
|
22
|
+
inputTokens: number;
|
|
23
|
+
outputTokens: number;
|
|
24
|
+
totalTokens: number;
|
|
25
|
+
cachedInputTokens: number;
|
|
26
|
+
reasoningTokens: number;
|
|
27
|
+
estimatedCost: number;
|
|
28
|
+
};
|
|
29
|
+
/** Last turn's usage (for context window display) */
|
|
30
|
+
lastTurn: {
|
|
31
|
+
inputTokens: number;
|
|
32
|
+
outputTokens: number;
|
|
33
|
+
totalTokens: number;
|
|
34
|
+
cachedInputTokens: number;
|
|
35
|
+
reasoningTokens: number;
|
|
36
|
+
estimatedCost: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Use SessionTokenUsage instead. Kept for backward compatibility
|
|
41
|
+
* with older session files that may have the old format.
|
|
42
|
+
*/
|
|
43
|
+
type TokenUsageTurn = {
|
|
44
|
+
stepIndex: number;
|
|
45
|
+
inputTokens: number;
|
|
46
|
+
outputTokens: number;
|
|
47
|
+
totalTokens: number;
|
|
48
|
+
cachedInputTokens: number;
|
|
49
|
+
reasoningTokens: number;
|
|
50
|
+
inputTokenDetails: {
|
|
51
|
+
noCacheTokens: number;
|
|
52
|
+
cacheReadTokens: number;
|
|
53
|
+
cacheWriteTokens: number;
|
|
54
|
+
};
|
|
55
|
+
outputTokenDetails: {
|
|
56
|
+
textTokens: number;
|
|
57
|
+
reasoningTokens: number;
|
|
58
|
+
};
|
|
59
|
+
timestamp: number;
|
|
60
|
+
estimatedCost: number;
|
|
61
|
+
};
|
|
13
62
|
type SavedMessageHistory = {
|
|
14
63
|
project: string;
|
|
15
64
|
sessionId: string;
|
|
@@ -18,6 +67,8 @@ type SavedMessageHistory = {
|
|
|
18
67
|
createdAt: Date;
|
|
19
68
|
updatedAt: Date;
|
|
20
69
|
messages: ModelMessage[];
|
|
70
|
+
tokenUsage?: SessionTokenUsage | TokenUsageTurn[];
|
|
71
|
+
metadata?: Record<string, unknown>;
|
|
21
72
|
};
|
|
22
73
|
interface MessageHistoryEvents {
|
|
23
74
|
"update-title": [string];
|
|
@@ -34,15 +85,23 @@ export declare class SessionManager extends EventEmitter<MessageHistoryEvents> {
|
|
|
34
85
|
private contextWindow;
|
|
35
86
|
private modelManager;
|
|
36
87
|
private tokenTracker;
|
|
88
|
+
private tokenUsage;
|
|
89
|
+
private transientMessages;
|
|
90
|
+
private metadata;
|
|
37
91
|
constructor({ stateDir, modelManager, tokenTracker, }: {
|
|
38
92
|
stateDir: string;
|
|
39
93
|
modelManager: ModelManager;
|
|
40
94
|
tokenTracker: TokenTracker;
|
|
41
95
|
});
|
|
96
|
+
private createEmptyTokenUsage;
|
|
42
97
|
create(modelId: string): void;
|
|
43
98
|
setModelId(modelId: string): void;
|
|
44
99
|
private validMessage;
|
|
45
100
|
get(): ModelMessage[];
|
|
101
|
+
setTransientMessages(messages: UserModelMessage[]): void;
|
|
102
|
+
clearTransientMessages(): void;
|
|
103
|
+
setMetadata(key: string, value: unknown): void;
|
|
104
|
+
getMetadata(key: string): unknown;
|
|
46
105
|
clear(): void;
|
|
47
106
|
setContextWindow(contextWindow: number): void;
|
|
48
107
|
getContextWindow(): number;
|
|
@@ -67,8 +126,41 @@ export declare class SessionManager extends EventEmitter<MessageHistoryEvents> {
|
|
|
67
126
|
getTitle(): string;
|
|
68
127
|
getCreatedAt(): Date;
|
|
69
128
|
getUpdatedAt(): Date;
|
|
129
|
+
getSessionFileName(): string;
|
|
130
|
+
getSessionFilePath(): string;
|
|
70
131
|
static load(stateDir: string, count?: number): Promise<SavedMessageHistory[]>;
|
|
71
132
|
restore(savedHistory: SavedMessageHistory): void;
|
|
133
|
+
recordTurnUsage(usage: {
|
|
134
|
+
inputTokens: number;
|
|
135
|
+
outputTokens: number;
|
|
136
|
+
totalTokens: number;
|
|
137
|
+
cachedInputTokens: number;
|
|
138
|
+
reasoningTokens: number;
|
|
139
|
+
inputTokenDetails: {
|
|
140
|
+
noCacheTokens: number;
|
|
141
|
+
cacheReadTokens: number;
|
|
142
|
+
cacheWriteTokens: number;
|
|
143
|
+
};
|
|
144
|
+
outputTokenDetails: {
|
|
145
|
+
textTokens: number;
|
|
146
|
+
reasoningTokens: number;
|
|
147
|
+
};
|
|
148
|
+
}): void;
|
|
149
|
+
/**
|
|
150
|
+
* @deprecated This method returns an empty array since we no longer store
|
|
151
|
+
* per-turn usage data. Use getTotalTokenUsage() or getLastTurnContextWindow() instead.
|
|
152
|
+
*/
|
|
153
|
+
getTokenUsage(): TokenUsageTurn[];
|
|
154
|
+
getTotalTokenUsage(): {
|
|
155
|
+
inputTokens: number;
|
|
156
|
+
outputTokens: number;
|
|
157
|
+
totalTokens: number;
|
|
158
|
+
cachedInputTokens: number;
|
|
159
|
+
reasoningTokens: number;
|
|
160
|
+
estimatedCost: number;
|
|
161
|
+
};
|
|
162
|
+
getLastTurnContextWindow(): number;
|
|
163
|
+
clearTokenUsage(): void;
|
|
72
164
|
}
|
|
73
165
|
export {};
|
|
74
166
|
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../source/sessions/manager.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,aAAa,CAAC;AAYvC,OAAO,EACL,KAAK,qBAAqB,EAE1B,KAAK,SAAS,EAAE,kBAAkB;AAClC,KAAK,YAAY,EAEjB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACtB,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../source/sessions/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/sessions/manager.js
CHANGED
|
@@ -4,8 +4,8 @@ import { mkdir, readdir, readFile, rename, stat, unlink, writeFile, } from "node
|
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { isString } from "@travisennis/stdlib/typeguards";
|
|
6
6
|
import { generateText, } from "ai";
|
|
7
|
-
import { dedent } from "../dedent.js";
|
|
8
|
-
import { logger } from "../logger.js";
|
|
7
|
+
import { dedent } from "../utils/dedent.js";
|
|
8
|
+
import { logger } from "../utils/logger.js";
|
|
9
9
|
export function createUserMessage(contentItems, prompt) {
|
|
10
10
|
const messageParts = [];
|
|
11
11
|
// Process content items (images and pre-defined texts)
|
|
@@ -39,6 +39,68 @@ function createAssistantMessage(content) {
|
|
|
39
39
|
],
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
+
function isPlainObject(x) {
|
|
43
|
+
return typeof x === "object" && x !== null && !Array.isArray(x);
|
|
44
|
+
}
|
|
45
|
+
function sanitizeToolCallInput(input) {
|
|
46
|
+
// If it's already a valid plain object, return as-is
|
|
47
|
+
if (isPlainObject(input)) {
|
|
48
|
+
return { sanitized: input, isValid: true };
|
|
49
|
+
}
|
|
50
|
+
// If it's a string, try to parse it as JSON
|
|
51
|
+
if (typeof input === "string") {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(input);
|
|
54
|
+
if (isPlainObject(parsed)) {
|
|
55
|
+
return { sanitized: parsed, isValid: true };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// JSON parsing failed - this is malformed JSON
|
|
60
|
+
logger.warn({ originalInput: input.slice(0, 100) }, "Filtered tool call with malformed JSON input");
|
|
61
|
+
return { sanitized: {}, isValid: false };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// For any other case (undefined, null, array, etc.)
|
|
65
|
+
logger.warn({ originalInput: typeof input === "string" ? input.slice(0, 100) : input }, "Filtered tool call with invalid input type");
|
|
66
|
+
return { sanitized: {}, isValid: false };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if a tool call input is valid and return sanitized version.
|
|
70
|
+
* This helper reduces complexity by extracting validation logic.
|
|
71
|
+
*/
|
|
72
|
+
function sanitizeToolCallPart(part) {
|
|
73
|
+
if (part.type !== "tool-call") {
|
|
74
|
+
return null; // Not a tool call, keep as-is
|
|
75
|
+
}
|
|
76
|
+
const { sanitized, isValid } = sanitizeToolCallInput(part.input);
|
|
77
|
+
if (!isValid) {
|
|
78
|
+
logger.debug({ toolName: part.toolName }, "Sanitized invalid tool call input");
|
|
79
|
+
}
|
|
80
|
+
// Always keep tool calls so the model can see the corresponding tool-result
|
|
81
|
+
return { ...part, input: sanitized };
|
|
82
|
+
}
|
|
83
|
+
export function sanitizeResponseMessages(messages) {
|
|
84
|
+
return messages.map((msg) => {
|
|
85
|
+
if (msg.role !== "assistant" || !Array.isArray(msg.content)) {
|
|
86
|
+
return msg;
|
|
87
|
+
}
|
|
88
|
+
// Sanitize tool call inputs while always preserving the tool-call itself.
|
|
89
|
+
// The model needs to see every tool-call to match it with its tool-result.
|
|
90
|
+
const sanitizedContent = [];
|
|
91
|
+
for (const part of msg.content) {
|
|
92
|
+
const sanitized = sanitizeToolCallPart(part);
|
|
93
|
+
if (sanitized === null) {
|
|
94
|
+
// Not a tool call, keep as-is
|
|
95
|
+
sanitizedContent.push(part);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
sanitizedContent.push(sanitized);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return { ...msg, content: sanitizedContent };
|
|
102
|
+
});
|
|
103
|
+
}
|
|
42
104
|
export class SessionManager extends EventEmitter {
|
|
43
105
|
history;
|
|
44
106
|
sessionId;
|
|
@@ -50,6 +112,9 @@ export class SessionManager extends EventEmitter {
|
|
|
50
112
|
contextWindow;
|
|
51
113
|
modelManager;
|
|
52
114
|
tokenTracker;
|
|
115
|
+
tokenUsage;
|
|
116
|
+
transientMessages = [];
|
|
117
|
+
metadata = {};
|
|
53
118
|
constructor({ stateDir, modelManager, tokenTracker, }) {
|
|
54
119
|
super();
|
|
55
120
|
this.history = [];
|
|
@@ -62,6 +127,27 @@ export class SessionManager extends EventEmitter {
|
|
|
62
127
|
this.contextWindow = 0;
|
|
63
128
|
this.modelManager = modelManager;
|
|
64
129
|
this.tokenTracker = tokenTracker;
|
|
130
|
+
this.tokenUsage = null;
|
|
131
|
+
}
|
|
132
|
+
createEmptyTokenUsage() {
|
|
133
|
+
return {
|
|
134
|
+
total: {
|
|
135
|
+
inputTokens: 0,
|
|
136
|
+
outputTokens: 0,
|
|
137
|
+
totalTokens: 0,
|
|
138
|
+
cachedInputTokens: 0,
|
|
139
|
+
reasoningTokens: 0,
|
|
140
|
+
estimatedCost: 0,
|
|
141
|
+
},
|
|
142
|
+
lastTurn: {
|
|
143
|
+
inputTokens: 0,
|
|
144
|
+
outputTokens: 0,
|
|
145
|
+
totalTokens: 0,
|
|
146
|
+
cachedInputTokens: 0,
|
|
147
|
+
reasoningTokens: 0,
|
|
148
|
+
estimatedCost: 0,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
65
151
|
}
|
|
66
152
|
create(modelId) {
|
|
67
153
|
this.clear();
|
|
@@ -90,11 +176,35 @@ export class SessionManager extends EventEmitter {
|
|
|
90
176
|
return true;
|
|
91
177
|
}
|
|
92
178
|
get() {
|
|
93
|
-
|
|
179
|
+
const history = [...this.history].filter(this.validMessage);
|
|
180
|
+
if (this.transientMessages.length > 0 && history.length > 0) {
|
|
181
|
+
const lastIndex = history.length - 1;
|
|
182
|
+
return [
|
|
183
|
+
...history.slice(0, lastIndex),
|
|
184
|
+
...this.transientMessages,
|
|
185
|
+
history[lastIndex],
|
|
186
|
+
];
|
|
187
|
+
}
|
|
188
|
+
return history;
|
|
189
|
+
}
|
|
190
|
+
setTransientMessages(messages) {
|
|
191
|
+
this.transientMessages = messages;
|
|
192
|
+
}
|
|
193
|
+
clearTransientMessages() {
|
|
194
|
+
this.transientMessages = [];
|
|
195
|
+
}
|
|
196
|
+
setMetadata(key, value) {
|
|
197
|
+
this.metadata[key] = value;
|
|
198
|
+
}
|
|
199
|
+
getMetadata(key) {
|
|
200
|
+
return this.metadata[key];
|
|
94
201
|
}
|
|
95
202
|
clear() {
|
|
96
203
|
this.history.length = 0;
|
|
204
|
+
this.transientMessages = [];
|
|
205
|
+
this.metadata = {};
|
|
97
206
|
this.contextWindow = 0;
|
|
207
|
+
this.tokenUsage = null;
|
|
98
208
|
this.emit("clear-history");
|
|
99
209
|
}
|
|
100
210
|
setContextWindow(contextWindow) {
|
|
@@ -128,12 +238,31 @@ export class SessionManager extends EventEmitter {
|
|
|
128
238
|
}
|
|
129
239
|
appendToolMessages(toolResultMessages) {
|
|
130
240
|
this.updatedAt = new Date();
|
|
131
|
-
|
|
241
|
+
// Collect existing tool-result IDs to prevent duplicates
|
|
242
|
+
// (the AI SDK may include tool-results that acai also creates)
|
|
243
|
+
const existingIds = new Set();
|
|
244
|
+
for (const msg of this.history) {
|
|
245
|
+
if (msg.role === "tool" && Array.isArray(msg.content)) {
|
|
246
|
+
for (const part of msg.content) {
|
|
247
|
+
if (part.type === "tool-result") {
|
|
248
|
+
existingIds.add(part.toolCallId);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const deduplicated = toolResultMessages.filter((msg) => {
|
|
254
|
+
if (!Array.isArray(msg.content))
|
|
255
|
+
return true;
|
|
256
|
+
return !msg.content.some((part) => part.type === "tool-result" && existingIds.has(part.toolCallId));
|
|
257
|
+
});
|
|
258
|
+
this.history.push(...deduplicated);
|
|
132
259
|
}
|
|
133
260
|
appendResponseMessages(responseMessages) {
|
|
134
261
|
this.updatedAt = new Date();
|
|
262
|
+
// Sanitize tool call inputs to prevent malformed JSON from poisoning history
|
|
263
|
+
const sanitizedMessages = sanitizeResponseMessages(responseMessages);
|
|
135
264
|
// Filter out messages with empty content arrays
|
|
136
|
-
const validMessages =
|
|
265
|
+
const validMessages = sanitizedMessages.filter(this.validMessage);
|
|
137
266
|
this.history.push(...validMessages);
|
|
138
267
|
}
|
|
139
268
|
isEmpty() {
|
|
@@ -141,7 +270,7 @@ export class SessionManager extends EventEmitter {
|
|
|
141
270
|
}
|
|
142
271
|
async save() {
|
|
143
272
|
const msgHistoryDir = this.stateDir;
|
|
144
|
-
const fileName =
|
|
273
|
+
const fileName = this.getSessionFileName();
|
|
145
274
|
const filePath = join(msgHistoryDir, fileName);
|
|
146
275
|
const tempFilePath = `${filePath}.tmp`;
|
|
147
276
|
// Validate data before writing
|
|
@@ -160,6 +289,8 @@ export class SessionManager extends EventEmitter {
|
|
|
160
289
|
createdAt: this.createdAt,
|
|
161
290
|
updatedAt: this.updatedAt,
|
|
162
291
|
messages: this.history,
|
|
292
|
+
...(this.tokenUsage !== null ? { tokenUsage: this.tokenUsage } : {}),
|
|
293
|
+
metadata: Object.keys(this.metadata).length > 0 ? this.metadata : undefined,
|
|
163
294
|
};
|
|
164
295
|
try {
|
|
165
296
|
// Ensure directory exists
|
|
@@ -297,12 +428,18 @@ React Component Rendering Debug";
|
|
|
297
428
|
getUpdatedAt() {
|
|
298
429
|
return this.updatedAt;
|
|
299
430
|
}
|
|
431
|
+
getSessionFileName() {
|
|
432
|
+
return `session-${this.sessionId}.json`;
|
|
433
|
+
}
|
|
434
|
+
getSessionFilePath() {
|
|
435
|
+
return join(this.stateDir, this.getSessionFileName());
|
|
436
|
+
}
|
|
300
437
|
static async load(stateDir, count = 10) {
|
|
301
438
|
try {
|
|
302
439
|
const files = await readdir(stateDir);
|
|
303
|
-
const
|
|
440
|
+
const sessionFiles = files.filter((file) => file.startsWith("session-") && file.endsWith(".json"));
|
|
304
441
|
// Get file stats and sort by modification time (newest first)
|
|
305
|
-
const fileStatsPromises =
|
|
442
|
+
const fileStatsPromises = sessionFiles.map(async (fileName) => {
|
|
306
443
|
const filePath = join(stateDir, fileName);
|
|
307
444
|
try {
|
|
308
445
|
const fileStat = await stat(filePath);
|
|
@@ -385,6 +522,122 @@ React Component Rendering Debug";
|
|
|
385
522
|
typeof savedHistory.updatedAt === "string"
|
|
386
523
|
? new Date(savedHistory.updatedAt)
|
|
387
524
|
: savedHistory.updatedAt;
|
|
388
|
-
|
|
525
|
+
// Sanitize messages while preserving original order
|
|
526
|
+
// Only sanitize assistant and tool messages (not user or system messages)
|
|
527
|
+
const sanitizedMessages = savedHistory.messages.map((msg) => {
|
|
528
|
+
if (msg.role === "assistant" || msg.role === "tool") {
|
|
529
|
+
const [sanitized] = sanitizeResponseMessages([msg]);
|
|
530
|
+
return sanitized;
|
|
531
|
+
}
|
|
532
|
+
return msg;
|
|
533
|
+
});
|
|
534
|
+
// Filter out messages with empty content arrays
|
|
535
|
+
const validMessages = sanitizedMessages.filter(this.validMessage);
|
|
536
|
+
this.history = [...validMessages];
|
|
537
|
+
// Handle tokenUsage restoration with backward compatibility
|
|
538
|
+
// Old format: TokenUsageTurn[] (array)
|
|
539
|
+
// New format: SessionTokenUsage (object with total and lastTurn)
|
|
540
|
+
if (savedHistory.tokenUsage) {
|
|
541
|
+
if (Array.isArray(savedHistory.tokenUsage)) {
|
|
542
|
+
// Old format: convert array to new format
|
|
543
|
+
const oldUsage = savedHistory.tokenUsage;
|
|
544
|
+
if (oldUsage.length > 0) {
|
|
545
|
+
const total = oldUsage.reduce((acc, turn) => {
|
|
546
|
+
acc.inputTokens += turn.inputTokens;
|
|
547
|
+
acc.outputTokens += turn.outputTokens;
|
|
548
|
+
acc.totalTokens += turn.totalTokens;
|
|
549
|
+
acc.cachedInputTokens += turn.cachedInputTokens;
|
|
550
|
+
acc.reasoningTokens += turn.reasoningTokens;
|
|
551
|
+
acc.estimatedCost += turn.estimatedCost;
|
|
552
|
+
return acc;
|
|
553
|
+
}, {
|
|
554
|
+
inputTokens: 0,
|
|
555
|
+
outputTokens: 0,
|
|
556
|
+
totalTokens: 0,
|
|
557
|
+
cachedInputTokens: 0,
|
|
558
|
+
reasoningTokens: 0,
|
|
559
|
+
estimatedCost: 0,
|
|
560
|
+
});
|
|
561
|
+
const lastTurn = oldUsage[oldUsage.length - 1];
|
|
562
|
+
this.tokenUsage = {
|
|
563
|
+
total,
|
|
564
|
+
lastTurn: {
|
|
565
|
+
inputTokens: lastTurn.inputTokens,
|
|
566
|
+
outputTokens: lastTurn.outputTokens,
|
|
567
|
+
totalTokens: lastTurn.totalTokens,
|
|
568
|
+
cachedInputTokens: lastTurn.cachedInputTokens,
|
|
569
|
+
reasoningTokens: lastTurn.reasoningTokens,
|
|
570
|
+
estimatedCost: lastTurn.estimatedCost,
|
|
571
|
+
},
|
|
572
|
+
};
|
|
573
|
+
}
|
|
574
|
+
else {
|
|
575
|
+
this.tokenUsage = null;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
else {
|
|
579
|
+
// New format: already SessionTokenUsage
|
|
580
|
+
this.tokenUsage = savedHistory.tokenUsage;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
this.tokenUsage = null;
|
|
585
|
+
}
|
|
586
|
+
this.metadata = savedHistory.metadata ?? {};
|
|
587
|
+
}
|
|
588
|
+
// Token usage tracking methods
|
|
589
|
+
recordTurnUsage(usage) {
|
|
590
|
+
const modelConfig = this.modelManager.getModelMetadata("repl");
|
|
591
|
+
const estimatedCost = usage.inputTokens * modelConfig.costPerInputToken +
|
|
592
|
+
usage.outputTokens * modelConfig.costPerOutputToken;
|
|
593
|
+
// Initialize tokenUsage if null
|
|
594
|
+
if (this.tokenUsage === null) {
|
|
595
|
+
this.tokenUsage = this.createEmptyTokenUsage();
|
|
596
|
+
}
|
|
597
|
+
// Update total
|
|
598
|
+
this.tokenUsage.total.inputTokens += usage.inputTokens;
|
|
599
|
+
this.tokenUsage.total.outputTokens += usage.outputTokens;
|
|
600
|
+
this.tokenUsage.total.totalTokens += usage.totalTokens;
|
|
601
|
+
this.tokenUsage.total.cachedInputTokens += usage.cachedInputTokens;
|
|
602
|
+
this.tokenUsage.total.reasoningTokens += usage.reasoningTokens;
|
|
603
|
+
this.tokenUsage.total.estimatedCost += estimatedCost;
|
|
604
|
+
// Update lastTurn
|
|
605
|
+
this.tokenUsage.lastTurn.inputTokens = usage.inputTokens;
|
|
606
|
+
this.tokenUsage.lastTurn.outputTokens = usage.outputTokens;
|
|
607
|
+
this.tokenUsage.lastTurn.totalTokens = usage.totalTokens;
|
|
608
|
+
this.tokenUsage.lastTurn.cachedInputTokens = usage.cachedInputTokens;
|
|
609
|
+
this.tokenUsage.lastTurn.reasoningTokens = usage.reasoningTokens;
|
|
610
|
+
this.tokenUsage.lastTurn.estimatedCost = estimatedCost;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* @deprecated This method returns an empty array since we no longer store
|
|
614
|
+
* per-turn usage data. Use getTotalTokenUsage() or getLastTurnContextWindow() instead.
|
|
615
|
+
*/
|
|
616
|
+
getTokenUsage() {
|
|
617
|
+
// Return empty array for backward compatibility
|
|
618
|
+
// The actual data is now stored in compact format in this.tokenUsage
|
|
619
|
+
return [];
|
|
620
|
+
}
|
|
621
|
+
getTotalTokenUsage() {
|
|
622
|
+
if (this.tokenUsage === null) {
|
|
623
|
+
return {
|
|
624
|
+
inputTokens: 0,
|
|
625
|
+
outputTokens: 0,
|
|
626
|
+
totalTokens: 0,
|
|
627
|
+
cachedInputTokens: 0,
|
|
628
|
+
reasoningTokens: 0,
|
|
629
|
+
estimatedCost: 0,
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
return { ...this.tokenUsage.total };
|
|
633
|
+
}
|
|
634
|
+
getLastTurnContextWindow() {
|
|
635
|
+
if (this.tokenUsage === null) {
|
|
636
|
+
return 0;
|
|
637
|
+
}
|
|
638
|
+
return this.tokenUsage.lastTurn.totalTokens;
|
|
639
|
+
}
|
|
640
|
+
clearTokenUsage() {
|
|
641
|
+
this.tokenUsage = null;
|
|
389
642
|
}
|
|
390
643
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SessionManager } from "./manager.ts";
|
|
2
|
+
export declare function writeExitSummary(sessionManager: SessionManager, noSession?: boolean): void;
|
|
3
|
+
export declare function printExitSummary(sessionManager: SessionManager, noSession?: boolean): void;
|
|
4
|
+
//# sourceMappingURL=summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../source/sessions/summary.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AA4BnD,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,SAAS,CAAC,EAAE,OAAO,GAClB,IAAI,CAIN;AAED,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,SAAS,CAAC,EAAE,OAAO,GAClB,IAAI,CAGN"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
function formatSummary(sessionManager, noSession) {
|
|
5
|
+
const sessionId = sessionManager.getSessionId();
|
|
6
|
+
const title = sessionManager.getTitle();
|
|
7
|
+
const lines = [
|
|
8
|
+
"",
|
|
9
|
+
"Session Summary",
|
|
10
|
+
` ID: ${sessionId}`,
|
|
11
|
+
...(title ? [` Title: ${title}`] : []),
|
|
12
|
+
];
|
|
13
|
+
// Only show file path and resume command if session is being saved
|
|
14
|
+
if (!noSession) {
|
|
15
|
+
const filePath = sessionManager.getSessionFilePath();
|
|
16
|
+
lines.push(` File: ${filePath}`);
|
|
17
|
+
lines.push(` Resume: acai --resume ${sessionId}`);
|
|
18
|
+
}
|
|
19
|
+
lines.push("");
|
|
20
|
+
return lines.join("\n");
|
|
21
|
+
}
|
|
22
|
+
export function writeExitSummary(sessionManager, noSession) {
|
|
23
|
+
const summary = formatSummary(sessionManager, noSession);
|
|
24
|
+
const summaryPath = join(tmpdir(), "acai-exit-summary.txt");
|
|
25
|
+
writeFileSync(summaryPath, summary, "utf-8");
|
|
26
|
+
}
|
|
27
|
+
export function printExitSummary(sessionManager, noSession) {
|
|
28
|
+
const summary = formatSummary(sessionManager, noSession);
|
|
29
|
+
process.stderr.write(summary);
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface Skill {
|
|
2
|
+
name: string;
|
|
3
|
+
description: string;
|
|
4
|
+
filePath: string;
|
|
5
|
+
baseDir: string;
|
|
6
|
+
source: string;
|
|
7
|
+
userInvocable: boolean;
|
|
8
|
+
disableModelInvocation: boolean;
|
|
9
|
+
allowedTools?: string;
|
|
10
|
+
arguments?: string;
|
|
11
|
+
examples?: string[];
|
|
12
|
+
}
|
|
13
|
+
interface LoadSkillsFromDirOptions {
|
|
14
|
+
dir: string;
|
|
15
|
+
source: string;
|
|
16
|
+
useColonPath?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function loadSkillsFromDir(options: LoadSkillsFromDirOptions, subdir?: string): Promise<Skill[]>;
|
|
19
|
+
export declare class Skills {
|
|
20
|
+
private skills;
|
|
21
|
+
constructor(skills: Skill[]);
|
|
22
|
+
getAll(): Skill[];
|
|
23
|
+
getUserInvocable(): Skill[];
|
|
24
|
+
getModelInvocable(): Skill[];
|
|
25
|
+
}
|
|
26
|
+
export declare function loadSkills(): Promise<Skills>;
|
|
27
|
+
export declare function formatSkillsForPrompt(skills: Skill[]): string;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/skills/index.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,OAAO,CAAC;IACvB,sBAAsB,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,UAAU,wBAAwB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAqRD,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,EACjC,MAAM,SAAK,GACV,OAAO,CAAC,KAAK,EAAE,CAAC,CASlB;AAED,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAU;gBAEZ,MAAM,EAAE,KAAK,EAAE;IAI3B,MAAM,IAAI,KAAK,EAAE;IAIjB,gBAAgB,IAAI,KAAK,EAAE;IAI3B,iBAAiB,IAAI,KAAK,EAAE;CAG7B;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAsFlD;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAgC7D"}
|