wave-agent-sdk 0.0.3 → 0.0.5
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 +61 -4
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +84 -8
- package/dist/hooks/manager.d.ts.map +1 -1
- package/dist/hooks/manager.js +1 -1
- package/dist/managers/aiManager.d.ts +2 -1
- package/dist/managers/aiManager.d.ts.map +1 -1
- package/dist/managers/aiManager.js +37 -6
- package/dist/managers/mcpManager.js +5 -5
- package/dist/managers/messageManager.d.ts +13 -2
- package/dist/managers/messageManager.d.ts.map +1 -1
- package/dist/managers/messageManager.js +20 -7
- package/dist/managers/skillManager.js +3 -3
- package/dist/managers/slashCommandManager.js +1 -1
- package/dist/managers/subagentManager.d.ts +3 -1
- package/dist/managers/subagentManager.d.ts.map +1 -1
- package/dist/managers/subagentManager.js +5 -1
- package/dist/services/aiService.d.ts +9 -1
- package/dist/services/aiService.d.ts.map +1 -1
- package/dist/services/aiService.js +17 -3
- package/dist/services/memory.js +5 -5
- package/dist/services/session.d.ts +64 -15
- package/dist/services/session.d.ts.map +1 -1
- package/dist/services/session.js +80 -30
- package/dist/tools/bashTool.js +2 -2
- package/dist/tools/deleteFileTool.js +1 -1
- package/dist/tools/editTool.js +1 -1
- package/dist/tools/multiEditTool.js +2 -2
- package/dist/tools/writeTool.js +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/messageOperations.d.ts +2 -2
- package/dist/utils/messageOperations.d.ts.map +1 -1
- package/dist/utils/messageOperations.js +2 -1
- package/package.json +1 -1
- package/src/agent.ts +103 -9
- package/src/hooks/manager.ts +4 -2
- package/src/managers/aiManager.ts +43 -7
- package/src/managers/mcpManager.ts +5 -5
- package/src/managers/messageManager.ts +34 -5
- package/src/managers/skillManager.ts +3 -3
- package/src/managers/slashCommandManager.ts +1 -1
- package/src/managers/subagentManager.ts +14 -2
- package/src/services/aiService.ts +29 -6
- package/src/services/memory.ts +5 -5
- package/src/services/session.ts +93 -26
- package/src/tools/bashTool.ts +2 -2
- package/src/tools/deleteFileTool.ts +1 -1
- package/src/tools/editTool.ts +1 -1
- package/src/tools/multiEditTool.ts +2 -2
- package/src/tools/writeTool.ts +1 -1
- package/src/types.ts +13 -0
- package/src/utils/messageOperations.ts +3 -1
|
@@ -74,7 +74,7 @@ export interface CallAgentOptions {
|
|
|
74
74
|
messages: ChatCompletionMessageParam[];
|
|
75
75
|
sessionId?: string;
|
|
76
76
|
abortSignal?: AbortSignal;
|
|
77
|
-
memory?: string; // Memory content parameter, content read from
|
|
77
|
+
memory?: string; // Memory content parameter, content read from AGENTS.md
|
|
78
78
|
workdir: string; // Current working directory
|
|
79
79
|
tools?: ChatCompletionFunctionTool[]; // Tool configuration
|
|
80
80
|
model?: string; // Custom model
|
|
@@ -214,9 +214,18 @@ export interface CompressMessagesOptions {
|
|
|
214
214
|
abortSignal?: AbortSignal;
|
|
215
215
|
}
|
|
216
216
|
|
|
217
|
+
export interface CompressMessagesResult {
|
|
218
|
+
content: string;
|
|
219
|
+
usage?: {
|
|
220
|
+
prompt_tokens: number;
|
|
221
|
+
completion_tokens: number;
|
|
222
|
+
total_tokens: number;
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
217
226
|
export async function compressMessages(
|
|
218
227
|
options: CompressMessagesOptions,
|
|
219
|
-
): Promise<
|
|
228
|
+
): Promise<CompressMessagesResult> {
|
|
220
229
|
const { gatewayConfig, modelConfig, messages, abortSignal } = options;
|
|
221
230
|
|
|
222
231
|
// Create OpenAI client with injected configuration
|
|
@@ -294,15 +303,29 @@ For technical conversations, structure as:
|
|
|
294
303
|
},
|
|
295
304
|
);
|
|
296
305
|
|
|
297
|
-
|
|
306
|
+
const content =
|
|
298
307
|
response.choices[0]?.message?.content?.trim() ||
|
|
299
|
-
"Failed to compress conversation history"
|
|
300
|
-
|
|
308
|
+
"Failed to compress conversation history";
|
|
309
|
+
const usage = response.usage
|
|
310
|
+
? {
|
|
311
|
+
prompt_tokens: response.usage.prompt_tokens,
|
|
312
|
+
completion_tokens: response.usage.completion_tokens,
|
|
313
|
+
total_tokens: response.usage.total_tokens,
|
|
314
|
+
}
|
|
315
|
+
: undefined;
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
content,
|
|
319
|
+
usage,
|
|
320
|
+
};
|
|
301
321
|
} catch (error) {
|
|
302
322
|
if ((error as Error).name === "AbortError") {
|
|
303
323
|
throw new Error("Compression request was aborted");
|
|
304
324
|
}
|
|
305
325
|
// // logger.error("Failed to compress messages:", error);
|
|
306
|
-
return
|
|
326
|
+
return {
|
|
327
|
+
content: "Failed to compress conversation history",
|
|
328
|
+
usage: undefined,
|
|
329
|
+
};
|
|
307
330
|
}
|
|
308
331
|
}
|
package/src/services/memory.ts
CHANGED
|
@@ -16,7 +16,7 @@ export const addMemory = async (
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
|
-
const memoryFilePath = path.join(workdir, "
|
|
19
|
+
const memoryFilePath = path.join(workdir, "AGENTS.md");
|
|
20
20
|
|
|
21
21
|
// Format memory entry, starting with -, no timestamp
|
|
22
22
|
const memoryEntry = `- ${message.substring(1).trim()}\n`;
|
|
@@ -41,7 +41,7 @@ export const addMemory = async (
|
|
|
41
41
|
// Write file
|
|
42
42
|
await fs.writeFile(memoryFilePath, updatedContent, "utf-8");
|
|
43
43
|
|
|
44
|
-
// logger.
|
|
44
|
+
// logger.debug(`Memory added to ${memoryFilePath}:`, message);
|
|
45
45
|
} catch (error) {
|
|
46
46
|
// logger.error("Failed to add memory:", error);
|
|
47
47
|
throw new Error(`Failed to add memory: ${(error as Error).message}`);
|
|
@@ -63,7 +63,7 @@ export const ensureUserMemoryFile = async (): Promise<void> => {
|
|
|
63
63
|
const initialContent =
|
|
64
64
|
"# User Memory\n\nThis is the user-level memory file, recording important information and context across projects.\n\n";
|
|
65
65
|
await fs.writeFile(USER_MEMORY_FILE, initialContent, "utf-8");
|
|
66
|
-
// logger.
|
|
66
|
+
// logger.debug(`Created user memory file: ${USER_MEMORY_FILE}`);
|
|
67
67
|
} else {
|
|
68
68
|
throw error;
|
|
69
69
|
}
|
|
@@ -93,7 +93,7 @@ export const addUserMemory = async (message: string): Promise<void> => {
|
|
|
93
93
|
// Write file
|
|
94
94
|
await fs.writeFile(USER_MEMORY_FILE, updatedContent, "utf-8");
|
|
95
95
|
|
|
96
|
-
// logger.
|
|
96
|
+
// logger.debug(`User memory added to ${USER_MEMORY_FILE}:`, message);
|
|
97
97
|
} catch (error) {
|
|
98
98
|
// logger.error("Failed to add user memory:", error);
|
|
99
99
|
throw new Error(`Failed to add user memory: ${(error as Error).message}`);
|
|
@@ -113,7 +113,7 @@ export const getUserMemoryContent = async (): Promise<string> => {
|
|
|
113
113
|
// Read project memory file content
|
|
114
114
|
export const readMemoryFile = async (workdir: string): Promise<string> => {
|
|
115
115
|
try {
|
|
116
|
-
const memoryFilePath = path.join(workdir, "
|
|
116
|
+
const memoryFilePath = path.join(workdir, "AGENTS.md");
|
|
117
117
|
return await fs.readFile(memoryFilePath, "utf-8");
|
|
118
118
|
} catch (error) {
|
|
119
119
|
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
package/src/services/session.ts
CHANGED
|
@@ -30,12 +30,23 @@ const SESSION_DIR = join(homedir(), ".wave", "sessions");
|
|
|
30
30
|
const VERSION = "1.0.0";
|
|
31
31
|
const MAX_SESSION_AGE_DAYS = 30;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Resolve session directory path with fallback to default
|
|
35
|
+
* @param sessionDir Optional custom session directory
|
|
36
|
+
* @returns Resolved session directory path
|
|
37
|
+
*/
|
|
38
|
+
export function resolveSessionDir(sessionDir?: string): string {
|
|
39
|
+
return sessionDir || SESSION_DIR;
|
|
40
|
+
}
|
|
41
|
+
|
|
33
42
|
/**
|
|
34
43
|
* Ensure session directory exists
|
|
44
|
+
* @param sessionDir Optional custom session directory
|
|
35
45
|
*/
|
|
36
|
-
async function ensureSessionDir(): Promise<void> {
|
|
46
|
+
export async function ensureSessionDir(sessionDir?: string): Promise<void> {
|
|
47
|
+
const resolvedDir = resolveSessionDir(sessionDir);
|
|
37
48
|
try {
|
|
38
|
-
await fs.mkdir(
|
|
49
|
+
await fs.mkdir(resolvedDir, { recursive: true });
|
|
39
50
|
} catch (error) {
|
|
40
51
|
throw new Error(`Failed to create session directory: ${error}`);
|
|
41
52
|
}
|
|
@@ -44,9 +55,13 @@ async function ensureSessionDir(): Promise<void> {
|
|
|
44
55
|
/**
|
|
45
56
|
* Generate session file path
|
|
46
57
|
*/
|
|
47
|
-
export function getSessionFilePath(
|
|
58
|
+
export function getSessionFilePath(
|
|
59
|
+
sessionId: string,
|
|
60
|
+
sessionDir?: string,
|
|
61
|
+
): string {
|
|
48
62
|
const shortId = sessionId.split("_")[2] || sessionId.slice(-8);
|
|
49
|
-
|
|
63
|
+
const resolvedDir = resolveSessionDir(sessionDir);
|
|
64
|
+
return join(resolvedDir, `session_${shortId}.json`);
|
|
50
65
|
}
|
|
51
66
|
|
|
52
67
|
/**
|
|
@@ -62,7 +77,15 @@ function filterDiffBlocks(messages: Message[]): Message[] {
|
|
|
62
77
|
}
|
|
63
78
|
|
|
64
79
|
/**
|
|
65
|
-
* Save session data
|
|
80
|
+
* Save session data to storage
|
|
81
|
+
*
|
|
82
|
+
* @param sessionId - Unique identifier for the session
|
|
83
|
+
* @param messages - Array of messages to save
|
|
84
|
+
* @param workdir - Working directory for the session
|
|
85
|
+
* @param latestTotalTokens - Total tokens used in the session
|
|
86
|
+
* @param startedAt - ISO timestamp when session started (defaults to current time)
|
|
87
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
88
|
+
* @throws {Error} When session cannot be saved due to permission or disk space issues
|
|
66
89
|
*/
|
|
67
90
|
export async function saveSession(
|
|
68
91
|
sessionId: string,
|
|
@@ -70,6 +93,7 @@ export async function saveSession(
|
|
|
70
93
|
workdir: string,
|
|
71
94
|
latestTotalTokens: number = 0,
|
|
72
95
|
startedAt?: string,
|
|
96
|
+
sessionDir?: string,
|
|
73
97
|
): Promise<void> {
|
|
74
98
|
// Do not save session files in test environment
|
|
75
99
|
if (process.env.NODE_ENV === "test") {
|
|
@@ -81,7 +105,7 @@ export async function saveSession(
|
|
|
81
105
|
return;
|
|
82
106
|
}
|
|
83
107
|
|
|
84
|
-
await ensureSessionDir();
|
|
108
|
+
await ensureSessionDir(sessionDir);
|
|
85
109
|
|
|
86
110
|
// Filter out diff blocks before saving
|
|
87
111
|
const filteredMessages = filterDiffBlocks(messages);
|
|
@@ -100,7 +124,7 @@ export async function saveSession(
|
|
|
100
124
|
},
|
|
101
125
|
};
|
|
102
126
|
|
|
103
|
-
const filePath = getSessionFilePath(sessionId);
|
|
127
|
+
const filePath = getSessionFilePath(sessionId, sessionDir);
|
|
104
128
|
try {
|
|
105
129
|
await fs.writeFile(filePath, JSON.stringify(sessionData, null, 2), "utf-8");
|
|
106
130
|
} catch (error) {
|
|
@@ -109,12 +133,18 @@ export async function saveSession(
|
|
|
109
133
|
}
|
|
110
134
|
|
|
111
135
|
/**
|
|
112
|
-
* Load session data
|
|
136
|
+
* Load session data from storage
|
|
137
|
+
*
|
|
138
|
+
* @param sessionId - Unique identifier for the session to load
|
|
139
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
140
|
+
* @returns Promise that resolves to session data or null if session doesn't exist
|
|
141
|
+
* @throws {Error} When session exists but cannot be read or contains invalid data
|
|
113
142
|
*/
|
|
114
143
|
export async function loadSession(
|
|
115
144
|
sessionId: string,
|
|
145
|
+
sessionDir?: string,
|
|
116
146
|
): Promise<SessionData | null> {
|
|
117
|
-
const filePath = getSessionFilePath(sessionId);
|
|
147
|
+
const filePath = getSessionFilePath(sessionId, sessionDir);
|
|
118
148
|
|
|
119
149
|
try {
|
|
120
150
|
const content = await fs.readFile(filePath, "utf-8");
|
|
@@ -135,12 +165,18 @@ export async function loadSession(
|
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
/**
|
|
138
|
-
* Get most recent session
|
|
168
|
+
* Get the most recent session for a specific working directory
|
|
169
|
+
*
|
|
170
|
+
* @param workdir - Working directory to find the most recent session for
|
|
171
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
172
|
+
* @returns Promise that resolves to the most recent session data or null if no sessions exist
|
|
173
|
+
* @throws {Error} When session directory cannot be accessed or session data is corrupted
|
|
139
174
|
*/
|
|
140
175
|
export async function getLatestSession(
|
|
141
176
|
workdir: string,
|
|
177
|
+
sessionDir?: string,
|
|
142
178
|
): Promise<SessionData | null> {
|
|
143
|
-
const sessions = await listSessions(workdir);
|
|
179
|
+
const sessions = await listSessions(workdir, false, sessionDir);
|
|
144
180
|
if (sessions.length === 0) {
|
|
145
181
|
return null;
|
|
146
182
|
}
|
|
@@ -151,19 +187,27 @@ export async function getLatestSession(
|
|
|
151
187
|
new Date(b.lastActiveAt).getTime() - new Date(a.lastActiveAt).getTime(),
|
|
152
188
|
)[0];
|
|
153
189
|
|
|
154
|
-
return loadSession(latestSession.id);
|
|
190
|
+
return loadSession(latestSession.id, sessionDir);
|
|
155
191
|
}
|
|
156
192
|
|
|
157
193
|
/**
|
|
158
|
-
* List all sessions
|
|
194
|
+
* List all sessions for a specific working directory or across all working directories
|
|
195
|
+
*
|
|
196
|
+
* @param workdir - Working directory to filter sessions by
|
|
197
|
+
* @param includeAllWorkdirs - If true, returns sessions from all working directories
|
|
198
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
199
|
+
* @returns Promise that resolves to array of session metadata objects
|
|
200
|
+
* @throws {Error} When session directory cannot be accessed or read
|
|
159
201
|
*/
|
|
160
202
|
export async function listSessions(
|
|
161
203
|
workdir: string,
|
|
162
204
|
includeAllWorkdirs = false,
|
|
205
|
+
sessionDir?: string,
|
|
163
206
|
): Promise<SessionMetadata[]> {
|
|
164
207
|
try {
|
|
165
|
-
await ensureSessionDir();
|
|
166
|
-
const
|
|
208
|
+
await ensureSessionDir(sessionDir);
|
|
209
|
+
const resolvedDir = resolveSessionDir(sessionDir);
|
|
210
|
+
const files = await fs.readdir(resolvedDir);
|
|
167
211
|
|
|
168
212
|
const sessions: SessionMetadata[] = [];
|
|
169
213
|
|
|
@@ -173,7 +217,7 @@ export async function listSessions(
|
|
|
173
217
|
}
|
|
174
218
|
|
|
175
219
|
try {
|
|
176
|
-
const filePath = join(
|
|
220
|
+
const filePath = join(resolvedDir, file);
|
|
177
221
|
const content = await fs.readFile(filePath, "utf-8");
|
|
178
222
|
const sessionData = JSON.parse(content) as SessionData;
|
|
179
223
|
|
|
@@ -206,10 +250,18 @@ export async function listSessions(
|
|
|
206
250
|
}
|
|
207
251
|
|
|
208
252
|
/**
|
|
209
|
-
* Delete session
|
|
253
|
+
* Delete a session from storage
|
|
254
|
+
*
|
|
255
|
+
* @param sessionId - Unique identifier for the session to delete
|
|
256
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
257
|
+
* @returns Promise that resolves to true if session was deleted, false if it didn't exist
|
|
258
|
+
* @throws {Error} When session exists but cannot be deleted due to permission issues
|
|
210
259
|
*/
|
|
211
|
-
export async function deleteSession(
|
|
212
|
-
|
|
260
|
+
export async function deleteSession(
|
|
261
|
+
sessionId: string,
|
|
262
|
+
sessionDir?: string,
|
|
263
|
+
): Promise<boolean> {
|
|
264
|
+
const filePath = getSessionFilePath(sessionId, sessionDir);
|
|
213
265
|
|
|
214
266
|
try {
|
|
215
267
|
await fs.unlink(filePath);
|
|
@@ -223,15 +275,23 @@ export async function deleteSession(sessionId: string): Promise<boolean> {
|
|
|
223
275
|
}
|
|
224
276
|
|
|
225
277
|
/**
|
|
226
|
-
* Clean up expired sessions
|
|
278
|
+
* Clean up expired sessions older than the configured maximum age
|
|
279
|
+
*
|
|
280
|
+
* @param workdir - Working directory to clean up sessions for
|
|
281
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
282
|
+
* @returns Promise that resolves to the number of sessions that were deleted
|
|
283
|
+
* @throws {Error} When session directory cannot be accessed or sessions cannot be deleted
|
|
227
284
|
*/
|
|
228
|
-
export async function cleanupExpiredSessions(
|
|
285
|
+
export async function cleanupExpiredSessions(
|
|
286
|
+
workdir: string,
|
|
287
|
+
sessionDir?: string,
|
|
288
|
+
): Promise<number> {
|
|
229
289
|
// Do not perform cleanup operations in test environment
|
|
230
290
|
if (process.env.NODE_ENV === "test") {
|
|
231
291
|
return 0;
|
|
232
292
|
}
|
|
233
293
|
|
|
234
|
-
const sessions = await listSessions(workdir, true);
|
|
294
|
+
const sessions = await listSessions(workdir, true, sessionDir);
|
|
235
295
|
const now = new Date();
|
|
236
296
|
const maxAge = MAX_SESSION_AGE_DAYS * 24 * 60 * 60 * 1000; // Convert to milliseconds
|
|
237
297
|
|
|
@@ -242,7 +302,7 @@ export async function cleanupExpiredSessions(workdir: string): Promise<number> {
|
|
|
242
302
|
|
|
243
303
|
if (sessionAge > maxAge) {
|
|
244
304
|
try {
|
|
245
|
-
await deleteSession(session.id);
|
|
305
|
+
await deleteSession(session.id, sessionDir);
|
|
246
306
|
deletedCount++;
|
|
247
307
|
} catch (error) {
|
|
248
308
|
console.warn(
|
|
@@ -256,10 +316,17 @@ export async function cleanupExpiredSessions(workdir: string): Promise<number> {
|
|
|
256
316
|
}
|
|
257
317
|
|
|
258
318
|
/**
|
|
259
|
-
* Check if session exists
|
|
319
|
+
* Check if a session exists in storage
|
|
320
|
+
*
|
|
321
|
+
* @param sessionId - Unique identifier for the session to check
|
|
322
|
+
* @param sessionDir - Optional custom directory for session storage (defaults to ~/.wave/sessions/)
|
|
323
|
+
* @returns Promise that resolves to true if session exists, false otherwise
|
|
260
324
|
*/
|
|
261
|
-
export async function sessionExists(
|
|
262
|
-
|
|
325
|
+
export async function sessionExists(
|
|
326
|
+
sessionId: string,
|
|
327
|
+
sessionDir?: string,
|
|
328
|
+
): Promise<boolean> {
|
|
329
|
+
const filePath = getSessionFilePath(sessionId, sessionDir);
|
|
263
330
|
|
|
264
331
|
try {
|
|
265
332
|
await fs.access(filePath);
|
package/src/tools/bashTool.ts
CHANGED
|
@@ -44,10 +44,10 @@ export const bashTool: ToolPlugin = {
|
|
|
44
44
|
): Promise<ToolResult> => {
|
|
45
45
|
const command = args.command as string;
|
|
46
46
|
const runInBackground = args.run_in_background as boolean | undefined;
|
|
47
|
-
// Set default timeout:
|
|
47
|
+
// Set default timeout: 60s for foreground, no timeout for background
|
|
48
48
|
const timeout =
|
|
49
49
|
(args.timeout as number | undefined) ??
|
|
50
|
-
(runInBackground ? undefined :
|
|
50
|
+
(runInBackground ? undefined : 60000);
|
|
51
51
|
|
|
52
52
|
if (!command || typeof command !== "string") {
|
|
53
53
|
return {
|
package/src/tools/editTool.ts
CHANGED
|
@@ -160,7 +160,7 @@ export const editTool: ToolPlugin = {
|
|
|
160
160
|
? `Replaced ${replacementCount} instances`
|
|
161
161
|
: "Text replaced successfully";
|
|
162
162
|
|
|
163
|
-
// logger.
|
|
163
|
+
// logger.debug(`Edit tool: ${shortResult}`);
|
|
164
164
|
|
|
165
165
|
return {
|
|
166
166
|
success: true,
|
|
@@ -149,7 +149,7 @@ export const multiEditTool: ToolPlugin = {
|
|
|
149
149
|
if (edits[0] && edits[0].old_string === "") {
|
|
150
150
|
originalContent = "";
|
|
151
151
|
isNewFile = true;
|
|
152
|
-
// logger.
|
|
152
|
+
// logger.debug(`Creating new file: ${resolvedPath}`);
|
|
153
153
|
} else {
|
|
154
154
|
return {
|
|
155
155
|
success: false,
|
|
@@ -236,7 +236,7 @@ export const multiEditTool: ToolPlugin = {
|
|
|
236
236
|
|
|
237
237
|
const detailedContent = `${shortResult}\n\nOperations performed:\n${appliedEdits.map((edit, i) => `${i + 1}. ${edit}`).join("\n")}`;
|
|
238
238
|
|
|
239
|
-
// logger.
|
|
239
|
+
// logger.debug(`MultiEdit tool: ${shortResult}`);
|
|
240
240
|
|
|
241
241
|
return {
|
|
242
242
|
success: true,
|
package/src/tools/writeTool.ts
CHANGED
|
@@ -121,7 +121,7 @@ export const writeTool: ToolPlugin = {
|
|
|
121
121
|
const chars = content.length;
|
|
122
122
|
const detailedContent = `${shortResult} (${lines} lines, ${chars} characters)`;
|
|
123
123
|
|
|
124
|
-
// logger.
|
|
124
|
+
// logger.debug(`Write tool: ${shortResult}`);
|
|
125
125
|
|
|
126
126
|
return {
|
|
127
127
|
success: true,
|
package/src/types.ts
CHANGED
|
@@ -14,6 +14,7 @@ export interface Logger {
|
|
|
14
14
|
export interface Message {
|
|
15
15
|
role: "user" | "assistant";
|
|
16
16
|
blocks: MessageBlock[];
|
|
17
|
+
usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export type MessageBlock =
|
|
@@ -332,6 +333,18 @@ export class ConfigurationError extends Error {
|
|
|
332
333
|
}
|
|
333
334
|
}
|
|
334
335
|
|
|
336
|
+
/**
|
|
337
|
+
* Usage statistics for AI operations
|
|
338
|
+
* Extends OpenAI's Usage format with additional tracking fields
|
|
339
|
+
*/
|
|
340
|
+
export interface Usage {
|
|
341
|
+
prompt_tokens: number; // Tokens used in prompts
|
|
342
|
+
completion_tokens: number; // Tokens generated in completions
|
|
343
|
+
total_tokens: number; // Sum of prompt + completion tokens
|
|
344
|
+
model?: string; // Model used for the operation (e.g., "gpt-4", "gpt-3.5-turbo")
|
|
345
|
+
operation_type?: "agent" | "compress"; // Type of operation that generated usage
|
|
346
|
+
}
|
|
347
|
+
|
|
335
348
|
// Standard error messages
|
|
336
349
|
export const CONFIG_ERRORS = {
|
|
337
350
|
MISSING_API_KEY:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Message } from "../types.js";
|
|
1
|
+
import type { Message, Usage } from "../types.js";
|
|
2
2
|
import { readFileSync } from "fs";
|
|
3
3
|
import { extname } from "path";
|
|
4
4
|
import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
|
|
@@ -177,6 +177,7 @@ export const addAssistantMessageToMessages = (
|
|
|
177
177
|
messages: Message[],
|
|
178
178
|
content?: string,
|
|
179
179
|
toolCalls?: ChatCompletionMessageFunctionToolCall[],
|
|
180
|
+
usage?: Usage,
|
|
180
181
|
): Message[] => {
|
|
181
182
|
const blocks: Message["blocks"] = [];
|
|
182
183
|
|
|
@@ -202,6 +203,7 @@ export const addAssistantMessageToMessages = (
|
|
|
202
203
|
const initialAssistantMessage: Message = {
|
|
203
204
|
role: "assistant",
|
|
204
205
|
blocks,
|
|
206
|
+
usage, // Include usage data if provided
|
|
205
207
|
};
|
|
206
208
|
|
|
207
209
|
return [...messages, initialAssistantMessage];
|