@travisennis/acai 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +186 -17
- package/bin/acai-wrapper.js +26 -0
- package/dist/agent/index.d.ts +15 -2
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +202 -174
- package/dist/api/exa/index.js +1 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +40 -7
- package/dist/commands/add-directory-command.d.ts +1 -1
- package/dist/commands/add-directory-command.d.ts.map +1 -1
- package/dist/commands/add-directory-command.js +1 -32
- package/dist/commands/application-log-command.d.ts +1 -1
- package/dist/commands/application-log-command.d.ts.map +1 -1
- package/dist/commands/application-log-command.js +2 -38
- package/dist/commands/clear-command.d.ts +1 -1
- package/dist/commands/clear-command.d.ts.map +1 -1
- package/dist/commands/clear-command.js +1 -5
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +0 -9
- package/dist/commands/context-command.d.ts +1 -1
- package/dist/commands/context-command.d.ts.map +1 -1
- package/dist/commands/context-command.js +13 -72
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +0 -19
- package/dist/commands/edit-command.d.ts +1 -1
- package/dist/commands/edit-command.d.ts.map +1 -1
- package/dist/commands/edit-command.js +3 -49
- package/dist/commands/edit-prompt-command.d.ts +1 -1
- package/dist/commands/edit-prompt-command.d.ts.map +1 -1
- package/dist/commands/edit-prompt-command.js +1 -26
- package/dist/commands/exit-command.d.ts +1 -4
- package/dist/commands/exit-command.d.ts.map +1 -1
- package/dist/commands/exit-command.js +2 -18
- package/dist/commands/files-command.d.ts +1 -1
- package/dist/commands/files-command.d.ts.map +1 -1
- package/dist/commands/files-command.js +1 -54
- package/dist/commands/generate-rules-command.d.ts +1 -1
- package/dist/commands/generate-rules-command.d.ts.map +1 -1
- package/dist/commands/generate-rules-command.js +18 -60
- package/dist/commands/handoff-command.d.ts.map +1 -1
- package/dist/commands/handoff-command.js +0 -11
- package/dist/commands/health-command.d.ts +1 -1
- package/dist/commands/health-command.d.ts.map +1 -1
- package/dist/commands/health-command.js +8 -103
- package/dist/commands/help-command.d.ts +1 -1
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +6 -14
- package/dist/commands/history-command.d.ts +1 -1
- package/dist/commands/history-command.d.ts.map +1 -1
- package/dist/commands/history-command.js +30 -106
- package/dist/commands/init-command.d.ts +1 -1
- package/dist/commands/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +4 -23
- package/dist/commands/last-log-command.d.ts +1 -1
- package/dist/commands/last-log-command.d.ts.map +1 -1
- package/dist/commands/last-log-command.js +1 -28
- package/dist/commands/list-directories-command.d.ts +1 -1
- package/dist/commands/list-directories-command.d.ts.map +1 -1
- package/dist/commands/list-directories-command.js +1 -14
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +55 -78
- package/dist/commands/manager.d.ts +1 -8
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +7 -42
- package/dist/commands/model-command.d.ts +0 -22
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +5 -126
- package/dist/commands/paste-command.d.ts +1 -1
- package/dist/commands/paste-command.d.ts.map +1 -1
- package/dist/commands/paste-command.js +1 -79
- package/dist/commands/pickup-command.d.ts.map +1 -1
- package/dist/commands/pickup-command.js +3 -55
- package/dist/commands/prompt-command.d.ts +19 -1
- package/dist/commands/prompt-command.d.ts.map +1 -1
- package/dist/commands/prompt-command.js +172 -194
- package/dist/commands/remove-directory-command.d.ts +1 -1
- package/dist/commands/remove-directory-command.d.ts.map +1 -1
- package/dist/commands/remove-directory-command.js +1 -33
- package/dist/commands/reset-command.d.ts +1 -1
- package/dist/commands/reset-command.d.ts.map +1 -1
- package/dist/commands/reset-command.js +3 -11
- package/dist/commands/rules-command.d.ts +1 -1
- package/dist/commands/rules-command.d.ts.map +1 -1
- package/dist/commands/rules-command.js +1 -63
- package/dist/commands/save-command.d.ts +1 -1
- package/dist/commands/save-command.d.ts.map +1 -1
- package/dist/commands/save-command.js +1 -8
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +1 -48
- package/dist/commands/types.d.ts +0 -3
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/usage-command.d.ts +1 -1
- package/dist/commands/usage-command.d.ts.map +1 -1
- package/dist/commands/usage-command.js +5 -16
- package/dist/config.d.ts +17 -6
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +86 -53
- package/dist/execution/index.d.ts +17 -2
- package/dist/execution/index.d.ts.map +1 -1
- package/dist/execution/index.js +62 -20
- package/dist/formatting.d.ts +19 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +54 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +212 -153
- package/dist/messages.d.ts +3 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +67 -3
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +0 -7
- package/dist/models/deepseek-provider.d.ts.map +1 -1
- package/dist/models/deepseek-provider.js +0 -2
- package/dist/models/google-provider.d.ts.map +1 -1
- package/dist/models/google-provider.js +0 -3
- package/dist/models/groq-provider.d.ts.map +1 -1
- package/dist/models/groq-provider.js +0 -1
- package/dist/models/openai-provider.d.ts.map +1 -1
- package/dist/models/openai-provider.js +0 -4
- package/dist/models/openrouter-provider.d.ts +10 -9
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +82 -88
- package/dist/models/providers.d.ts +4 -14
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +1 -57
- package/dist/models/xai-provider.d.ts.map +1 -1
- package/dist/models/xai-provider.js +0 -2
- package/dist/prompts.d.ts +9 -4
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +427 -99
- package/dist/repl/project-status-line.d.ts +1 -0
- package/dist/repl/project-status-line.d.ts.map +1 -1
- package/dist/repl/project-status-line.js +57 -27
- package/dist/repl-new.d.ts +0 -2
- package/dist/repl-new.d.ts.map +1 -1
- package/dist/repl-new.js +34 -54
- package/dist/skills.d.ts +20 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +192 -0
- package/dist/terminal/control.d.ts +55 -0
- package/dist/terminal/control.d.ts.map +1 -0
- package/dist/terminal/control.js +109 -0
- package/dist/terminal/default-theme.d.ts +1 -1
- package/dist/terminal/default-theme.d.ts.map +1 -1
- package/dist/terminal/default-theme.js +24 -28
- package/dist/terminal/formatting.d.ts +23 -25
- package/dist/terminal/formatting.d.ts.map +1 -1
- package/dist/terminal/formatting.js +35 -52
- package/dist/terminal/highlight/index.d.ts.map +1 -1
- package/dist/terminal/highlight/index.js +3 -6
- package/dist/terminal/highlight/theme.d.ts.map +1 -1
- package/dist/terminal/highlight/theme.js +2 -6
- package/dist/terminal/index.d.ts +2 -101
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +2 -464
- package/dist/terminal/markdown.js +7 -5
- package/dist/terminal/strip-ansi.js +4 -4
- package/dist/terminal/table/cell.d.ts +114 -0
- package/dist/terminal/table/cell.d.ts.map +1 -0
- package/dist/terminal/table/cell.js +407 -0
- package/dist/terminal/table/debug.d.ts +15 -0
- package/dist/terminal/table/debug.d.ts.map +1 -0
- package/dist/terminal/table/debug.js +32 -0
- package/dist/terminal/table/index.d.ts +3 -0
- package/dist/terminal/table/index.d.ts.map +1 -0
- package/dist/terminal/table/index.js +2 -0
- package/dist/terminal/table/layout-manager.d.ts +27 -0
- package/dist/terminal/table/layout-manager.d.ts.map +1 -0
- package/dist/terminal/table/layout-manager.js +257 -0
- package/dist/terminal/table/table.d.ts +9 -0
- package/dist/terminal/table/table.d.ts.map +1 -0
- package/dist/terminal/table/table.js +97 -0
- package/dist/terminal/table/utils.d.ts +63 -0
- package/dist/terminal/table/utils.d.ts.map +1 -0
- package/dist/terminal/table/utils.js +326 -0
- package/dist/tokens/threshold.d.ts +6 -21
- package/dist/tokens/threshold.d.ts.map +1 -1
- package/dist/tokens/threshold.js +13 -31
- package/dist/tools/advanced-edit-file.d.ts.map +1 -1
- package/dist/tools/advanced-edit-file.js +5 -1
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +19 -5
- package/dist/tools/bash.d.ts +3 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +204 -42
- package/dist/tools/batch.d.ts +34 -0
- package/dist/tools/batch.d.ts.map +1 -0
- package/dist/tools/batch.js +174 -0
- package/dist/tools/code-interpreter.d.ts.map +1 -1
- package/dist/tools/code-interpreter.js +25 -9
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +9 -2
- package/dist/tools/directory-tree.d.ts +0 -6
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +29 -18
- package/dist/tools/dynamic-tool-loader.d.ts +0 -4
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +2 -2
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +16 -3
- package/dist/tools/glob.d.ts.map +1 -1
- package/dist/tools/glob.js +24 -13
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +40 -25
- package/dist/tools/index.d.ts +17 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +43 -1
- package/dist/tools/llm-edit-fixer.d.ts +0 -1
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -1
- package/dist/tools/llm-edit-fixer.js +14 -28
- package/dist/tools/move-file.d.ts.map +1 -1
- package/dist/tools/move-file.js +8 -1
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +32 -23
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +102 -45
- package/dist/tools/save-file.d.ts +4 -4
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +20 -2
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +7 -1
- package/dist/tools/types.d.ts +5 -1
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +1 -1
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +24 -9
- package/dist/tui/components/assistant-message.js +1 -1
- package/dist/tui/components/box.d.ts +20 -0
- package/dist/tui/components/box.d.ts.map +1 -0
- package/dist/tui/components/box.js +81 -0
- package/dist/tui/components/editor.d.ts +60 -5
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +577 -115
- package/dist/tui/components/footer.d.ts +0 -12
- package/dist/tui/components/footer.d.ts.map +1 -1
- package/dist/tui/components/footer.js +19 -7
- package/dist/tui/components/header.d.ts +21 -0
- package/dist/tui/components/header.d.ts.map +1 -0
- package/dist/tui/components/header.js +63 -0
- package/dist/tui/components/loader.d.ts +5 -1
- package/dist/tui/components/loader.d.ts.map +1 -1
- package/dist/tui/components/loader.js +2 -2
- package/dist/tui/components/markdown.d.ts +26 -23
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +107 -54
- package/dist/tui/components/modal.d.ts +0 -11
- package/dist/tui/components/modal.d.ts.map +1 -1
- package/dist/tui/components/modal.js +0 -29
- package/dist/tui/components/progress-bar.d.ts +19 -0
- package/dist/tui/components/progress-bar.d.ts.map +1 -0
- package/dist/tui/components/progress-bar.js +78 -0
- package/dist/tui/components/prompt-status.d.ts +2 -1
- package/dist/tui/components/prompt-status.d.ts.map +1 -1
- package/dist/tui/components/prompt-status.js +7 -2
- package/dist/tui/components/select-list.d.ts +27 -1
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +93 -29
- package/dist/tui/components/spacer.d.ts +1 -1
- package/dist/tui/components/spacer.d.ts.map +1 -1
- package/dist/tui/components/spacer.js +2 -2
- package/dist/tui/components/table.d.ts +27 -0
- package/dist/tui/components/table.d.ts.map +1 -0
- package/dist/tui/components/table.js +125 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -1
- package/dist/tui/components/thinking-block.js +4 -1
- package/dist/tui/components/tool-execution.d.ts +8 -4
- package/dist/tui/components/tool-execution.d.ts.map +1 -1
- package/dist/tui/components/tool-execution.js +88 -80
- package/dist/tui/components/user-message.d.ts.map +1 -1
- package/dist/tui/components/user-message.js +6 -4
- package/dist/tui/index.d.ts +9 -5
- package/dist/tui/index.d.ts.map +1 -1
- package/dist/tui/index.js +5 -1
- package/dist/tui/terminal.d.ts +2 -1
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +28 -38
- package/dist/tui/tui.d.ts +2 -0
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +53 -33
- package/dist/tui/utils.d.ts +5 -0
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +81 -1
- package/dist/{tools/bash-utils.d.ts → utils/bash.d.ts} +3 -3
- package/dist/utils/bash.d.ts.map +1 -0
- package/dist/{tools/bash-utils.js → utils/bash.js} +22 -11
- package/dist/utils/{filesystem.d.ts → filesystem/operations.d.ts} +1 -1
- package/dist/utils/filesystem/operations.d.ts.map +1 -0
- package/dist/{tools/filesystem-utils.d.ts → utils/filesystem/security.d.ts} +3 -2
- package/dist/utils/filesystem/security.d.ts.map +1 -0
- package/dist/{tools/filesystem-utils.js → utils/filesystem/security.js} +62 -4
- package/dist/utils/funcs.d.ts +6 -0
- package/dist/utils/funcs.d.ts.map +1 -0
- package/dist/utils/funcs.js +6 -0
- package/dist/{tools/git-utils.d.ts → utils/git.d.ts} +1 -1
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/{tools/git-utils.js → utils/git.js} +0 -6
- package/dist/utils/glob.js +1 -1
- package/dist/utils/{zod-utils.d.ts → zod.d.ts} +1 -1
- package/dist/utils/zod.d.ts.map +1 -0
- package/package.json +17 -17
- package/dist/agent/manual-loop.d.ts +0 -41
- package/dist/agent/manual-loop.d.ts.map +0 -1
- package/dist/agent/manual-loop.js +0 -278
- package/dist/repl/display-tool-messages.d.ts +0 -4
- package/dist/repl/display-tool-messages.d.ts.map +0 -1
- package/dist/repl/display-tool-messages.js +0 -58
- package/dist/repl/display-tool-use.d.ts +0 -14
- package/dist/repl/display-tool-use.d.ts.map +0 -1
- package/dist/repl/display-tool-use.js +0 -63
- package/dist/repl/get-prompt-header.d.ts +0 -8
- package/dist/repl/get-prompt-header.d.ts.map +0 -1
- package/dist/repl/get-prompt-header.js +0 -9
- package/dist/repl/prompt.d.ts +0 -21
- package/dist/repl/prompt.d.ts.map +0 -1
- package/dist/repl/prompt.js +0 -244
- package/dist/repl.d.ts +0 -29
- package/dist/repl.d.ts.map +0 -1
- package/dist/repl.js +0 -218
- package/dist/terminal/checkbox-prompt.d.ts +0 -36
- package/dist/terminal/checkbox-prompt.d.ts.map +0 -1
- package/dist/terminal/checkbox-prompt.js +0 -368
- package/dist/terminal/editor-prompt.d.ts +0 -10
- package/dist/terminal/editor-prompt.d.ts.map +0 -1
- package/dist/terminal/editor-prompt.js +0 -61
- package/dist/terminal/errors.d.ts +0 -19
- package/dist/terminal/errors.d.ts.map +0 -1
- package/dist/terminal/errors.js +0 -37
- package/dist/terminal/input-prompt.d.ts +0 -17
- package/dist/terminal/input-prompt.d.ts.map +0 -1
- package/dist/terminal/input-prompt.js +0 -181
- package/dist/terminal/search-prompt.d.ts +0 -20
- package/dist/terminal/search-prompt.d.ts.map +0 -1
- package/dist/terminal/search-prompt.js +0 -280
- package/dist/terminal/types.d.ts +0 -35
- package/dist/terminal/types.d.ts.map +0 -1
- package/dist/terminal/types.js +0 -1
- package/dist/tools/bash-utils.d.ts.map +0 -1
- package/dist/tools/filesystem-utils.d.ts.map +0 -1
- package/dist/tools/git-utils.d.ts.map +0 -1
- package/dist/utils/filesystem.d.ts.map +0 -1
- package/dist/utils/zod-utils.d.ts.map +0 -1
- /package/dist/utils/{filesystem.js → filesystem/operations.js} +0 -0
- /package/dist/utils/{zod-utils.js → zod.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
import { text } from "node:stream/consumers";
|
|
3
5
|
import { parseArgs } from "node:util";
|
|
4
6
|
import { asyncTry } from "@travisennis/stdlib/try";
|
|
@@ -6,25 +8,30 @@ import { isDefined } from "@travisennis/stdlib/typeguards";
|
|
|
6
8
|
import { Agent } from "./agent/index.js";
|
|
7
9
|
import { Cli } from "./cli.js";
|
|
8
10
|
import { CommandManager } from "./commands/manager.js";
|
|
9
|
-
import { config } from "./config.js";
|
|
11
|
+
import { config, } from "./config.js";
|
|
10
12
|
import { logger } from "./logger.js";
|
|
11
13
|
import { MessageHistory } from "./messages.js";
|
|
12
14
|
import { ModelManager } from "./models/manager.js";
|
|
13
15
|
import { isSupportedModel } from "./models/providers.js";
|
|
14
16
|
import { PromptManager } from "./prompts/manager.js";
|
|
15
17
|
import { systemPrompt } from "./prompts.js";
|
|
16
|
-
import { Repl } from "./repl.js";
|
|
17
18
|
import { NewRepl } from "./repl-new.js";
|
|
18
|
-
import {
|
|
19
|
+
import { setTerminalTitle } from "./terminal/formatting.js";
|
|
19
20
|
import { select } from "./terminal/select-prompt.js";
|
|
20
21
|
import { TokenCounter } from "./tokens/counter.js";
|
|
21
22
|
import { TokenTracker } from "./tokens/tracker.js";
|
|
22
|
-
import { initAgents, initTools } from "./tools/index.js";
|
|
23
|
+
import { initAgents, initTools, } from "./tools/index.js";
|
|
23
24
|
import { getPackageVersion } from "./version.js";
|
|
24
25
|
// Create workspace context from CLI arguments
|
|
25
26
|
export function createWorkspaceContext(addDirArgs = []) {
|
|
26
27
|
const primaryDir = process.cwd();
|
|
27
|
-
const allowedDirs = [
|
|
28
|
+
const allowedDirs = [
|
|
29
|
+
primaryDir,
|
|
30
|
+
"/tmp",
|
|
31
|
+
config.getAccessibleLogDir(),
|
|
32
|
+
path.join(os.homedir(), ".acai"),
|
|
33
|
+
...addDirArgs,
|
|
34
|
+
];
|
|
28
35
|
// Remove duplicates while preserving order
|
|
29
36
|
const uniqueDirs = allowedDirs.filter((dir, index, array) => array.indexOf(dir) === index);
|
|
30
37
|
return {
|
|
@@ -42,7 +49,8 @@ Options
|
|
|
42
49
|
--continue Load the most recent conversation
|
|
43
50
|
--resume Select a recent conversation to resume
|
|
44
51
|
--add-dir Add additional working directory (can be used multiple times)
|
|
45
|
-
--
|
|
52
|
+
--no-skills Disable skills discovery and loading
|
|
53
|
+
|
|
46
54
|
--help, -h Show help
|
|
47
55
|
--version, -v Show version
|
|
48
56
|
|
|
@@ -58,7 +66,7 @@ const parsed = parseArgs({
|
|
|
58
66
|
continue: { type: "boolean", default: false },
|
|
59
67
|
resume: { type: "boolean", default: false },
|
|
60
68
|
"add-dir": { type: "string", multiple: true },
|
|
61
|
-
"
|
|
69
|
+
"no-skills": { type: "boolean", default: false },
|
|
62
70
|
help: { type: "boolean", short: "h" },
|
|
63
71
|
version: { type: "boolean", short: "v" },
|
|
64
72
|
},
|
|
@@ -76,8 +84,56 @@ const workspace = createWorkspaceContext(flags["add-dir"]);
|
|
|
76
84
|
export function handleError(error) {
|
|
77
85
|
logger.error({ error: error }, error.message);
|
|
78
86
|
}
|
|
79
|
-
|
|
80
|
-
|
|
87
|
+
// Configuration constants
|
|
88
|
+
const DEFAULT_HISTORY_LIMIT = 10;
|
|
89
|
+
const CONTINUE_HISTORY_LIMIT = 1;
|
|
90
|
+
// Helper functions for main()
|
|
91
|
+
async function initializeAppState(appConfig, initialPromptInput, stdInPrompt, hasContinueOrResume) {
|
|
92
|
+
const appDir = config.app;
|
|
93
|
+
// Parallelize independent async operations
|
|
94
|
+
const [messageHistoryDir, modelManager] = await Promise.all([
|
|
95
|
+
appDir.ensurePath("message-history"),
|
|
96
|
+
initializeModelManager(appDir),
|
|
97
|
+
]);
|
|
98
|
+
// Initialize synchronous components
|
|
99
|
+
const tokenTracker = new TokenTracker();
|
|
100
|
+
const tokenCounter = new TokenCounter();
|
|
101
|
+
// Initialize dependent components
|
|
102
|
+
const messageHistory = await initializeMessageHistory(messageHistoryDir, modelManager, tokenTracker);
|
|
103
|
+
// Handle conversation history loading
|
|
104
|
+
await handleConversationHistory(messageHistory, messageHistoryDir, hasContinueOrResume);
|
|
105
|
+
// Setup prompt manager
|
|
106
|
+
const promptManager = new PromptManager(tokenCounter);
|
|
107
|
+
if (!hasContinueOrResume && isDefined(initialPromptInput)) {
|
|
108
|
+
promptManager.set(initialPromptInput);
|
|
109
|
+
}
|
|
110
|
+
if (stdInPrompt) {
|
|
111
|
+
promptManager.addContext(stdInPrompt);
|
|
112
|
+
}
|
|
113
|
+
const promptHistory = [];
|
|
114
|
+
const commands = new CommandManager({
|
|
115
|
+
promptManager,
|
|
116
|
+
modelManager,
|
|
117
|
+
messageHistory,
|
|
118
|
+
tokenTracker,
|
|
119
|
+
config,
|
|
120
|
+
tokenCounter,
|
|
121
|
+
promptHistory,
|
|
122
|
+
workspace,
|
|
123
|
+
});
|
|
124
|
+
await commands.initializeCommmands();
|
|
125
|
+
return {
|
|
126
|
+
appConfig,
|
|
127
|
+
modelManager,
|
|
128
|
+
tokenTracker,
|
|
129
|
+
tokenCounter,
|
|
130
|
+
messageHistory,
|
|
131
|
+
promptManager,
|
|
132
|
+
promptHistory,
|
|
133
|
+
commands,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
async function handleEarlyExits() {
|
|
81
137
|
if (flags.version === true) {
|
|
82
138
|
console.info(getPackageVersion());
|
|
83
139
|
process.exit(0);
|
|
@@ -86,21 +142,21 @@ async function main() {
|
|
|
86
142
|
console.info(helpText);
|
|
87
143
|
process.exit(0);
|
|
88
144
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
function validateCliArguments() {
|
|
92
148
|
if (flags.continue === true && flags.resume === true) {
|
|
93
149
|
console.error("Cannot use --continue and --resume flags together.");
|
|
94
150
|
process.exit(1);
|
|
95
151
|
}
|
|
152
|
+
}
|
|
153
|
+
async function determineInitialPrompt() {
|
|
96
154
|
const hasContinueOrResume = flags.continue === true || flags.resume === true;
|
|
97
|
-
// --- Determine Initial Prompt (potential conflict) ---
|
|
98
155
|
const positionalPrompt = input.at(0);
|
|
99
156
|
let stdInPrompt;
|
|
100
157
|
// Check if there's data available on stdin
|
|
101
158
|
if (!process.stdin.isTTY) {
|
|
102
159
|
try {
|
|
103
|
-
// Non-TTY stdin means data is being piped in
|
|
104
160
|
stdInPrompt = await text(process.stdin);
|
|
105
161
|
}
|
|
106
162
|
catch (error) {
|
|
@@ -116,8 +172,9 @@ async function main() {
|
|
|
116
172
|
console.error("Cannot use --continue or --resume with an initial prompt.");
|
|
117
173
|
process.exit(1);
|
|
118
174
|
}
|
|
119
|
-
|
|
120
|
-
|
|
175
|
+
return { initialPromptInput, stdInPrompt, hasContinueOrResume };
|
|
176
|
+
}
|
|
177
|
+
async function initializeModelManager(appDir) {
|
|
121
178
|
const chosenModel = isSupportedModel(flags.model)
|
|
122
179
|
? flags.model
|
|
123
180
|
: "openrouter:glm-4.6";
|
|
@@ -126,37 +183,40 @@ async function main() {
|
|
|
126
183
|
});
|
|
127
184
|
modelManager.setModel("repl", chosenModel);
|
|
128
185
|
modelManager.setModel("cli", chosenModel);
|
|
129
|
-
modelManager.setModel("title-conversation",
|
|
130
|
-
modelManager.setModel("conversation-summarizer",
|
|
131
|
-
modelManager.setModel("tool-repair",
|
|
132
|
-
modelManager.setModel("conversation-analyzer",
|
|
186
|
+
modelManager.setModel("title-conversation", chosenModel);
|
|
187
|
+
modelManager.setModel("conversation-summarizer", chosenModel);
|
|
188
|
+
modelManager.setModel("tool-repair", chosenModel);
|
|
189
|
+
modelManager.setModel("conversation-analyzer", chosenModel);
|
|
133
190
|
modelManager.setModel("init-project", chosenModel);
|
|
134
|
-
modelManager.setModel("task-agent",
|
|
191
|
+
modelManager.setModel("task-agent", chosenModel);
|
|
135
192
|
modelManager.setModel("handoff-agent", chosenModel);
|
|
136
|
-
modelManager.setModel("edit-fix",
|
|
137
|
-
|
|
138
|
-
|
|
193
|
+
modelManager.setModel("edit-fix", chosenModel);
|
|
194
|
+
return modelManager;
|
|
195
|
+
}
|
|
196
|
+
async function initializeMessageHistory(messageHistoryDir, modelManager, tokenTracker) {
|
|
139
197
|
const messageHistory = new MessageHistory({
|
|
140
198
|
stateDir: messageHistoryDir,
|
|
141
199
|
modelManager,
|
|
142
200
|
tokenTracker,
|
|
143
201
|
});
|
|
144
|
-
messageHistory.on("update-title", (title) =>
|
|
202
|
+
messageHistory.on("update-title", (title) => setTerminalTitle(title));
|
|
203
|
+
return messageHistory;
|
|
204
|
+
}
|
|
205
|
+
async function handleConversationHistory(messageHistory, messageHistoryDir, _hasContinueOrResume) {
|
|
145
206
|
if (flags.continue === true) {
|
|
146
|
-
const histories = await MessageHistory.load(messageHistoryDir,
|
|
207
|
+
const histories = await MessageHistory.load(messageHistoryDir, CONTINUE_HISTORY_LIMIT);
|
|
147
208
|
const latestHistory = histories.at(0);
|
|
148
209
|
if (latestHistory) {
|
|
149
210
|
messageHistory.restore(latestHistory);
|
|
150
211
|
console.info(`Resuming conversation: ${latestHistory.title}`);
|
|
151
|
-
|
|
152
|
-
terminal.setTitle(latestHistory.title || `acai: ${process.cwd()}`);
|
|
212
|
+
setTerminalTitle(latestHistory.title || `acai: ${process.cwd()}`);
|
|
153
213
|
}
|
|
154
214
|
else {
|
|
155
215
|
logger.info("No previous conversation found to continue.");
|
|
156
216
|
}
|
|
157
217
|
}
|
|
158
218
|
else if (flags.resume === true) {
|
|
159
|
-
const histories = await MessageHistory.load(messageHistoryDir,
|
|
219
|
+
const histories = await MessageHistory.load(messageHistoryDir, DEFAULT_HISTORY_LIMIT);
|
|
160
220
|
if (histories.length > 0) {
|
|
161
221
|
try {
|
|
162
222
|
const choice = await select({
|
|
@@ -171,23 +231,19 @@ async function main() {
|
|
|
171
231
|
if (selectedHistory) {
|
|
172
232
|
messageHistory.restore(selectedHistory);
|
|
173
233
|
logger.info(`Resuming conversation: ${selectedHistory.title}`);
|
|
174
|
-
|
|
175
|
-
terminal.setTitle(selectedHistory.title || `acai: ${process.cwd()}`);
|
|
234
|
+
setTerminalTitle(selectedHistory.title || `acai: ${process.cwd()}`);
|
|
176
235
|
}
|
|
177
236
|
else {
|
|
178
|
-
// This case should theoretically not happen if choice is valid
|
|
179
237
|
logger.error("Selected history index out of bounds.");
|
|
180
238
|
}
|
|
181
239
|
}
|
|
182
240
|
catch (error) {
|
|
183
|
-
// Handle Ctrl-C cancellation
|
|
184
241
|
if (error instanceof Error &&
|
|
185
242
|
"isCanceled" in error &&
|
|
186
243
|
error.isCanceled === true) {
|
|
187
244
|
logger.info("Resume selection cancelled.");
|
|
188
245
|
}
|
|
189
246
|
else {
|
|
190
|
-
// Re-throw other errors
|
|
191
247
|
throw error;
|
|
192
248
|
}
|
|
193
249
|
}
|
|
@@ -196,131 +252,134 @@ async function main() {
|
|
|
196
252
|
logger.info("No previous conversations found to resume.");
|
|
197
253
|
}
|
|
198
254
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const commands = new CommandManager({
|
|
209
|
-
promptManager,
|
|
210
|
-
modelManager,
|
|
211
|
-
terminal,
|
|
212
|
-
messageHistory,
|
|
213
|
-
tokenTracker,
|
|
214
|
-
config,
|
|
215
|
-
tokenCounter,
|
|
216
|
-
promptHistory,
|
|
255
|
+
}
|
|
256
|
+
async function runCliMode(state) {
|
|
257
|
+
const skillsEnabled = !flags["no-skills"] && (await config.getSkillsEnabled());
|
|
258
|
+
const cliProcess = new Cli({
|
|
259
|
+
promptManager: state.promptManager,
|
|
260
|
+
messageHistory: state.messageHistory,
|
|
261
|
+
modelManager: state.modelManager,
|
|
262
|
+
tokenTracker: state.tokenTracker,
|
|
263
|
+
tokenCounter: state.tokenCounter,
|
|
217
264
|
workspace,
|
|
265
|
+
skillsEnabled,
|
|
218
266
|
});
|
|
219
|
-
await
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
promptManager,
|
|
223
|
-
config: appConfig,
|
|
224
|
-
messageHistory,
|
|
225
|
-
modelManager,
|
|
226
|
-
tokenTracker,
|
|
227
|
-
tokenCounter,
|
|
228
|
-
workspace,
|
|
229
|
-
});
|
|
230
|
-
return (await asyncTry(cliProcess.run())).recover(handleError);
|
|
231
|
-
}
|
|
267
|
+
(await asyncTry(cliProcess.run())).recover(handleError);
|
|
268
|
+
}
|
|
269
|
+
async function runReplMode(state) {
|
|
232
270
|
const agent = new Agent({
|
|
233
|
-
messageHistory,
|
|
234
|
-
modelManager,
|
|
235
|
-
tokenTracker,
|
|
271
|
+
messageHistory: state.messageHistory,
|
|
272
|
+
modelManager: state.modelManager,
|
|
273
|
+
tokenTracker: state.tokenTracker,
|
|
236
274
|
});
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
agent.abort();
|
|
261
|
-
});
|
|
262
|
-
// Render any existing messages (from --continue mode)
|
|
263
|
-
// repl.renderInitialMessages(agent.state);
|
|
264
|
-
// Initialize tools once outside the loop - all models support tool calling
|
|
265
|
-
const coreTools = await initTools({
|
|
266
|
-
tokenCounter,
|
|
267
|
-
workspace,
|
|
268
|
-
modelManager,
|
|
269
|
-
tokenTracker,
|
|
270
|
-
});
|
|
271
|
-
const agentTools = await initAgents({
|
|
272
|
-
terminal,
|
|
273
|
-
modelManager,
|
|
274
|
-
tokenTracker,
|
|
275
|
-
tokenCounter,
|
|
276
|
-
workspace,
|
|
277
|
-
});
|
|
278
|
-
const completeToolDefs = {
|
|
279
|
-
...coreTools.toolDefs,
|
|
280
|
-
...agentTools.toolDefs,
|
|
281
|
-
};
|
|
282
|
-
const tools = {
|
|
283
|
-
toolDefs: completeToolDefs,
|
|
284
|
-
executors: new Map([...coreTools.executors, ...agentTools.executors]),
|
|
285
|
-
};
|
|
286
|
-
// Interactive loop
|
|
287
|
-
while (true) {
|
|
288
|
-
const userInput = await repl.getUserInput();
|
|
289
|
-
// Process the message - agent.prompt will add user message and trigger state updates
|
|
290
|
-
try {
|
|
291
|
-
const results = agent.run({
|
|
292
|
-
systemPrompt: await systemPrompt(),
|
|
293
|
-
input: userInput,
|
|
294
|
-
toolDefs: tools.toolDefs,
|
|
295
|
-
executors: tools.executors,
|
|
296
|
-
abortSignal: agent.abortSignal,
|
|
297
|
-
});
|
|
298
|
-
for await (const result of results) {
|
|
299
|
-
repl.handle(result, agent.state);
|
|
300
|
-
}
|
|
301
|
-
messageHistory.save();
|
|
302
|
-
}
|
|
303
|
-
catch (_error) {
|
|
304
|
-
// Display error in the TUI by adding an error message to the chat
|
|
305
|
-
// repl.showError((error as Error).message || "Unknown error occurred");
|
|
306
|
-
}
|
|
275
|
+
const repl = new NewRepl({
|
|
276
|
+
agent,
|
|
277
|
+
promptManager: state.promptManager,
|
|
278
|
+
config: state.appConfig,
|
|
279
|
+
messageHistory: state.messageHistory,
|
|
280
|
+
modelManager: state.modelManager,
|
|
281
|
+
tokenTracker: state.tokenTracker,
|
|
282
|
+
commands: state.commands,
|
|
283
|
+
tokenCounter: state.tokenCounter,
|
|
284
|
+
promptHistory: state.promptHistory,
|
|
285
|
+
workspace,
|
|
286
|
+
});
|
|
287
|
+
// Initialize TUI
|
|
288
|
+
await repl.init();
|
|
289
|
+
state.messageHistory.on("clear-history", () => {
|
|
290
|
+
logger.info("Resetting agent state.");
|
|
291
|
+
agent.resetState();
|
|
292
|
+
repl.rerender();
|
|
293
|
+
});
|
|
294
|
+
// Set interrupt callback
|
|
295
|
+
repl.setInterruptCallback(() => {
|
|
296
|
+
try {
|
|
297
|
+
state.messageHistory.save();
|
|
307
298
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
tokenCounter,
|
|
318
|
-
promptHistory,
|
|
299
|
+
catch (error) {
|
|
300
|
+
// Log but don't throw - we still want to abort the agent
|
|
301
|
+
logger.warn({ error }, "Failed to save message history on interrupt");
|
|
302
|
+
}
|
|
303
|
+
agent.abort();
|
|
304
|
+
});
|
|
305
|
+
// Initialize tools
|
|
306
|
+
const coreTools = await initTools({
|
|
307
|
+
tokenCounter: state.tokenCounter,
|
|
319
308
|
workspace,
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
: false,
|
|
309
|
+
modelManager: state.modelManager,
|
|
310
|
+
tokenTracker: state.tokenTracker,
|
|
323
311
|
});
|
|
324
|
-
|
|
312
|
+
const agentTools = await initAgents({
|
|
313
|
+
modelManager: state.modelManager,
|
|
314
|
+
tokenTracker: state.tokenTracker,
|
|
315
|
+
tokenCounter: state.tokenCounter,
|
|
316
|
+
workspace,
|
|
317
|
+
});
|
|
318
|
+
const completeToolDefs = {
|
|
319
|
+
...coreTools.toolDefs,
|
|
320
|
+
...agentTools.toolDefs,
|
|
321
|
+
};
|
|
322
|
+
const tools = {
|
|
323
|
+
toolDefs: completeToolDefs,
|
|
324
|
+
executors: new Map([...coreTools.executors, ...agentTools.executors]),
|
|
325
|
+
};
|
|
326
|
+
// Interactive loop
|
|
327
|
+
while (true) {
|
|
328
|
+
const userInput = await repl.getUserInput();
|
|
329
|
+
const projectConfig = await config.getConfig();
|
|
330
|
+
const activeTools = projectConfig.tools.activeTools;
|
|
331
|
+
const skillsEnabled = !flags["no-skills"] && (projectConfig.skills?.enabled ?? true);
|
|
332
|
+
try {
|
|
333
|
+
const results = agent.run({
|
|
334
|
+
systemPrompt: await systemPrompt({
|
|
335
|
+
type: projectConfig.systemPromptType,
|
|
336
|
+
activeTools,
|
|
337
|
+
allowedDirs: workspace.allowedDirs,
|
|
338
|
+
skillsEnabled,
|
|
339
|
+
}),
|
|
340
|
+
input: userInput,
|
|
341
|
+
toolDefs: tools.toolDefs,
|
|
342
|
+
activeTools,
|
|
343
|
+
executors: tools.executors,
|
|
344
|
+
abortSignal: agent.abortSignal,
|
|
345
|
+
});
|
|
346
|
+
for await (const result of results) {
|
|
347
|
+
repl.handle(result, agent.state);
|
|
348
|
+
}
|
|
349
|
+
state.messageHistory.save();
|
|
350
|
+
}
|
|
351
|
+
catch (_error) {
|
|
352
|
+
// Display error in the TUI by adding an error message to the chat
|
|
353
|
+
// repl.showError((error as Error).message || "Unknown error occurred");
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
async function main() {
|
|
358
|
+
try {
|
|
359
|
+
const appConfig = await config.ensureDefaultConfig("acai");
|
|
360
|
+
// Note: SIGINT/SIGTERM handlers are set up by CLI and REPL components
|
|
361
|
+
// as needed. We don't set a global handler here to avoid conflicts.
|
|
362
|
+
// Handle early exits
|
|
363
|
+
if (await handleEarlyExits())
|
|
364
|
+
return;
|
|
365
|
+
// Validate CLI arguments
|
|
366
|
+
validateCliArguments();
|
|
367
|
+
// Determine initial prompt
|
|
368
|
+
const { initialPromptInput, stdInPrompt, hasContinueOrResume } = await determineInitialPrompt();
|
|
369
|
+
// Initialize application state
|
|
370
|
+
const state = await initializeAppState(appConfig, initialPromptInput, stdInPrompt, hasContinueOrResume);
|
|
371
|
+
// Set terminal title after all validation is complete
|
|
372
|
+
setTerminalTitle(`acai: ${workspace.primaryDir}`);
|
|
373
|
+
// Handle CLI mode if initial prompt provided
|
|
374
|
+
if (isDefined(initialPromptInput)) {
|
|
375
|
+
return await runCliMode(state);
|
|
376
|
+
}
|
|
377
|
+
// Setup REPL mode
|
|
378
|
+
return await runReplMode(state);
|
|
379
|
+
}
|
|
380
|
+
catch (error) {
|
|
381
|
+
handleError(error);
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
325
384
|
}
|
|
326
385
|
main();
|
package/dist/messages.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ export declare class MessageHistory extends EventEmitter<MessageHistoryEvents> {
|
|
|
31
31
|
private createdAt;
|
|
32
32
|
private updatedAt;
|
|
33
33
|
private stateDir;
|
|
34
|
+
private contextWindow;
|
|
34
35
|
private modelManager;
|
|
35
36
|
private tokenTracker;
|
|
36
37
|
constructor({ stateDir, modelManager, tokenTracker, }: {
|
|
@@ -42,6 +43,8 @@ export declare class MessageHistory extends EventEmitter<MessageHistoryEvents> {
|
|
|
42
43
|
private validMessage;
|
|
43
44
|
get(): ModelMessage[];
|
|
44
45
|
clear(): void;
|
|
46
|
+
setContextWindow(contextWindow: number): void;
|
|
47
|
+
getContextWindow(): number;
|
|
45
48
|
appendUserMessage(msg: string): void;
|
|
46
49
|
appendUserMessage(msg: UserModelMessage): void;
|
|
47
50
|
appendAssistantMessage(msg: string): void;
|
package/dist/messages.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../source/messages.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../source/messages.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;AAEZ,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,SAAS,CAAC;AAExD,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EAAE,EACtC,MAAM,CAAC,EAAE,MAAM,GACd,gBAAgB,CAuBlB;AAcD;;;GAGG;AACH,KAAK,eAAe,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;AAEhE,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B,CAAC;AAUF,UAAU,oBAAoB;IAC5B,cAAc,EAAE,CAAC,MAAM,CAAC,CAAC;IACzB,eAAe,EAAE,EAAE,CAAC;CACrB;AAED,qBAAa,cAAe,SAAQ,YAAY,CAAC,oBAAoB,CAAC;IACpE,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAe;gBAEvB,EACV,QAAQ,EACR,YAAY,EACZ,YAAY,GACb,EAAE;QACD,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,YAAY,CAAC;QAC3B,YAAY,EAAE,YAAY,CAAC;KAC5B;IAcD,MAAM,CAAC,OAAO,EAAE,MAAM;IAStB,OAAO,CAAC,YAAY;IAoBpB,GAAG;IAIH,KAAK;IAML,gBAAgB,CAAC,aAAa,EAAE,MAAM;IAOtC,gBAAgB;IAIhB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IACpC,iBAAiB,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;IAmB9C,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IACzC,sBAAsB,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI;IAOxD,kBAAkB,CAAC,kBAAkB,EAAE,gBAAgB,EAAE;IAKzD,sBAAsB,CAAC,gBAAgB,EAAE,eAAe,EAAE;IAO1D,OAAO;IAID,IAAI;YA+DI,aAAa;IA6B3B,mBAAmB,IAAI,gBAAgB,GAAG,SAAS;IAOnD,kBAAkB,IAAI,gBAAgB,GAAG,SAAS;IAOlD;;;OAGG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;WA2ClB,IAAI,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,SAAK,GACT,OAAO,CAAC,mBAAmB,EAAE,CAAC;IAiGjC,OAAO,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;CAajD"}
|
package/dist/messages.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import EventEmitter from "node:events";
|
|
3
|
-
import { readdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { mkdir, readdir, readFile, rename, stat, unlink, writeFile, } from "node:fs/promises";
|
|
4
4
|
import { basename, join } from "node:path";
|
|
5
5
|
import { isString } from "@travisennis/stdlib/typeguards";
|
|
6
6
|
import { generateText, } from "ai";
|
|
7
|
+
import { logger } from "./logger.js";
|
|
7
8
|
export function createUserMessage(contentItems, prompt) {
|
|
8
9
|
const messageParts = [];
|
|
9
10
|
// Process content items (images and pre-defined texts)
|
|
@@ -45,6 +46,7 @@ export class MessageHistory extends EventEmitter {
|
|
|
45
46
|
createdAt;
|
|
46
47
|
updatedAt;
|
|
47
48
|
stateDir;
|
|
49
|
+
contextWindow;
|
|
48
50
|
modelManager;
|
|
49
51
|
tokenTracker;
|
|
50
52
|
constructor({ stateDir, modelManager, tokenTracker, }) {
|
|
@@ -56,6 +58,7 @@ export class MessageHistory extends EventEmitter {
|
|
|
56
58
|
this.createdAt = new Date();
|
|
57
59
|
this.updatedAt = new Date();
|
|
58
60
|
this.stateDir = stateDir;
|
|
61
|
+
this.contextWindow = 0;
|
|
59
62
|
this.modelManager = modelManager;
|
|
60
63
|
this.tokenTracker = tokenTracker;
|
|
61
64
|
}
|
|
@@ -87,8 +90,18 @@ export class MessageHistory extends EventEmitter {
|
|
|
87
90
|
}
|
|
88
91
|
clear() {
|
|
89
92
|
this.history.length = 0;
|
|
93
|
+
this.contextWindow = 0;
|
|
90
94
|
this.emit("clear-history");
|
|
91
95
|
}
|
|
96
|
+
setContextWindow(contextWindow) {
|
|
97
|
+
if (contextWindow < 0) {
|
|
98
|
+
throw new Error("Context window cannot be negative");
|
|
99
|
+
}
|
|
100
|
+
this.contextWindow = contextWindow;
|
|
101
|
+
}
|
|
102
|
+
getContextWindow() {
|
|
103
|
+
return this.contextWindow;
|
|
104
|
+
}
|
|
92
105
|
appendUserMessage(msg) {
|
|
93
106
|
const now = new Date();
|
|
94
107
|
const msgObj = isString(msg) ? createUserMessage([], msg) : msg;
|
|
@@ -126,6 +139,14 @@ export class MessageHistory extends EventEmitter {
|
|
|
126
139
|
const msgHistoryDir = this.stateDir;
|
|
127
140
|
const fileName = `message-history-${this.sessionId}.json`;
|
|
128
141
|
const filePath = join(msgHistoryDir, fileName);
|
|
142
|
+
const tempFilePath = `${filePath}.tmp`;
|
|
143
|
+
// Validate data before writing
|
|
144
|
+
if (!this.sessionId || this.sessionId.trim() === "") {
|
|
145
|
+
throw new Error("Cannot save: sessionId is empty");
|
|
146
|
+
}
|
|
147
|
+
if (!Array.isArray(this.history)) {
|
|
148
|
+
throw new Error("Cannot save: history is not an array");
|
|
149
|
+
}
|
|
129
150
|
const project = basename(process.cwd());
|
|
130
151
|
const output = {
|
|
131
152
|
project,
|
|
@@ -136,7 +157,35 @@ export class MessageHistory extends EventEmitter {
|
|
|
136
157
|
updatedAt: this.updatedAt,
|
|
137
158
|
messages: this.history,
|
|
138
159
|
};
|
|
139
|
-
|
|
160
|
+
try {
|
|
161
|
+
// Ensure directory exists
|
|
162
|
+
await mkdir(msgHistoryDir, { recursive: true });
|
|
163
|
+
// Write to temporary file first
|
|
164
|
+
await writeFile(tempFilePath, JSON.stringify(output, null, 2));
|
|
165
|
+
// Atomically rename to final file
|
|
166
|
+
await rename(tempFilePath, filePath);
|
|
167
|
+
logger.info(`Message history saved to ${filePath}`);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
// Clean up temp file if it exists
|
|
171
|
+
try {
|
|
172
|
+
await unlink(tempFilePath);
|
|
173
|
+
}
|
|
174
|
+
catch (_cleanupError) {
|
|
175
|
+
// Ignore cleanup errors
|
|
176
|
+
}
|
|
177
|
+
// Check if it's an ENOENT error from rename (temp file doesn't exist)
|
|
178
|
+
if (error instanceof Error &&
|
|
179
|
+
"code" in error &&
|
|
180
|
+
error.code === "ENOENT") {
|
|
181
|
+
logger.warn(`Temp file missing during save for ${filePath}, write may have been interrupted`);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
logger.error(error, `Failed to save message history to ${filePath}:`);
|
|
185
|
+
// Don't throw - just log. This is called from interrupt handlers
|
|
186
|
+
// and we don't want to crash the program on save failure.
|
|
187
|
+
}
|
|
188
|
+
}
|
|
140
189
|
}
|
|
141
190
|
async generateTitle(message) {
|
|
142
191
|
// Skip title generation if message is empty
|
|
@@ -232,7 +281,17 @@ export class MessageHistory extends EventEmitter {
|
|
|
232
281
|
const fileReadPromises = sortedFiles.map(async (fileName) => {
|
|
233
282
|
const filePath = join(stateDir, fileName);
|
|
234
283
|
try {
|
|
284
|
+
// Check file stats first to avoid reading empty files
|
|
285
|
+
const stats = await stat(filePath);
|
|
286
|
+
if (stats.size === 0) {
|
|
287
|
+
// Silently skip empty files - they're likely from interrupted saves
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
235
290
|
const content = await readFile(filePath, "utf-8");
|
|
291
|
+
// Skip files that only contain whitespace
|
|
292
|
+
if (content.trim().length === 0) {
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
236
295
|
const parsed = JSON.parse(content);
|
|
237
296
|
const result = parsed;
|
|
238
297
|
// Basic validation - ensure messages array exists
|
|
@@ -244,7 +303,12 @@ export class MessageHistory extends EventEmitter {
|
|
|
244
303
|
}
|
|
245
304
|
}
|
|
246
305
|
catch (error) {
|
|
247
|
-
|
|
306
|
+
// Only log unexpected errors, not empty/malformed JSON files
|
|
307
|
+
// which are common from interrupted saves
|
|
308
|
+
if (!(error instanceof SyntaxError) ||
|
|
309
|
+
!error.message.includes("Unexpected end of JSON input")) {
|
|
310
|
+
console.error(`Error reading or parsing file ${filePath}:`, error);
|
|
311
|
+
}
|
|
248
312
|
}
|
|
249
313
|
return null; // Return null for failed reads/parses
|
|
250
314
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../source/models/anthropic-provider.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,QAAA,MAAM,eAAe;;;;;;;;CAuBX,CAAC;AAEX,KAAK,SAAS,GAAG,aAAa,MAAM,OAAO,eAAe,EAAE,CAAC;AAE7D,eAAO,MAAM,mBAAmB,EAAE,SAAS,EAE1C,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;CAK7B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE;KAClC,CAAC,IAAI,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../source/models/anthropic-provider.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,QAAA,MAAM,eAAe;;;;;;;;CAuBX,CAAC;AAEX,KAAK,SAAS,GAAG,aAAa,MAAM,OAAO,eAAe,EAAE,CAAC;AAE7D,eAAO,MAAM,mBAAmB,EAAE,SAAS,EAE1C,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;CAK7B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE;KAClC,CAAC,IAAI,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC;CAsF3C,CAAC"}
|