wave-agent-sdk 0.0.8 → 0.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +92 -23
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +351 -137
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -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 +75 -0
- package/dist/managers/permissionManager.d.ts.map +1 -0
- package/dist/managers/permissionManager.js +368 -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 +109 -11
- 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 +39 -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/bashParser.d.ts +24 -0
- package/dist/utils/bashParser.d.ts.map +1 -0
- package/dist/utils/bashParser.js +413 -0
- 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/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/pathSafety.d.ts +10 -0
- package/dist/utils/pathSafety.d.ts.map +1 -0
- package/dist/utils/pathSafety.js +23 -0
- 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/package.json +9 -9
- package/src/agent.ts +475 -216
- package/src/index.ts +3 -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 +480 -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 +126 -13
- 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 +52 -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/bashParser.ts +444 -0
- 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/markdownParser.ts +1 -19
- package/src/utils/messageOperations.ts +7 -35
- package/src/utils/pathEncoder.ts +24 -9
- package/src/utils/pathSafety.ts +26 -0
- package/src/utils/subagentParser.ts +11 -8
- 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
|
@@ -5,17 +5,10 @@
|
|
|
5
5
|
* to optimize token usage and reduce costs. Cache control is only applied to Claude
|
|
6
6
|
* models and preserves backward compatibility with existing message formats.
|
|
7
7
|
*/
|
|
8
|
+
import { logger } from "./globalLogger.js";
|
|
8
9
|
// ============================================================================
|
|
9
10
|
// Default Configuration
|
|
10
11
|
// ============================================================================
|
|
11
|
-
/**
|
|
12
|
-
* Default cache control configuration
|
|
13
|
-
*/
|
|
14
|
-
export const DEFAULT_CACHE_CONTROL_CONFIG = {
|
|
15
|
-
cacheSystemMessage: true,
|
|
16
|
-
cacheUserMessageCount: 2,
|
|
17
|
-
cacheLastTool: true,
|
|
18
|
-
};
|
|
19
12
|
// ============================================================================
|
|
20
13
|
// Utility Functions (Basic Structure - to be implemented)
|
|
21
14
|
// ============================================================================
|
|
@@ -48,6 +41,24 @@ export function isValidCacheControl(control) {
|
|
|
48
41
|
"type" in control &&
|
|
49
42
|
control.type === "ephemeral");
|
|
50
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Adds cache control to the last tool call in an array
|
|
46
|
+
* @param toolCalls - Array of tool calls
|
|
47
|
+
* @returns Tool calls array with cache control on the last tool call
|
|
48
|
+
*/
|
|
49
|
+
function addCacheControlToLastToolCall(toolCalls) {
|
|
50
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
51
|
+
return toolCalls;
|
|
52
|
+
}
|
|
53
|
+
const result = [...toolCalls];
|
|
54
|
+
const lastIndex = result.length - 1;
|
|
55
|
+
// Add cache control to the last tool call
|
|
56
|
+
result[lastIndex] = {
|
|
57
|
+
...result[lastIndex],
|
|
58
|
+
cache_control: { type: "ephemeral" },
|
|
59
|
+
};
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
51
62
|
/**
|
|
52
63
|
* Adds cache control markers to message content
|
|
53
64
|
* @param content - Original content (string or structured)
|
|
@@ -66,7 +77,7 @@ export function addCacheControlToContent(content, shouldCache) {
|
|
|
66
77
|
}
|
|
67
78
|
// Validate array input
|
|
68
79
|
if (!Array.isArray(content)) {
|
|
69
|
-
|
|
80
|
+
logger.warn("Invalid content type for cache control transformation:", typeof content);
|
|
70
81
|
return [];
|
|
71
82
|
}
|
|
72
83
|
// Filter and convert only text parts with validation
|
|
@@ -92,7 +103,7 @@ export function addCacheControlToContent(content, shouldCache) {
|
|
|
92
103
|
}
|
|
93
104
|
// Validate array input
|
|
94
105
|
if (!Array.isArray(content)) {
|
|
95
|
-
|
|
106
|
+
logger.warn("Invalid content type for cache control transformation:", typeof content);
|
|
96
107
|
return [];
|
|
97
108
|
}
|
|
98
109
|
// Handle structured content - preserve existing structure, add cache control to text parts
|
|
@@ -122,17 +133,17 @@ export function addCacheControlToLastTool(tools) {
|
|
|
122
133
|
// Validate tools structure
|
|
123
134
|
const validTools = tools.filter((tool) => {
|
|
124
135
|
if (!tool || typeof tool !== "object") {
|
|
125
|
-
|
|
136
|
+
logger.warn("Invalid tool structure detected, skipping:", tool);
|
|
126
137
|
return false;
|
|
127
138
|
}
|
|
128
139
|
if (tool.type !== "function" || !tool.function) {
|
|
129
|
-
|
|
140
|
+
logger.warn("Tool is not a function type or missing function property:", tool);
|
|
130
141
|
return false;
|
|
131
142
|
}
|
|
132
143
|
return true;
|
|
133
144
|
});
|
|
134
145
|
if (validTools.length === 0) {
|
|
135
|
-
|
|
146
|
+
logger.warn("No valid tools found for cache control");
|
|
136
147
|
return [];
|
|
137
148
|
}
|
|
138
149
|
// Create a copy of the valid tools array
|
|
@@ -148,16 +159,37 @@ export function addCacheControlToLastTool(tools) {
|
|
|
148
159
|
return result;
|
|
149
160
|
}
|
|
150
161
|
/**
|
|
151
|
-
*
|
|
162
|
+
* Finds the latest message index at 20-message intervals (sliding window approach)
|
|
163
|
+
* @param messages - Array of chat completion messages
|
|
164
|
+
* @returns Index of the latest interval message (20th, 40th, 60th, etc.) or -1 if none
|
|
165
|
+
*/
|
|
166
|
+
export function findIntervalMessageIndex(messages) {
|
|
167
|
+
if (!Array.isArray(messages) || messages.length === 0) {
|
|
168
|
+
return -1;
|
|
169
|
+
}
|
|
170
|
+
const interval = 20; // Hardcoded interval
|
|
171
|
+
const messageCount = messages.length;
|
|
172
|
+
// Find the largest interval that fits within the message count
|
|
173
|
+
// Math.floor(messageCount / interval) gives us how many complete intervals we have
|
|
174
|
+
// Multiply by interval to get the position of the latest interval message
|
|
175
|
+
const latestIntervalPosition = Math.floor(messageCount / interval) * interval;
|
|
176
|
+
// If no complete intervals exist, return -1
|
|
177
|
+
if (latestIntervalPosition === 0) {
|
|
178
|
+
return -1;
|
|
179
|
+
}
|
|
180
|
+
// Convert from 1-based position to 0-based index
|
|
181
|
+
return latestIntervalPosition - 1;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Transforms messages for Claude cache control with hardcoded strategy
|
|
152
185
|
* @param messages - Original OpenAI message array
|
|
153
186
|
* @param modelName - Model name for cache detection
|
|
154
|
-
* @param config - Cache control configuration
|
|
155
187
|
* @returns Messages with cache control markers applied
|
|
156
188
|
*/
|
|
157
|
-
export function transformMessagesForClaudeCache(messages, modelName
|
|
189
|
+
export function transformMessagesForClaudeCache(messages, modelName) {
|
|
158
190
|
// Validate inputs
|
|
159
191
|
if (!messages || !Array.isArray(messages)) {
|
|
160
|
-
|
|
192
|
+
logger.warn("Invalid messages array provided to transformMessagesForClaudeCache");
|
|
161
193
|
return [];
|
|
162
194
|
}
|
|
163
195
|
if (messages.length === 0) {
|
|
@@ -167,40 +199,52 @@ export function transformMessagesForClaudeCache(messages, modelName, config = DE
|
|
|
167
199
|
if (!isClaudeModel(modelName)) {
|
|
168
200
|
return messages;
|
|
169
201
|
}
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
202
|
+
// Find the latest interval message index (20th, 40th, 60th, etc.)
|
|
203
|
+
const intervalMessageIndex = findIntervalMessageIndex(messages);
|
|
204
|
+
// Find last system message index
|
|
205
|
+
let lastSystemIndex = -1;
|
|
206
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
207
|
+
if (messages[i].role === "system") {
|
|
208
|
+
lastSystemIndex = i;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
174
211
|
}
|
|
175
212
|
const result = messages.map((message, index) => {
|
|
176
213
|
// Validate message structure
|
|
177
214
|
if (!message || typeof message !== "object" || !message.role) {
|
|
178
|
-
|
|
215
|
+
logger.warn("Invalid message structure at index", index, ":", message);
|
|
179
216
|
return message; // Return as-is to avoid breaking the flow
|
|
180
217
|
}
|
|
181
|
-
//
|
|
182
|
-
if (message.role === "system" &&
|
|
218
|
+
// Last system message: always cached (hardcoded)
|
|
219
|
+
if (message.role === "system" && index === lastSystemIndex) {
|
|
183
220
|
return {
|
|
184
221
|
...message,
|
|
185
|
-
content: addCacheControlToContent(message.content, true),
|
|
222
|
+
content: addCacheControlToContent(message.content || "", true),
|
|
186
223
|
};
|
|
187
224
|
}
|
|
188
|
-
//
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
.
|
|
200
|
-
|
|
225
|
+
// Interval-based message caching: cache message at latest interval position (sliding window)
|
|
226
|
+
if (index === intervalMessageIndex) {
|
|
227
|
+
// If the message is a tool role, add cache control directly to the message
|
|
228
|
+
if (message.role === "tool") {
|
|
229
|
+
return {
|
|
230
|
+
...message,
|
|
231
|
+
cache_control: { type: "ephemeral" },
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
// If the message has tool calls, cache the last tool call instead of content
|
|
235
|
+
else if (message.role === "assistant" &&
|
|
236
|
+
message.tool_calls &&
|
|
237
|
+
message.tool_calls.length > 0) {
|
|
238
|
+
return {
|
|
239
|
+
...message,
|
|
240
|
+
tool_calls: addCacheControlToLastToolCall(message.tool_calls),
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
// For other message types without tool calls, cache the content
|
|
201
245
|
return {
|
|
202
246
|
...message,
|
|
203
|
-
content: addCacheControlToContent(message.content, true),
|
|
247
|
+
content: addCacheControlToContent(message.content || "", true),
|
|
204
248
|
};
|
|
205
249
|
}
|
|
206
250
|
}
|
|
@@ -278,90 +322,3 @@ export function isValidClaudeUsage(usage) {
|
|
|
278
322
|
}
|
|
279
323
|
return true;
|
|
280
324
|
}
|
|
281
|
-
/**
|
|
282
|
-
* Adds cache control to the last N user messages in a conversation
|
|
283
|
-
* This optimizes multi-turn conversations by caching recent user context
|
|
284
|
-
*
|
|
285
|
-
* @param messages - Array of chat completion messages
|
|
286
|
-
* @param maxUserMessagesToCache - Maximum number of recent user messages to cache (default: 2)
|
|
287
|
-
* @returns Modified messages array with cache control on recent user messages
|
|
288
|
-
*/
|
|
289
|
-
export function addCacheControlToRecentUserMessages(messages, maxUserMessagesToCache = 2) {
|
|
290
|
-
// Validate inputs
|
|
291
|
-
if (!messages || !Array.isArray(messages)) {
|
|
292
|
-
console.warn("Invalid messages array provided to addCacheControlToRecentUserMessages");
|
|
293
|
-
return [];
|
|
294
|
-
}
|
|
295
|
-
if (messages.length === 0 || maxUserMessagesToCache <= 0) {
|
|
296
|
-
return messages;
|
|
297
|
-
}
|
|
298
|
-
// Validate maxUserMessagesToCache is a reasonable number
|
|
299
|
-
if (maxUserMessagesToCache > 100) {
|
|
300
|
-
console.warn("maxUserMessagesToCache is unusually high:", maxUserMessagesToCache, "limiting to 100");
|
|
301
|
-
maxUserMessagesToCache = 100;
|
|
302
|
-
}
|
|
303
|
-
// Find all user message indices in reverse order (most recent first)
|
|
304
|
-
const userMessageIndices = [];
|
|
305
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
306
|
-
const message = messages[i];
|
|
307
|
-
// Validate message structure
|
|
308
|
-
if (!message || typeof message !== "object" || !message.role) {
|
|
309
|
-
console.warn("Invalid message at index", i, ", skipping");
|
|
310
|
-
continue;
|
|
311
|
-
}
|
|
312
|
-
if (message.role === "user") {
|
|
313
|
-
userMessageIndices.push(i);
|
|
314
|
-
if (userMessageIndices.length >= maxUserMessagesToCache) {
|
|
315
|
-
break;
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
// If no user messages found, return unchanged
|
|
320
|
-
if (userMessageIndices.length === 0) {
|
|
321
|
-
return messages;
|
|
322
|
-
}
|
|
323
|
-
// Create a copy of messages and modify the identified user messages
|
|
324
|
-
const modifiedMessages = [...messages];
|
|
325
|
-
for (const index of userMessageIndices) {
|
|
326
|
-
const message = modifiedMessages[index];
|
|
327
|
-
if (message.role === "user" && message.content != null) {
|
|
328
|
-
try {
|
|
329
|
-
modifiedMessages[index] = {
|
|
330
|
-
...message,
|
|
331
|
-
content: addCacheControlToContent(message.content, true),
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
catch (error) {
|
|
335
|
-
console.warn("Failed to add cache control to user message at index", index, ":", error);
|
|
336
|
-
// Continue with original message if transformation fails
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return modifiedMessages;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* Helper function to identify user message indices that should be cached
|
|
344
|
-
* Used for testing and validation purposes
|
|
345
|
-
*
|
|
346
|
-
* @param messages - Array of chat completion messages
|
|
347
|
-
* @param maxUserMessagesToCache - Maximum number of recent user messages to identify
|
|
348
|
-
* @returns Array of indices for user messages that should be cached
|
|
349
|
-
*/
|
|
350
|
-
export function findRecentUserMessageIndices(messages, maxUserMessagesToCache = 2) {
|
|
351
|
-
if (!Array.isArray(messages) ||
|
|
352
|
-
messages.length === 0 ||
|
|
353
|
-
maxUserMessagesToCache <= 0) {
|
|
354
|
-
return [];
|
|
355
|
-
}
|
|
356
|
-
const userMessageIndices = [];
|
|
357
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
358
|
-
if (messages[i].role === "user") {
|
|
359
|
-
userMessageIndices.push(i);
|
|
360
|
-
if (userMessageIndices.length >= maxUserMessagesToCache) {
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
// Return indices in original order (not reversed)
|
|
366
|
-
return userMessageIndices.reverse();
|
|
367
|
-
}
|
|
@@ -22,16 +22,4 @@ export declare const USER_MEMORY_FILE: string;
|
|
|
22
22
|
* AI related constants
|
|
23
23
|
*/
|
|
24
24
|
export declare const DEFAULT_TOKEN_LIMIT = 96000;
|
|
25
|
-
/**
|
|
26
|
-
* @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
|
|
27
|
-
* They are maintained for backward compatibility with existing code that might still reference them,
|
|
28
|
-
* but the actual AI services now use configuration injection.
|
|
29
|
-
*/
|
|
30
|
-
export declare const FAST_MODEL_ID: string;
|
|
31
|
-
/**
|
|
32
|
-
* @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
|
|
33
|
-
* They are maintained for backward compatibility with existing code that might still reference them,
|
|
34
|
-
* but the actual AI services now use configuration injection.
|
|
35
|
-
*/
|
|
36
|
-
export declare const AGENT_MODEL_ID: string;
|
|
37
25
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAmC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAmC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAEhF;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAA0C,CAAC;AAE3E;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC"}
|
package/dist/utils/constants.js
CHANGED
|
@@ -19,20 +19,8 @@ export const ERROR_LOG_DIRECTORY = path.join(DATA_DIRECTORY, "error-logs");
|
|
|
19
19
|
/**
|
|
20
20
|
* User-level memory file path
|
|
21
21
|
*/
|
|
22
|
-
export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "
|
|
22
|
+
export const USER_MEMORY_FILE = path.join(DATA_DIRECTORY, "AGENTS.md");
|
|
23
23
|
/**
|
|
24
24
|
* AI related constants
|
|
25
25
|
*/
|
|
26
26
|
export const DEFAULT_TOKEN_LIMIT = 96000; // Default token limit
|
|
27
|
-
/**
|
|
28
|
-
* @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
|
|
29
|
-
* They are maintained for backward compatibility with existing code that might still reference them,
|
|
30
|
-
* but the actual AI services now use configuration injection.
|
|
31
|
-
*/
|
|
32
|
-
export const FAST_MODEL_ID = process.env.AIGW_FAST_MODEL || "gemini-2.5-flash";
|
|
33
|
-
/**
|
|
34
|
-
* @deprecated These constants are now legacy. Use ModelConfig through Agent constructor instead.
|
|
35
|
-
* They are maintained for backward compatibility with existing code that might still reference them,
|
|
36
|
-
* but the actual AI services now use configuration injection.
|
|
37
|
-
*/
|
|
38
|
-
export const AGENT_MODEL_ID = process.env.AIGW_MODEL || "claude-sonnet-4-20250514";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { Message } from "../types/index.js";
|
|
2
2
|
import { ChatCompletionMessageParam } from "openai/resources.js";
|
|
3
3
|
/**
|
|
4
|
-
* Convert message format to API call format, stopping when a compressed message is encountered
|
|
4
|
+
* Convert message format to API call format, stopping when a compressed message is encountered.
|
|
5
|
+
* Messages with no meaningful content or tool calls are filtered out.
|
|
5
6
|
* @param messages Message list
|
|
6
7
|
* @returns Converted API message format list
|
|
7
8
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAwB7B
|
|
1
|
+
{"version":3,"file":"convertMessagesForAPI.d.ts","sourceRoot":"","sources":["../../src/utils/convertMessagesForAPI.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAIjD,OAAO,EAEL,0BAA0B,EAC3B,MAAM,qBAAqB,CAAC;AAwB7B;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,OAAO,EAAE,GAClB,0BAA0B,EAAE,CAsN9B"}
|
|
@@ -22,7 +22,8 @@ function safeToolArguments(args) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
|
-
* Convert message format to API call format, stopping when a compressed message is encountered
|
|
25
|
+
* Convert message format to API call format, stopping when a compressed message is encountered.
|
|
26
|
+
* Messages with no meaningful content or tool calls are filtered out.
|
|
26
27
|
* @param messages Message list
|
|
27
28
|
* @returns Converted API message format list
|
|
28
29
|
*/
|
|
@@ -44,7 +45,7 @@ export function convertMessagesForAPI(messages) {
|
|
|
44
45
|
}
|
|
45
46
|
break;
|
|
46
47
|
}
|
|
47
|
-
// Skip empty assistant messages
|
|
48
|
+
// Skip empty assistant messages (no blocks or all blocks are empty)
|
|
48
49
|
if (message.role === "assistant" && message.blocks.length === 0) {
|
|
49
50
|
continue;
|
|
50
51
|
}
|
|
@@ -101,10 +102,14 @@ export function convertMessagesForAPI(messages) {
|
|
|
101
102
|
// Construct the content of the assistant message
|
|
102
103
|
let content = "";
|
|
103
104
|
let tool_calls = undefined;
|
|
104
|
-
// Construct content from text blocks
|
|
105
|
-
const textBlocks = message.blocks.filter((block) => block.type === "text"
|
|
105
|
+
// Construct content from text blocks - filter out empty content
|
|
106
|
+
const textBlocks = message.blocks.filter((block) => block.type === "text" &&
|
|
107
|
+
block.content &&
|
|
108
|
+
block.content.trim().length > 0);
|
|
106
109
|
if (textBlocks.length > 0) {
|
|
107
|
-
content = textBlocks
|
|
110
|
+
content = textBlocks
|
|
111
|
+
.map((block) => (block.type === "text" ? block.content : ""))
|
|
112
|
+
.join("\n");
|
|
108
113
|
}
|
|
109
114
|
// Construct tool calls from tool blocks
|
|
110
115
|
if (toolBlocks.length > 0) {
|
|
@@ -122,13 +127,15 @@ export function convertMessagesForAPI(messages) {
|
|
|
122
127
|
tool_calls = undefined;
|
|
123
128
|
}
|
|
124
129
|
}
|
|
125
|
-
// Construct assistant message - only add if there is content or tool calls
|
|
126
|
-
|
|
130
|
+
// Construct assistant message - only add if there is meaningful content or tool calls
|
|
131
|
+
const hasContent = content && content.trim().length > 0;
|
|
132
|
+
const hasToolCalls = tool_calls && tool_calls.length > 0;
|
|
133
|
+
if (hasContent || hasToolCalls) {
|
|
127
134
|
const assistantMessage = {
|
|
128
135
|
role: "assistant",
|
|
129
|
-
content,
|
|
136
|
+
content: hasContent ? content : undefined,
|
|
130
137
|
tool_calls,
|
|
131
|
-
...(message.
|
|
138
|
+
...(message.additionalFields ? { ...message.additionalFields } : {}),
|
|
132
139
|
};
|
|
133
140
|
recentMessages.unshift(assistantMessage);
|
|
134
141
|
}
|
|
@@ -137,8 +144,10 @@ export function convertMessagesForAPI(messages) {
|
|
|
137
144
|
// User messages converted to standard format
|
|
138
145
|
const contentParts = [];
|
|
139
146
|
message.blocks.forEach((block) => {
|
|
140
|
-
// Add text content
|
|
141
|
-
if (block.type === "text" &&
|
|
147
|
+
// Add text content - only if it has meaningful content
|
|
148
|
+
if (block.type === "text" &&
|
|
149
|
+
block.content &&
|
|
150
|
+
block.content.trim().length > 0) {
|
|
142
151
|
contentParts.push({
|
|
143
152
|
type: "text",
|
|
144
153
|
text: block.customCommandContent || block.content,
|
|
@@ -172,11 +181,21 @@ export function convertMessagesForAPI(messages) {
|
|
|
172
181
|
});
|
|
173
182
|
}
|
|
174
183
|
});
|
|
184
|
+
// Only add user message if there is meaningful content
|
|
175
185
|
if (contentParts.length > 0) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
// Filter out empty text parts
|
|
187
|
+
const meaningfulParts = contentParts.filter((part) => {
|
|
188
|
+
if (part.type === "text") {
|
|
189
|
+
return part.text && part.text.trim().length > 0;
|
|
190
|
+
}
|
|
191
|
+
return true; // Keep image parts
|
|
179
192
|
});
|
|
193
|
+
if (meaningfulParts.length > 0) {
|
|
194
|
+
recentMessages.unshift({
|
|
195
|
+
role: "user",
|
|
196
|
+
content: meaningfulParts,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
180
199
|
}
|
|
181
200
|
}
|
|
182
201
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Path } from "glob";
|
|
2
|
+
import type { FileItem } from "../types/fileSearch.js";
|
|
3
|
+
/**
|
|
4
|
+
* Convert Path objects to FileItem objects
|
|
5
|
+
*/
|
|
6
|
+
export declare const convertPathsToFileItems: (paths: Path[]) => FileItem[];
|
|
7
|
+
/**
|
|
8
|
+
* Search files and directories using glob patterns
|
|
9
|
+
*/
|
|
10
|
+
export declare const searchFiles: (query: string, options?: {
|
|
11
|
+
maxResults?: number;
|
|
12
|
+
workingDirectory?: string;
|
|
13
|
+
}) => Promise<FileItem[]>;
|
|
14
|
+
//# sourceMappingURL=fileSearch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileSearch.d.ts","sourceRoot":"","sources":["../../src/utils/fileSearch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,IAAI,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,OAAO,IAAI,EAAE,KAAG,QAAQ,EAK/D,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,OAAO,MAAM,EACb,UAAU;IACR,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,KACA,OAAO,CAAC,QAAQ,EAAE,CAmFpB,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { globIterate } from "glob";
|
|
2
|
+
import { getGlobIgnorePatterns } from "./fileFilter.js";
|
|
3
|
+
/**
|
|
4
|
+
* Convert Path objects to FileItem objects
|
|
5
|
+
*/
|
|
6
|
+
export const convertPathsToFileItems = (paths) => {
|
|
7
|
+
return paths.map((pathObj) => ({
|
|
8
|
+
path: pathObj.relative(),
|
|
9
|
+
type: pathObj.isDirectory() ? "directory" : "file",
|
|
10
|
+
}));
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Search files and directories using glob patterns
|
|
14
|
+
*/
|
|
15
|
+
export const searchFiles = async (query, options) => {
|
|
16
|
+
const { maxResults = 10, workingDirectory = process.cwd() } = options || {};
|
|
17
|
+
try {
|
|
18
|
+
const globOptions = {
|
|
19
|
+
ignore: getGlobIgnorePatterns(workingDirectory),
|
|
20
|
+
maxDepth: 10,
|
|
21
|
+
nocase: true, // Case insensitive
|
|
22
|
+
dot: true, // Include hidden files and directories
|
|
23
|
+
cwd: workingDirectory, // Specify search root directory
|
|
24
|
+
withFileTypes: true, // Get Path objects instead of strings
|
|
25
|
+
};
|
|
26
|
+
// Build glob patterns based on query
|
|
27
|
+
let patterns = [];
|
|
28
|
+
if (!query.trim()) {
|
|
29
|
+
// When query is empty, show some common file types and directories
|
|
30
|
+
patterns = [
|
|
31
|
+
"**/*.{ts,tsx,js,jsx,json,py,java}", // Combine common file extensions
|
|
32
|
+
"*/", // First level directories
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Build multiple glob patterns to support more flexible search
|
|
37
|
+
patterns = [
|
|
38
|
+
// Match files with filenames containing query
|
|
39
|
+
`**/*${query}*`,
|
|
40
|
+
// Match files with query in path (match directory names)
|
|
41
|
+
`**/${query}*/**/*`,
|
|
42
|
+
// Match directory names containing query
|
|
43
|
+
`**/*${query}*/`,
|
|
44
|
+
// Match directories containing query in path
|
|
45
|
+
`**/${query}*/`,
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
// Collect results until we reach maxResults
|
|
49
|
+
const collectedPaths = [];
|
|
50
|
+
const seenPaths = new Set();
|
|
51
|
+
// Process each pattern sequentially
|
|
52
|
+
for (const pattern of patterns) {
|
|
53
|
+
if (collectedPaths.length >= maxResults) {
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
// Use globIterate to get results one by one
|
|
57
|
+
const iterator = globIterate(pattern, globOptions);
|
|
58
|
+
for await (const pathObj of iterator) {
|
|
59
|
+
if (collectedPaths.length >= maxResults) {
|
|
60
|
+
// Stop the iterator when we have enough results
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
const relativePath = pathObj.relative();
|
|
64
|
+
if (!seenPaths.has(relativePath)) {
|
|
65
|
+
seenPaths.add(relativePath);
|
|
66
|
+
collectedPaths.push(pathObj);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Sort collected paths: directories first, then files
|
|
71
|
+
collectedPaths.sort((a, b) => {
|
|
72
|
+
const aIsDir = a.isDirectory();
|
|
73
|
+
const bIsDir = b.isDirectory();
|
|
74
|
+
if (aIsDir && !bIsDir)
|
|
75
|
+
return -1;
|
|
76
|
+
if (!aIsDir && bIsDir)
|
|
77
|
+
return 1;
|
|
78
|
+
return a.relative().localeCompare(b.relative());
|
|
79
|
+
});
|
|
80
|
+
// Convert to FileItems
|
|
81
|
+
const fileItems = convertPathsToFileItems(collectedPaths);
|
|
82
|
+
return fileItems;
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
console.error("Glob search error:", error);
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -6,10 +6,22 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare function readFirstLine(filePath: string): Promise<string>;
|
|
8
8
|
/**
|
|
9
|
-
* Reads a file from the end and returns the
|
|
9
|
+
* Reads a file from the end and returns the last non-empty line.
|
|
10
|
+
*
|
|
11
|
+
* This version supports files that end with:
|
|
12
|
+
* - "\n" (Unix-style, including modern macOS)
|
|
13
|
+
* - "\r\n" (Windows-style)
|
|
14
|
+
* - "\r" (older Mac-style, HL7, etc.)
|
|
10
15
|
*
|
|
11
16
|
* @param {string} filePath - The path to the file.
|
|
17
|
+
* @param {number} [minLength=1] - Minimum length for the returned line.
|
|
12
18
|
* @return {Promise<string>} - The last non-empty line of the file, or an empty string if no non-empty lines found.
|
|
13
19
|
*/
|
|
14
|
-
export declare function getLastLine(filePath: string): Promise<string>;
|
|
20
|
+
export declare function getLastLine(filePath: string, minLength?: number): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Ensures that a pattern is present in the global git ignore file.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} pattern - The pattern to add to global git ignore.
|
|
25
|
+
*/
|
|
26
|
+
export declare function ensureGlobalGitIgnore(pattern: string): Promise<void>;
|
|
15
27
|
//# sourceMappingURL=fileUtils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fileUtils.d.ts","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fileUtils.d.ts","sourceRoot":"","sources":["../../src/utils/fileUtils.ts"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBrE;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,WAAW,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,SAAI,GACZ,OAAO,CAAC,MAAM,CAAC,CA8DjB;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC1E"}
|