wave-agent-sdk 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/dist/agent.d.ts +92 -23
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +340 -137
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/managers/aiManager.d.ts +14 -36
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +74 -77
- package/dist/managers/backgroundBashManager.d.ts.map +1 -1
- package/dist/managers/backgroundBashManager.js +4 -3
- package/dist/managers/hookManager.d.ts +3 -8
- package/dist/managers/hookManager.d.ts.map +1 -1
- package/dist/managers/hookManager.js +39 -29
- package/dist/managers/liveConfigManager.d.ts +55 -18
- package/dist/managers/liveConfigManager.d.ts.map +1 -1
- package/dist/managers/liveConfigManager.js +372 -90
- package/dist/managers/lspManager.d.ts +43 -0
- package/dist/managers/lspManager.d.ts.map +1 -0
- package/dist/managers/lspManager.js +326 -0
- package/dist/managers/messageManager.d.ts +8 -16
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +52 -74
- package/dist/managers/permissionManager.d.ts +66 -0
- package/dist/managers/permissionManager.d.ts.map +1 -0
- package/dist/managers/permissionManager.js +208 -0
- package/dist/managers/skillManager.d.ts +1 -0
- package/dist/managers/skillManager.d.ts.map +1 -1
- package/dist/managers/skillManager.js +2 -1
- package/dist/managers/slashCommandManager.d.ts.map +1 -1
- package/dist/managers/slashCommandManager.js +0 -1
- package/dist/managers/subagentManager.d.ts +8 -23
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +97 -117
- package/dist/managers/toolManager.d.ts +38 -1
- package/dist/managers/toolManager.d.ts.map +1 -1
- package/dist/managers/toolManager.js +66 -2
- package/dist/services/aiService.d.ts +3 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +123 -30
- package/dist/services/configurationService.d.ts +116 -0
- package/dist/services/configurationService.d.ts.map +1 -0
- package/dist/services/configurationService.js +585 -0
- package/dist/services/fileWatcher.d.ts.map +1 -1
- package/dist/services/fileWatcher.js +5 -6
- package/dist/services/hook.d.ts +7 -124
- package/dist/services/hook.d.ts.map +1 -1
- package/dist/services/hook.js +46 -458
- package/dist/services/jsonlHandler.d.ts +24 -15
- package/dist/services/jsonlHandler.d.ts.map +1 -1
- package/dist/services/jsonlHandler.js +67 -88
- package/dist/services/memory.d.ts +0 -9
- package/dist/services/memory.d.ts.map +1 -1
- package/dist/services/memory.js +2 -49
- package/dist/services/session.d.ts +82 -33
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +275 -181
- package/dist/tools/bashTool.d.ts.map +1 -1
- package/dist/tools/bashTool.js +72 -13
- package/dist/tools/deleteFileTool.d.ts.map +1 -1
- package/dist/tools/deleteFileTool.js +25 -0
- package/dist/tools/editTool.d.ts.map +1 -1
- package/dist/tools/editTool.js +30 -6
- package/dist/tools/lspTool.d.ts +6 -0
- package/dist/tools/lspTool.d.ts.map +1 -0
- package/dist/tools/lspTool.js +589 -0
- package/dist/tools/multiEditTool.d.ts.map +1 -1
- package/dist/tools/multiEditTool.js +26 -7
- package/dist/tools/readTool.d.ts.map +1 -1
- package/dist/tools/readTool.js +111 -2
- package/dist/tools/skillTool.js +2 -2
- package/dist/tools/todoWriteTool.d.ts.map +1 -1
- package/dist/tools/todoWriteTool.js +23 -0
- package/dist/tools/types.d.ts +11 -8
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/writeTool.d.ts.map +1 -1
- package/dist/tools/writeTool.js +25 -9
- package/dist/types/commands.d.ts +0 -1
- package/dist/types/commands.d.ts.map +1 -1
- package/dist/types/config.d.ts +4 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/configuration.d.ts +69 -0
- package/dist/types/configuration.d.ts.map +1 -0
- package/dist/types/configuration.js +8 -0
- package/dist/types/core.d.ts +10 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/environment.d.ts +41 -0
- package/dist/types/environment.d.ts.map +1 -1
- package/dist/types/fileSearch.d.ts +5 -0
- package/dist/types/fileSearch.d.ts.map +1 -0
- package/dist/types/fileSearch.js +1 -0
- package/dist/types/hooks.d.ts +11 -2
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/hooks.js +1 -7
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +5 -0
- package/dist/types/lsp.d.ts +90 -0
- package/dist/types/lsp.d.ts.map +1 -0
- package/dist/types/lsp.js +4 -0
- package/dist/types/messaging.d.ts +6 -11
- package/dist/types/messaging.d.ts.map +1 -1
- package/dist/types/permissions.d.ts +35 -0
- package/dist/types/permissions.d.ts.map +1 -0
- package/dist/types/permissions.js +12 -0
- package/dist/types/session.d.ts +1 -6
- package/dist/types/session.d.ts.map +1 -1
- package/dist/types/skills.d.ts +1 -0
- package/dist/types/skills.d.ts.map +1 -1
- package/dist/types/tools.d.ts +35 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +4 -0
- package/dist/utils/abortUtils.d.ts +34 -0
- package/dist/utils/abortUtils.d.ts.map +1 -0
- package/dist/utils/abortUtils.js +92 -0
- package/dist/utils/bashHistory.d.ts +4 -0
- package/dist/utils/bashHistory.d.ts.map +1 -1
- package/dist/utils/bashHistory.js +21 -4
- package/dist/utils/builtinSubagents.d.ts +7 -0
- package/dist/utils/builtinSubagents.d.ts.map +1 -0
- package/dist/utils/builtinSubagents.js +65 -0
- package/dist/utils/cacheControlUtils.d.ts +8 -33
- package/dist/utils/cacheControlUtils.d.ts.map +1 -1
- package/dist/utils/cacheControlUtils.js +83 -126
- package/dist/utils/constants.d.ts +0 -12
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +1 -13
- package/dist/utils/convertMessagesForAPI.d.ts +2 -1
- package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
- package/dist/utils/convertMessagesForAPI.js +33 -14
- package/dist/utils/fileSearch.d.ts +14 -0
- package/dist/utils/fileSearch.d.ts.map +1 -0
- package/dist/utils/fileSearch.js +88 -0
- package/dist/utils/fileUtils.d.ts +14 -2
- package/dist/utils/fileUtils.d.ts.map +1 -1
- package/dist/utils/fileUtils.js +101 -17
- package/dist/utils/globalLogger.d.ts +0 -14
- package/dist/utils/globalLogger.d.ts.map +1 -1
- package/dist/utils/globalLogger.js +0 -16
- package/dist/utils/largeOutputHandler.d.ts +15 -0
- package/dist/utils/largeOutputHandler.d.ts.map +1 -0
- package/dist/utils/largeOutputHandler.js +40 -0
- package/dist/utils/markdownParser.d.ts.map +1 -1
- package/dist/utils/markdownParser.js +1 -17
- package/dist/utils/messageOperations.d.ts +1 -11
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +7 -24
- package/dist/utils/pathEncoder.d.ts +4 -0
- package/dist/utils/pathEncoder.d.ts.map +1 -1
- package/dist/utils/pathEncoder.js +16 -9
- package/dist/utils/subagentParser.d.ts +2 -2
- package/dist/utils/subagentParser.d.ts.map +1 -1
- package/dist/utils/subagentParser.js +10 -7
- package/dist/utils/tokenEstimator.d.ts +39 -0
- package/dist/utils/tokenEstimator.d.ts.map +1 -0
- package/dist/utils/tokenEstimator.js +55 -0
- package/package.json +5 -8
- package/src/agent.ts +460 -216
- package/src/index.ts +2 -0
- package/src/managers/aiManager.ts +107 -111
- package/src/managers/backgroundBashManager.ts +4 -3
- package/src/managers/hookManager.ts +44 -39
- package/src/managers/liveConfigManager.ts +524 -138
- package/src/managers/lspManager.ts +434 -0
- package/src/managers/messageManager.ts +73 -103
- package/src/managers/permissionManager.ts +276 -0
- package/src/managers/skillManager.ts +3 -1
- package/src/managers/slashCommandManager.ts +1 -2
- package/src/managers/subagentManager.ts +116 -159
- package/src/managers/toolManager.ts +95 -3
- package/src/services/aiService.ts +207 -26
- package/src/services/configurationService.ts +762 -0
- package/src/services/fileWatcher.ts +5 -6
- package/src/services/hook.ts +50 -631
- package/src/services/jsonlHandler.ts +84 -100
- package/src/services/memory.ts +2 -59
- package/src/services/session.ts +338 -213
- package/src/tools/bashTool.ts +89 -16
- package/src/tools/deleteFileTool.ts +36 -0
- package/src/tools/editTool.ts +41 -7
- package/src/tools/lspTool.ts +760 -0
- package/src/tools/multiEditTool.ts +37 -8
- package/src/tools/readTool.ts +125 -2
- package/src/tools/skillTool.ts +2 -2
- package/src/tools/todoWriteTool.ts +33 -1
- package/src/tools/types.ts +15 -9
- package/src/tools/writeTool.ts +36 -10
- package/src/types/commands.ts +0 -1
- package/src/types/config.ts +5 -0
- package/src/types/configuration.ts +73 -0
- package/src/types/core.ts +11 -0
- package/src/types/environment.ts +44 -0
- package/src/types/fileSearch.ts +4 -0
- package/src/types/hooks.ts +14 -11
- package/src/types/index.ts +5 -0
- package/src/types/lsp.ts +96 -0
- package/src/types/messaging.ts +8 -13
- package/src/types/permissions.ts +48 -0
- package/src/types/session.ts +3 -8
- package/src/types/skills.ts +1 -0
- package/src/types/tools.ts +38 -0
- package/src/utils/abortUtils.ts +118 -0
- package/src/utils/bashHistory.ts +28 -4
- package/src/utils/builtinSubagents.ts +71 -0
- package/src/utils/cacheControlUtils.ts +106 -171
- package/src/utils/constants.ts +1 -16
- package/src/utils/convertMessagesForAPI.ts +38 -14
- package/src/utils/fileSearch.ts +107 -0
- package/src/utils/fileUtils.ts +114 -19
- package/src/utils/globalLogger.ts +0 -17
- package/src/utils/largeOutputHandler.ts +55 -0
- package/src/utils/markdownParser.ts +1 -19
- package/src/utils/messageOperations.ts +7 -35
- package/src/utils/pathEncoder.ts +24 -9
- package/src/utils/subagentParser.ts +11 -8
- package/src/utils/tokenEstimator.ts +68 -0
- package/dist/constants/events.d.ts +0 -28
- package/dist/constants/events.d.ts.map +0 -1
- package/dist/constants/events.js +0 -27
- package/dist/services/configurationWatcher.d.ts +0 -120
- package/dist/services/configurationWatcher.d.ts.map +0 -1
- package/dist/services/configurationWatcher.js +0 -439
- package/dist/services/memoryStore.d.ts +0 -81
- package/dist/services/memoryStore.d.ts.map +0 -1
- package/dist/services/memoryStore.js +0 -200
- package/dist/types/memoryStore.d.ts +0 -82
- package/dist/types/memoryStore.d.ts.map +0 -1
- package/dist/types/memoryStore.js +0 -7
- package/dist/utils/configResolver.d.ts +0 -65
- package/dist/utils/configResolver.d.ts.map +0 -1
- package/dist/utils/configResolver.js +0 -210
- package/src/constants/events.ts +0 -38
- package/src/services/configurationWatcher.ts +0 -622
- package/src/services/memoryStore.ts +0 -279
- package/src/types/memoryStore.ts +0 -94
- package/src/utils/configResolver.ts +0 -302
package/dist/utils/fileUtils.js
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { createReadStream } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { execSync } from "node:child_process";
|
|
5
|
+
import { homedir } from "node:os";
|
|
2
6
|
/**
|
|
3
7
|
* Reads the first line of a file efficiently using Node.js readline.
|
|
4
8
|
*
|
|
@@ -6,7 +10,6 @@ import fs from "node:fs";
|
|
|
6
10
|
* @return {Promise<string>} - The first non-empty line of the file, or an empty string otherwise.
|
|
7
11
|
*/
|
|
8
12
|
export async function readFirstLine(filePath) {
|
|
9
|
-
const { createReadStream } = fs;
|
|
10
13
|
const { createInterface } = await import("node:readline");
|
|
11
14
|
const fileStream = createReadStream(filePath);
|
|
12
15
|
const rl = createInterface({
|
|
@@ -32,30 +35,111 @@ export async function readFirstLine(filePath) {
|
|
|
32
35
|
}
|
|
33
36
|
}
|
|
34
37
|
/**
|
|
35
|
-
* Reads a file from the end and returns the
|
|
38
|
+
* Reads a file from the end and returns the last non-empty line.
|
|
39
|
+
*
|
|
40
|
+
* This version supports files that end with:
|
|
41
|
+
* - "\n" (Unix-style, including modern macOS)
|
|
42
|
+
* - "\r\n" (Windows-style)
|
|
43
|
+
* - "\r" (older Mac-style, HL7, etc.)
|
|
36
44
|
*
|
|
37
45
|
* @param {string} filePath - The path to the file.
|
|
46
|
+
* @param {number} [minLength=1] - Minimum length for the returned line.
|
|
38
47
|
* @return {Promise<string>} - The last non-empty line of the file, or an empty string if no non-empty lines found.
|
|
39
48
|
*/
|
|
40
|
-
export async function getLastLine(filePath) {
|
|
41
|
-
|
|
42
|
-
const { promisify } = await import("util");
|
|
43
|
-
const execAsync = promisify(exec);
|
|
49
|
+
export async function getLastLine(filePath, minLength = 1) {
|
|
50
|
+
let fileHandle;
|
|
44
51
|
try {
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
const stats = await fs.stat(filePath);
|
|
53
|
+
const fileSize = stats.size;
|
|
54
|
+
if (fileSize === 0)
|
|
55
|
+
return "";
|
|
56
|
+
fileHandle = await fs.open(filePath, "r");
|
|
57
|
+
const bufferSize = 8 * 1024; // 8KB buffer is usually enough for the last line
|
|
58
|
+
const buffer = Buffer.alloc(bufferSize);
|
|
59
|
+
let lineEnd = null;
|
|
60
|
+
let lineStart = null;
|
|
61
|
+
let currentPosition = fileSize;
|
|
62
|
+
while (currentPosition > 0 && lineStart === null) {
|
|
63
|
+
const readSize = Math.min(bufferSize, currentPosition);
|
|
64
|
+
currentPosition -= readSize;
|
|
65
|
+
const { bytesRead } = await fileHandle.read(buffer, 0, readSize, currentPosition);
|
|
66
|
+
for (let i = bytesRead - 1; i >= 0; i--) {
|
|
67
|
+
const charCode = buffer[i];
|
|
68
|
+
if (lineEnd === null) {
|
|
69
|
+
// Still looking for the end of the last non-empty line (skip trailing newlines and whitespace)
|
|
70
|
+
if (charCode > 32) {
|
|
71
|
+
lineEnd = currentPosition + i + 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// Looking for the start of the line (the newline before it)
|
|
76
|
+
if (charCode === 10 || charCode === 13) {
|
|
77
|
+
lineStart = currentPosition + i + 1;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
53
81
|
}
|
|
54
82
|
}
|
|
55
|
-
|
|
83
|
+
if (lineEnd === null)
|
|
84
|
+
return "";
|
|
85
|
+
if (lineStart === null)
|
|
86
|
+
lineStart = 0;
|
|
87
|
+
const length = lineEnd - lineStart;
|
|
88
|
+
if (length < minLength)
|
|
89
|
+
return "";
|
|
90
|
+
const resultBuffer = Buffer.alloc(length);
|
|
91
|
+
await fileHandle.read(resultBuffer, 0, length, lineStart);
|
|
92
|
+
const result = resultBuffer.toString("utf8").trim();
|
|
93
|
+
return result.length >= minLength ? result : "";
|
|
56
94
|
}
|
|
57
95
|
catch {
|
|
58
|
-
// If
|
|
96
|
+
// If reading fails (e.g., file doesn't exist), return empty string
|
|
59
97
|
return "";
|
|
60
98
|
}
|
|
99
|
+
finally {
|
|
100
|
+
if (fileHandle) {
|
|
101
|
+
await fileHandle.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Ensures that a pattern is present in the global git ignore file.
|
|
107
|
+
*
|
|
108
|
+
* @param {string} pattern - The pattern to add to global git ignore.
|
|
109
|
+
*/
|
|
110
|
+
export async function ensureGlobalGitIgnore(pattern) {
|
|
111
|
+
try {
|
|
112
|
+
let globalIgnorePath;
|
|
113
|
+
try {
|
|
114
|
+
globalIgnorePath = execSync("git config --get core.excludesfile", {
|
|
115
|
+
encoding: "utf8",
|
|
116
|
+
}).trim();
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
// If not set, use default paths
|
|
120
|
+
const xdgConfigHome = process.env.XDG_CONFIG_HOME || path.join(homedir(), ".config");
|
|
121
|
+
globalIgnorePath = path.join(xdgConfigHome, "git", "ignore");
|
|
122
|
+
}
|
|
123
|
+
if (!globalIgnorePath)
|
|
124
|
+
return;
|
|
125
|
+
// Ensure directory exists
|
|
126
|
+
await fs.mkdir(path.dirname(globalIgnorePath), { recursive: true });
|
|
127
|
+
let content = "";
|
|
128
|
+
try {
|
|
129
|
+
content = await fs.readFile(globalIgnorePath, "utf8");
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// File doesn't exist
|
|
133
|
+
}
|
|
134
|
+
const lines = content.split("\n").map((line) => line.trim());
|
|
135
|
+
if (!lines.includes(pattern)) {
|
|
136
|
+
const newContent = content.endsWith("\n") || content === ""
|
|
137
|
+
? `${content}${pattern}\n`
|
|
138
|
+
: `${content}\n${pattern}\n`;
|
|
139
|
+
await fs.writeFile(globalIgnorePath, newContent, "utf8");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Ignore errors
|
|
144
|
+
}
|
|
61
145
|
}
|
|
@@ -30,20 +30,6 @@ import type { Logger } from "../types/core.js";
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export declare function setGlobalLogger(logger: Logger | null): void;
|
|
33
|
-
/**
|
|
34
|
-
* Retrieve the current global logger instance
|
|
35
|
-
*
|
|
36
|
-
* @returns Current logger instance or null if unconfigured
|
|
37
|
-
*
|
|
38
|
-
* @example
|
|
39
|
-
* ```typescript
|
|
40
|
-
* const currentLogger = getGlobalLogger();
|
|
41
|
-
* if (currentLogger) {
|
|
42
|
-
* currentLogger.info('Direct logger access');
|
|
43
|
-
* }
|
|
44
|
-
* ```
|
|
45
|
-
*/
|
|
46
|
-
export declare function getGlobalLogger(): Logger | null;
|
|
47
33
|
/**
|
|
48
34
|
* Reset global logger to unconfigured state
|
|
49
35
|
* Equivalent to setGlobalLogger(null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"globalLogger.d.ts","sourceRoot":"","sources":["../../src/utils/globalLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAa/C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED
|
|
1
|
+
{"version":3,"file":"globalLogger.d.ts","sourceRoot":"","sources":["../../src/utils/globalLogger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAa/C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAMD;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM;IACjB;;;OAGG;8BACc,OAAO,EAAE,KAAG,IAAI;IAKjC;;;OAGG;6BACa,OAAO,EAAE,KAAG,IAAI;IAKhC;;;OAGG;6BACa,OAAO,EAAE,KAAG,IAAI;IAKhC;;;OAGG;8BACc,OAAO,EAAE,KAAG,IAAI;CAIzB,CAAC"}
|
|
@@ -40,22 +40,6 @@ let globalLogger = null;
|
|
|
40
40
|
export function setGlobalLogger(logger) {
|
|
41
41
|
globalLogger = logger;
|
|
42
42
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Retrieve the current global logger instance
|
|
45
|
-
*
|
|
46
|
-
* @returns Current logger instance or null if unconfigured
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* ```typescript
|
|
50
|
-
* const currentLogger = getGlobalLogger();
|
|
51
|
-
* if (currentLogger) {
|
|
52
|
-
* currentLogger.info('Direct logger access');
|
|
53
|
-
* }
|
|
54
|
-
* ```
|
|
55
|
-
*/
|
|
56
|
-
export function getGlobalLogger() {
|
|
57
|
-
return globalLogger;
|
|
58
|
-
}
|
|
59
43
|
/**
|
|
60
44
|
* Reset global logger to unconfigured state
|
|
61
45
|
* Equivalent to setGlobalLogger(null)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const LARGE_OUTPUT_TOKEN_THRESHOLD = 20000;
|
|
2
|
+
/**
|
|
3
|
+
* Handle large command output by writing to temporary file when token threshold is exceeded
|
|
4
|
+
*
|
|
5
|
+
* Uses token-based threshold (20k tokens) to determine when output should be written to temp file.
|
|
6
|
+
* This provides accurate estimation of actual token cost for LLM processing.
|
|
7
|
+
*
|
|
8
|
+
* @param output - The command output string
|
|
9
|
+
* @returns Object containing processed content and optional file path
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleLargeOutput(output: string): Promise<{
|
|
12
|
+
content: string;
|
|
13
|
+
filePath?: string;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=largeOutputHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"largeOutputHandler.d.ts","sourceRoot":"","sources":["../../src/utils/largeOutputHandler.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,4BAA4B,QAAQ,CAAC;AAElD;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/D,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CA8BD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { writeFile } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { logger } from "./globalLogger.js";
|
|
5
|
+
import { estimateTokenCount, getTokenUsageDescription, } from "./tokenEstimator.js";
|
|
6
|
+
// Token threshold for writing output to temp file (20k tokens)
|
|
7
|
+
export const LARGE_OUTPUT_TOKEN_THRESHOLD = 20000;
|
|
8
|
+
/**
|
|
9
|
+
* Handle large command output by writing to temporary file when token threshold is exceeded
|
|
10
|
+
*
|
|
11
|
+
* Uses token-based threshold (20k tokens) to determine when output should be written to temp file.
|
|
12
|
+
* This provides accurate estimation of actual token cost for LLM processing.
|
|
13
|
+
*
|
|
14
|
+
* @param output - The command output string
|
|
15
|
+
* @returns Object containing processed content and optional file path
|
|
16
|
+
*/
|
|
17
|
+
export async function handleLargeOutput(output) {
|
|
18
|
+
const estimatedTokens = estimateTokenCount(output);
|
|
19
|
+
// Check token threshold
|
|
20
|
+
if (estimatedTokens <= LARGE_OUTPUT_TOKEN_THRESHOLD) {
|
|
21
|
+
return { content: output };
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
// Create temp file for large output
|
|
25
|
+
const tempFileName = `bash-output-${Date.now()}-${Math.random().toString(36).substr(2, 9)}.txt`;
|
|
26
|
+
const tempFilePath = join(tmpdir(), tempFileName);
|
|
27
|
+
await writeFile(tempFilePath, output, "utf8");
|
|
28
|
+
const sizeKB = Math.round(output.length / 1024);
|
|
29
|
+
const tokenDescription = getTokenUsageDescription(output, LARGE_OUTPUT_TOKEN_THRESHOLD);
|
|
30
|
+
return {
|
|
31
|
+
content: `Large output (${sizeKB} KB, ${tokenDescription}) written to temporary file. Use the Read tool to access the full content.`,
|
|
32
|
+
filePath: tempFilePath,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
logger.warn(`Failed to write large output to temp file: ${error}`);
|
|
37
|
+
// Fallback to direct output if temp file creation fails
|
|
38
|
+
return { content: output };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdownParser.d.ts","sourceRoot":"","sources":["../../src/utils/markdownParser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;
|
|
1
|
+
{"version":3,"file":"markdownParser.d.ts","sourceRoot":"","sources":["../../src/utils/markdownParser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAElE,UAAU,kBAAkB;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,wBAAwB,CAAC;CACnC;AA6CD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CA+BtE;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG;IAClD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAgBA;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,iBAAiB,EAAE,GAC3B,MAAM,CAcR"}
|
|
@@ -22,19 +22,7 @@ function parseFrontmatter(content) {
|
|
|
22
22
|
continue;
|
|
23
23
|
const key = trimmedLine.slice(0, colonIndex).trim();
|
|
24
24
|
const value = trimmedLine.slice(colonIndex + 1).trim();
|
|
25
|
-
|
|
26
|
-
if (key === "allowed-tools" && value) {
|
|
27
|
-
// Simple array parsing: "tool1, tool2, tool3" or "[tool1, tool2]"
|
|
28
|
-
let arrayValue = value;
|
|
29
|
-
if (arrayValue.startsWith("[") && arrayValue.endsWith("]")) {
|
|
30
|
-
arrayValue = arrayValue.slice(1, -1);
|
|
31
|
-
}
|
|
32
|
-
frontmatter[key] = arrayValue
|
|
33
|
-
.split(",")
|
|
34
|
-
.map((s) => s.trim())
|
|
35
|
-
.filter(Boolean);
|
|
36
|
-
}
|
|
37
|
-
else if (value) {
|
|
25
|
+
if (value) {
|
|
38
26
|
frontmatter[key] = value;
|
|
39
27
|
}
|
|
40
28
|
}
|
|
@@ -55,10 +43,6 @@ export function parseMarkdownFile(filePath) {
|
|
|
55
43
|
let config;
|
|
56
44
|
if (frontmatter) {
|
|
57
45
|
config = {};
|
|
58
|
-
if (frontmatter["allowed-tools"] &&
|
|
59
|
-
Array.isArray(frontmatter["allowed-tools"])) {
|
|
60
|
-
config.allowedTools = frontmatter["allowed-tools"];
|
|
61
|
-
}
|
|
62
46
|
if (frontmatter.model && typeof frontmatter.model === "string") {
|
|
63
47
|
config.model = frontmatter.model;
|
|
64
48
|
}
|
|
@@ -39,15 +39,6 @@ export interface UpdateToolBlockParams {
|
|
|
39
39
|
parametersChunk?: string;
|
|
40
40
|
}
|
|
41
41
|
export type AgentToolBlockUpdateParams = Omit<UpdateToolBlockParams, "messages">;
|
|
42
|
-
export interface AddDiffBlockParams {
|
|
43
|
-
messages: Message[];
|
|
44
|
-
path: string;
|
|
45
|
-
diffResult: Array<{
|
|
46
|
-
value: string;
|
|
47
|
-
added?: boolean;
|
|
48
|
-
removed?: boolean;
|
|
49
|
-
}>;
|
|
50
|
-
}
|
|
51
42
|
export interface AddErrorBlockParams {
|
|
52
43
|
messages: Message[];
|
|
53
44
|
error: string;
|
|
@@ -85,8 +76,7 @@ export declare const extractUserInputHistory: (messages: Message[]) => string[];
|
|
|
85
76
|
*/
|
|
86
77
|
export declare const convertImageToBase64: (imagePath: string) => string;
|
|
87
78
|
export declare const addUserMessageToMessages: ({ messages, content, images, customCommandContent, source, }: AddUserMessageParams) => Message[];
|
|
88
|
-
export declare const addAssistantMessageToMessages: (messages: Message[], content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[], usage?: Usage,
|
|
89
|
-
export declare const addDiffBlockToMessage: ({ messages, path, diffResult, }: AddDiffBlockParams) => Message[];
|
|
79
|
+
export declare const addAssistantMessageToMessages: (messages: Message[], content?: string, toolCalls?: ChatCompletionMessageFunctionToolCall[], usage?: Usage, additionalFields?: Record<string, unknown>) => Message[];
|
|
90
80
|
export declare const updateToolBlockInMessage: ({ messages, id, parameters, result, success, error, stage, name, shortResult, images, compactParams, parametersChunk, }: UpdateToolBlockParams) => Message[];
|
|
91
81
|
export declare const addErrorBlockToMessage: ({ messages, error, }: AddErrorBlockParams) => Message[];
|
|
92
82
|
export declare const addMemoryBlockToMessage: ({ messages, content, isSuccess, memoryType, storagePath, }: AddMemoryBlockParams) => Message[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAGjE,OAAO,EAAE,qCAAqC,EAAE,MAAM,qBAAqB,CAAC;AAI5E,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAGD,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,KAAK,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,CAAC;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAC3C,qBAAqB,EACrB,UAAU,CACX,CAAC;AAEF,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"messageOperations.d.ts","sourceRoot":"","sources":["../../src/utils/messageOperations.ts"],"names":[],"mappings":"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"}
|
|
@@ -85,7 +85,7 @@ export const addUserMessageToMessages = ({ messages, content, images, customComm
|
|
|
85
85
|
return [...messages, userMessage];
|
|
86
86
|
};
|
|
87
87
|
// Add assistant message (support one-time addition of answer and tool calls)
|
|
88
|
-
export const addAssistantMessageToMessages = (messages, content, toolCalls, usage,
|
|
88
|
+
export const addAssistantMessageToMessages = (messages, content, toolCalls, usage, additionalFields) => {
|
|
89
89
|
const blocks = [];
|
|
90
90
|
// If there's answer content, add text block
|
|
91
91
|
if (content) {
|
|
@@ -108,27 +108,10 @@ export const addAssistantMessageToMessages = (messages, content, toolCalls, usag
|
|
|
108
108
|
role: "assistant",
|
|
109
109
|
blocks,
|
|
110
110
|
usage, // Include usage data if provided
|
|
111
|
-
...(
|
|
111
|
+
...(additionalFields ? { additionalFields: { ...additionalFields } } : {}),
|
|
112
112
|
};
|
|
113
113
|
return [...messages, initialAssistantMessage];
|
|
114
114
|
};
|
|
115
|
-
// Update File Operation Block of the last assistant message
|
|
116
|
-
export const addDiffBlockToMessage = ({ messages, path, diffResult, }) => {
|
|
117
|
-
const newMessages = [...messages];
|
|
118
|
-
// Find the last assistant message
|
|
119
|
-
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
120
|
-
if (newMessages[i].role === "assistant") {
|
|
121
|
-
// Directly add diff block instead of replacing existing blocks
|
|
122
|
-
newMessages[i].blocks.push({
|
|
123
|
-
type: "diff",
|
|
124
|
-
path: path,
|
|
125
|
-
diffResult: diffResult,
|
|
126
|
-
});
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return newMessages;
|
|
131
|
-
};
|
|
132
115
|
// Update Tool Block of the last assistant message
|
|
133
116
|
export const updateToolBlockInMessage = ({ messages, id, parameters, result, success, error, stage, name, shortResult, images, compactParams, parametersChunk, }) => {
|
|
134
117
|
const newMessages = [...messages];
|
|
@@ -292,7 +275,7 @@ export const getMessagesToCompress = (messages, keepLastCount = 7) => {
|
|
|
292
275
|
// Add command output block to message list
|
|
293
276
|
export const addCommandOutputMessage = ({ messages, command, }) => {
|
|
294
277
|
const outputMessage = {
|
|
295
|
-
role: "
|
|
278
|
+
role: "user",
|
|
296
279
|
blocks: [
|
|
297
280
|
{
|
|
298
281
|
type: "command_output",
|
|
@@ -308,10 +291,10 @@ export const addCommandOutputMessage = ({ messages, command, }) => {
|
|
|
308
291
|
// Update output content of command output block
|
|
309
292
|
export const updateCommandOutputInMessage = ({ messages, command, output, }) => {
|
|
310
293
|
const newMessages = [...messages];
|
|
311
|
-
// Find the last
|
|
294
|
+
// Find the last user message with a command_output block for this command
|
|
312
295
|
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
313
296
|
const msg = newMessages[i];
|
|
314
|
-
if (msg.role === "
|
|
297
|
+
if (msg.role === "user") {
|
|
315
298
|
const commandBlock = msg.blocks.find((block) => block.type === "command_output" &&
|
|
316
299
|
block.command === command &&
|
|
317
300
|
block.isRunning);
|
|
@@ -326,10 +309,10 @@ export const updateCommandOutputInMessage = ({ messages, command, output, }) =>
|
|
|
326
309
|
// Complete command execution, update exit status
|
|
327
310
|
export const completeCommandInMessage = ({ messages, command, exitCode, }) => {
|
|
328
311
|
const newMessages = [...messages];
|
|
329
|
-
// Find the last
|
|
312
|
+
// Find the last user message with a command_output block for this command
|
|
330
313
|
for (let i = newMessages.length - 1; i >= 0; i--) {
|
|
331
314
|
const msg = newMessages[i];
|
|
332
|
-
if (msg.role === "
|
|
315
|
+
if (msg.role === "user") {
|
|
333
316
|
const commandBlock = msg.blocks.find((block) => block.type === "command_output" &&
|
|
334
317
|
block.command === command &&
|
|
335
318
|
block.isRunning);
|
|
@@ -72,6 +72,10 @@ export declare class PathEncoder {
|
|
|
72
72
|
* Resolve symbolic links and normalize path before encoding
|
|
73
73
|
*/
|
|
74
74
|
resolvePath(path: string): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Get project directory info without creating the directory
|
|
77
|
+
*/
|
|
78
|
+
getProjectDirectory(originalPath: string, baseSessionDir: string): Promise<ProjectDirectory>;
|
|
75
79
|
/**
|
|
76
80
|
* Create project directory entity from original path
|
|
77
81
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pathEncoder.d.ts","sourceRoot":"","sources":["../../src/utils/pathEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;gBAExC,OAAO,GAAE,mBAAwB;IAY7C;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMnD;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAyCxC;;;OAGG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzD;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgC9C;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD;;OAEG;IACG,sBAAsB,CAC1B,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"pathEncoder.d.ts","sourceRoot":"","sources":["../../src/utils/pathEncoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAwB;gBAExC,OAAO,GAAE,mBAAwB;IAY7C;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMnD;;;OAGG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM;IAyCxC;;;OAGG;IACG,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAIzD;;;OAGG;IACH,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAgC9C;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBhD;;OAEG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAmC5B;;OAEG;IACG,sBAAsB,CAC1B,YAAY,EAAE,MAAM,EACpB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAgB5B;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IA+BjD;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM;IAqBtE;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAsDhC;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,WAAW;CAMpB;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -110,9 +110,9 @@ export class PathEncoder {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
113
|
+
* Get project directory info without creating the directory
|
|
114
114
|
*/
|
|
115
|
-
async
|
|
115
|
+
async getProjectDirectory(originalPath, baseSessionDir) {
|
|
116
116
|
// Resolve the original path and check for symbolic links
|
|
117
117
|
const expandedPath = this.expandTilde(originalPath);
|
|
118
118
|
const absolutePath = resolve(expandedPath);
|
|
@@ -134,13 +134,6 @@ export class PathEncoder {
|
|
|
134
134
|
if (resolvedPath.length > this.options.maxLength) {
|
|
135
135
|
pathHash = this.generateHash(resolvedPath, this.options.hashLength);
|
|
136
136
|
}
|
|
137
|
-
// Ensure the encoded directory exists
|
|
138
|
-
try {
|
|
139
|
-
await mkdir(encodedPath, { recursive: true });
|
|
140
|
-
}
|
|
141
|
-
catch {
|
|
142
|
-
// Ignore errors if directory already exists
|
|
143
|
-
}
|
|
144
137
|
return {
|
|
145
138
|
originalPath: resolvedPath,
|
|
146
139
|
encodedName,
|
|
@@ -149,6 +142,20 @@ export class PathEncoder {
|
|
|
149
142
|
isSymbolicLink,
|
|
150
143
|
};
|
|
151
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Create project directory entity from original path
|
|
147
|
+
*/
|
|
148
|
+
async createProjectDirectory(originalPath, baseSessionDir) {
|
|
149
|
+
const projectDirectory = await this.getProjectDirectory(originalPath, baseSessionDir);
|
|
150
|
+
// Ensure the encoded directory exists
|
|
151
|
+
try {
|
|
152
|
+
await mkdir(projectDirectory.encodedPath, { recursive: true });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
// Ignore errors if directory already exists
|
|
156
|
+
}
|
|
157
|
+
return projectDirectory;
|
|
158
|
+
}
|
|
152
159
|
/**
|
|
153
160
|
* Validate that an encoded name is filesystem-safe
|
|
154
161
|
*/
|
|
@@ -5,11 +5,11 @@ export interface SubagentConfiguration {
|
|
|
5
5
|
model?: string;
|
|
6
6
|
systemPrompt: string;
|
|
7
7
|
filePath: string;
|
|
8
|
-
scope: "project" | "user";
|
|
8
|
+
scope: "project" | "user" | "builtin";
|
|
9
9
|
priority: number;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Load all subagent configurations from project and user directories
|
|
12
|
+
* Load all subagent configurations from project and user directories, plus built-in subagents
|
|
13
13
|
*/
|
|
14
14
|
export declare function loadSubagentConfigurations(workdir: string): Promise<SubagentConfiguration[]>;
|
|
15
15
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagentParser.d.ts","sourceRoot":"","sources":["../../src/utils/subagentParser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"subagentParser.d.ts","sourceRoot":"","sources":["../../src/utils/subagentParser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC;CAClB;AA+KD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAsBlC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,qBAAqB,GAAG,IAAI,CAAC,CAGvC"}
|
|
@@ -68,10 +68,10 @@ function validateConfiguration(config, filePath) {
|
|
|
68
68
|
if (!config.description) {
|
|
69
69
|
throw new Error(`Missing required field 'description' in ${filePath}`);
|
|
70
70
|
}
|
|
71
|
-
// Validate name pattern
|
|
72
|
-
const namePattern = /^[a-
|
|
71
|
+
// Validate name pattern - allow letters (upper/lowercase), numbers, and hyphens
|
|
72
|
+
const namePattern = /^[a-zA-Z][a-zA-Z0-9-]*$/;
|
|
73
73
|
if (!namePattern.test(config.name)) {
|
|
74
|
-
throw new Error(`Invalid subagent name '${config.name}' in ${filePath}. Must start with a letter and contain only
|
|
74
|
+
throw new Error(`Invalid subagent name '${config.name}' in ${filePath}. Must start with a letter and contain only letters, numbers, and hyphens.`);
|
|
75
75
|
}
|
|
76
76
|
// Validate model if specified - allow any non-empty string
|
|
77
77
|
if (config.model && typeof config.model !== "string") {
|
|
@@ -132,17 +132,20 @@ function scanSubagentDirectory(dirPath, scope) {
|
|
|
132
132
|
return configurations;
|
|
133
133
|
}
|
|
134
134
|
/**
|
|
135
|
-
* Load all subagent configurations from project and user directories
|
|
135
|
+
* Load all subagent configurations from project and user directories, plus built-in subagents
|
|
136
136
|
*/
|
|
137
137
|
export async function loadSubagentConfigurations(workdir) {
|
|
138
138
|
const projectDir = join(workdir, ".wave", "agents");
|
|
139
139
|
const userDir = join(process.env.HOME || "~", ".wave", "agents");
|
|
140
|
+
// Load configurations from all sources
|
|
141
|
+
const { getBuiltinSubagents } = await import("./builtinSubagents.js");
|
|
142
|
+
const builtinConfigs = getBuiltinSubagents();
|
|
140
143
|
const projectConfigs = scanSubagentDirectory(projectDir, "project");
|
|
141
144
|
const userConfigs = scanSubagentDirectory(userDir, "user");
|
|
142
|
-
// Merge configurations, with project configs taking precedence
|
|
145
|
+
// Merge configurations, with project configs taking highest precedence
|
|
143
146
|
const configMap = new Map();
|
|
144
|
-
// Process in reverse priority order (
|
|
145
|
-
for (const config of [...userConfigs, ...projectConfigs]) {
|
|
147
|
+
// Process in reverse priority order (built-in first, then user, then project)
|
|
148
|
+
for (const config of [...builtinConfigs, ...userConfigs, ...projectConfigs]) {
|
|
146
149
|
configMap.set(config.name, config);
|
|
147
150
|
}
|
|
148
151
|
return Array.from(configMap.values()).sort((a, b) => {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple token estimation utility for text content
|
|
3
|
+
*
|
|
4
|
+
* This provides a fast approximation of token count without requiring
|
|
5
|
+
* actual tokenization, which would be expensive for large content.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Estimate the number of tokens in a text string
|
|
9
|
+
*
|
|
10
|
+
* Uses a simple heuristic based on character count and common patterns:
|
|
11
|
+
* - Average token length varies by language and content type
|
|
12
|
+
* - English text: ~4-5 characters per token
|
|
13
|
+
* - Code/structured text: ~3-4 characters per token
|
|
14
|
+
* - Numbers/symbols: ~2-3 characters per token
|
|
15
|
+
*
|
|
16
|
+
* This function uses a conservative estimate of 4 characters per token
|
|
17
|
+
* which works well for mixed content (text + code + symbols).
|
|
18
|
+
*
|
|
19
|
+
* @param text - The text to estimate tokens for
|
|
20
|
+
* @returns Estimated number of tokens
|
|
21
|
+
*/
|
|
22
|
+
export declare function estimateTokenCount(text: string): number;
|
|
23
|
+
/**
|
|
24
|
+
* Check if estimated token count exceeds a threshold
|
|
25
|
+
*
|
|
26
|
+
* @param text - The text to check
|
|
27
|
+
* @param threshold - Token threshold (default: 20,000)
|
|
28
|
+
* @returns True if estimated tokens exceed threshold
|
|
29
|
+
*/
|
|
30
|
+
export declare function exceedsTokenThreshold(text: string, threshold?: number): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Get a human-readable description of estimated token usage
|
|
33
|
+
*
|
|
34
|
+
* @param text - The text to analyze
|
|
35
|
+
* @param threshold - Token threshold for comparison
|
|
36
|
+
* @returns Description string with token count and threshold info
|
|
37
|
+
*/
|
|
38
|
+
export declare function getTokenUsageDescription(text: string, threshold?: number): string;
|
|
39
|
+
//# sourceMappingURL=tokenEstimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokenEstimator.d.ts","sourceRoot":"","sources":["../../src/utils/tokenEstimator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAcvD;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAc,GACxB,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,MAAc,GACxB,MAAM,CAKR"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple token estimation utility for text content
|
|
3
|
+
*
|
|
4
|
+
* This provides a fast approximation of token count without requiring
|
|
5
|
+
* actual tokenization, which would be expensive for large content.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Estimate the number of tokens in a text string
|
|
9
|
+
*
|
|
10
|
+
* Uses a simple heuristic based on character count and common patterns:
|
|
11
|
+
* - Average token length varies by language and content type
|
|
12
|
+
* - English text: ~4-5 characters per token
|
|
13
|
+
* - Code/structured text: ~3-4 characters per token
|
|
14
|
+
* - Numbers/symbols: ~2-3 characters per token
|
|
15
|
+
*
|
|
16
|
+
* This function uses a conservative estimate of 4 characters per token
|
|
17
|
+
* which works well for mixed content (text + code + symbols).
|
|
18
|
+
*
|
|
19
|
+
* @param text - The text to estimate tokens for
|
|
20
|
+
* @returns Estimated number of tokens
|
|
21
|
+
*/
|
|
22
|
+
export function estimateTokenCount(text) {
|
|
23
|
+
if (!text || text.length === 0) {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
// Base estimation: 4 characters per token (conservative)
|
|
27
|
+
const baseEstimate = Math.ceil(text.length / 4);
|
|
28
|
+
// Adjust for whitespace (spaces don't contribute much to token count)
|
|
29
|
+
const whitespaceCount = (text.match(/\s/g) || []).length;
|
|
30
|
+
const adjustedEstimate = Math.ceil((text.length - whitespaceCount * 0.5) / 4);
|
|
31
|
+
// Use the more conservative (higher) estimate
|
|
32
|
+
return Math.max(baseEstimate, adjustedEstimate);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if estimated token count exceeds a threshold
|
|
36
|
+
*
|
|
37
|
+
* @param text - The text to check
|
|
38
|
+
* @param threshold - Token threshold (default: 20,000)
|
|
39
|
+
* @returns True if estimated tokens exceed threshold
|
|
40
|
+
*/
|
|
41
|
+
export function exceedsTokenThreshold(text, threshold = 20000) {
|
|
42
|
+
return estimateTokenCount(text) > threshold;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get a human-readable description of estimated token usage
|
|
46
|
+
*
|
|
47
|
+
* @param text - The text to analyze
|
|
48
|
+
* @param threshold - Token threshold for comparison
|
|
49
|
+
* @returns Description string with token count and threshold info
|
|
50
|
+
*/
|
|
51
|
+
export function getTokenUsageDescription(text, threshold = 20000) {
|
|
52
|
+
const estimatedTokens = estimateTokenCount(text);
|
|
53
|
+
const exceedsThreshold = estimatedTokens > threshold;
|
|
54
|
+
return `${estimatedTokens.toLocaleString()} tokens (${exceedsThreshold ? "exceeds" : "within"} ${threshold.toLocaleString()} limit)`;
|
|
55
|
+
}
|