wave-agent-sdk 0.0.1

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.
Files changed (170) hide show
  1. package/README.md +32 -0
  2. package/dist/agent.d.ts +96 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +286 -0
  5. package/dist/hooks/executor.d.ts +56 -0
  6. package/dist/hooks/executor.d.ts.map +1 -0
  7. package/dist/hooks/executor.js +312 -0
  8. package/dist/hooks/index.d.ts +17 -0
  9. package/dist/hooks/index.d.ts.map +1 -0
  10. package/dist/hooks/index.js +14 -0
  11. package/dist/hooks/manager.d.ts +90 -0
  12. package/dist/hooks/manager.d.ts.map +1 -0
  13. package/dist/hooks/manager.js +395 -0
  14. package/dist/hooks/matcher.d.ts +49 -0
  15. package/dist/hooks/matcher.d.ts.map +1 -0
  16. package/dist/hooks/matcher.js +147 -0
  17. package/dist/hooks/settings.d.ts +46 -0
  18. package/dist/hooks/settings.d.ts.map +1 -0
  19. package/dist/hooks/settings.js +100 -0
  20. package/dist/hooks/types.d.ts +80 -0
  21. package/dist/hooks/types.d.ts.map +1 -0
  22. package/dist/hooks/types.js +59 -0
  23. package/dist/index.d.ts +16 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +20 -0
  26. package/dist/managers/aiManager.d.ts +61 -0
  27. package/dist/managers/aiManager.d.ts.map +1 -0
  28. package/dist/managers/aiManager.js +415 -0
  29. package/dist/managers/backgroundBashManager.d.ts +27 -0
  30. package/dist/managers/backgroundBashManager.d.ts.map +1 -0
  31. package/dist/managers/backgroundBashManager.js +166 -0
  32. package/dist/managers/bashManager.d.ts +20 -0
  33. package/dist/managers/bashManager.d.ts.map +1 -0
  34. package/dist/managers/bashManager.js +66 -0
  35. package/dist/managers/mcpManager.d.ts +63 -0
  36. package/dist/managers/mcpManager.d.ts.map +1 -0
  37. package/dist/managers/mcpManager.js +378 -0
  38. package/dist/managers/messageManager.d.ts +85 -0
  39. package/dist/managers/messageManager.d.ts.map +1 -0
  40. package/dist/managers/messageManager.js +265 -0
  41. package/dist/managers/skillManager.d.ts +59 -0
  42. package/dist/managers/skillManager.d.ts.map +1 -0
  43. package/dist/managers/skillManager.js +317 -0
  44. package/dist/managers/slashCommandManager.d.ts +77 -0
  45. package/dist/managers/slashCommandManager.d.ts.map +1 -0
  46. package/dist/managers/slashCommandManager.js +208 -0
  47. package/dist/managers/toolManager.d.ts +23 -0
  48. package/dist/managers/toolManager.d.ts.map +1 -0
  49. package/dist/managers/toolManager.js +79 -0
  50. package/dist/services/aiService.d.ts +28 -0
  51. package/dist/services/aiService.d.ts.map +1 -0
  52. package/dist/services/aiService.js +180 -0
  53. package/dist/services/memory.d.ts +8 -0
  54. package/dist/services/memory.d.ts.map +1 -0
  55. package/dist/services/memory.js +128 -0
  56. package/dist/services/session.d.ts +54 -0
  57. package/dist/services/session.d.ts.map +1 -0
  58. package/dist/services/session.js +196 -0
  59. package/dist/tools/bashTool.d.ts +14 -0
  60. package/dist/tools/bashTool.d.ts.map +1 -0
  61. package/dist/tools/bashTool.js +351 -0
  62. package/dist/tools/deleteFileTool.d.ts +6 -0
  63. package/dist/tools/deleteFileTool.d.ts.map +1 -0
  64. package/dist/tools/deleteFileTool.js +67 -0
  65. package/dist/tools/editTool.d.ts +6 -0
  66. package/dist/tools/editTool.d.ts.map +1 -0
  67. package/dist/tools/editTool.js +168 -0
  68. package/dist/tools/globTool.d.ts +6 -0
  69. package/dist/tools/globTool.d.ts.map +1 -0
  70. package/dist/tools/globTool.js +113 -0
  71. package/dist/tools/grepTool.d.ts +6 -0
  72. package/dist/tools/grepTool.d.ts.map +1 -0
  73. package/dist/tools/grepTool.js +268 -0
  74. package/dist/tools/lsTool.d.ts +6 -0
  75. package/dist/tools/lsTool.d.ts.map +1 -0
  76. package/dist/tools/lsTool.js +160 -0
  77. package/dist/tools/multiEditTool.d.ts +6 -0
  78. package/dist/tools/multiEditTool.d.ts.map +1 -0
  79. package/dist/tools/multiEditTool.js +222 -0
  80. package/dist/tools/readTool.d.ts +6 -0
  81. package/dist/tools/readTool.d.ts.map +1 -0
  82. package/dist/tools/readTool.js +136 -0
  83. package/dist/tools/types.d.ts +35 -0
  84. package/dist/tools/types.d.ts.map +1 -0
  85. package/dist/tools/types.js +4 -0
  86. package/dist/tools/writeTool.d.ts +6 -0
  87. package/dist/tools/writeTool.d.ts.map +1 -0
  88. package/dist/tools/writeTool.js +138 -0
  89. package/dist/types.d.ts +212 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +13 -0
  92. package/dist/utils/bashHistory.d.ts +46 -0
  93. package/dist/utils/bashHistory.d.ts.map +1 -0
  94. package/dist/utils/bashHistory.js +236 -0
  95. package/dist/utils/commandArgumentParser.d.ts +34 -0
  96. package/dist/utils/commandArgumentParser.d.ts.map +1 -0
  97. package/dist/utils/commandArgumentParser.js +123 -0
  98. package/dist/utils/constants.d.ts +27 -0
  99. package/dist/utils/constants.d.ts.map +1 -0
  100. package/dist/utils/constants.js +28 -0
  101. package/dist/utils/convertMessagesForAPI.d.ts +9 -0
  102. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -0
  103. package/dist/utils/convertMessagesForAPI.js +189 -0
  104. package/dist/utils/customCommands.d.ts +14 -0
  105. package/dist/utils/customCommands.d.ts.map +1 -0
  106. package/dist/utils/customCommands.js +71 -0
  107. package/dist/utils/fileFilter.d.ts +26 -0
  108. package/dist/utils/fileFilter.d.ts.map +1 -0
  109. package/dist/utils/fileFilter.js +177 -0
  110. package/dist/utils/markdownParser.d.ts +27 -0
  111. package/dist/utils/markdownParser.d.ts.map +1 -0
  112. package/dist/utils/markdownParser.js +109 -0
  113. package/dist/utils/mcpUtils.d.ts +24 -0
  114. package/dist/utils/mcpUtils.d.ts.map +1 -0
  115. package/dist/utils/mcpUtils.js +51 -0
  116. package/dist/utils/messageOperations.d.ts +118 -0
  117. package/dist/utils/messageOperations.d.ts.map +1 -0
  118. package/dist/utils/messageOperations.js +334 -0
  119. package/dist/utils/path.d.ts +25 -0
  120. package/dist/utils/path.d.ts.map +1 -0
  121. package/dist/utils/path.js +109 -0
  122. package/dist/utils/skillParser.d.ts +18 -0
  123. package/dist/utils/skillParser.d.ts.map +1 -0
  124. package/dist/utils/skillParser.js +147 -0
  125. package/dist/utils/stringUtils.d.ts +13 -0
  126. package/dist/utils/stringUtils.d.ts.map +1 -0
  127. package/dist/utils/stringUtils.js +44 -0
  128. package/package.json +51 -0
  129. package/src/agent.ts +405 -0
  130. package/src/hooks/executor.ts +440 -0
  131. package/src/hooks/index.ts +52 -0
  132. package/src/hooks/manager.ts +618 -0
  133. package/src/hooks/matcher.ts +187 -0
  134. package/src/hooks/settings.ts +129 -0
  135. package/src/hooks/types.ts +169 -0
  136. package/src/index.ts +24 -0
  137. package/src/managers/aiManager.ts +573 -0
  138. package/src/managers/backgroundBashManager.ts +203 -0
  139. package/src/managers/bashManager.ts +97 -0
  140. package/src/managers/mcpManager.ts +493 -0
  141. package/src/managers/messageManager.ts +415 -0
  142. package/src/managers/skillManager.ts +404 -0
  143. package/src/managers/slashCommandManager.ts +293 -0
  144. package/src/managers/toolManager.ts +106 -0
  145. package/src/services/aiService.ts +252 -0
  146. package/src/services/memory.ts +149 -0
  147. package/src/services/session.ts +265 -0
  148. package/src/tools/bashTool.ts +402 -0
  149. package/src/tools/deleteFileTool.ts +81 -0
  150. package/src/tools/editTool.ts +192 -0
  151. package/src/tools/globTool.ts +135 -0
  152. package/src/tools/grepTool.ts +326 -0
  153. package/src/tools/lsTool.ts +187 -0
  154. package/src/tools/multiEditTool.ts +268 -0
  155. package/src/tools/readTool.ts +165 -0
  156. package/src/tools/types.ts +47 -0
  157. package/src/tools/writeTool.ts +163 -0
  158. package/src/types.ts +260 -0
  159. package/src/utils/bashHistory.ts +303 -0
  160. package/src/utils/commandArgumentParser.ts +153 -0
  161. package/src/utils/constants.ts +37 -0
  162. package/src/utils/convertMessagesForAPI.ts +236 -0
  163. package/src/utils/customCommands.ts +85 -0
  164. package/src/utils/fileFilter.ts +202 -0
  165. package/src/utils/markdownParser.ts +156 -0
  166. package/src/utils/mcpUtils.ts +81 -0
  167. package/src/utils/messageOperations.ts +506 -0
  168. package/src/utils/path.ts +118 -0
  169. package/src/utils/skillParser.ts +188 -0
  170. package/src/utils/stringUtils.ts +50 -0
@@ -0,0 +1,415 @@
1
+ import { randomUUID } from "crypto";
2
+ import {
3
+ addAssistantMessageToMessages,
4
+ updateToolBlockInMessage,
5
+ addErrorBlockToMessage,
6
+ addDiffBlockToMessage,
7
+ addUserMessageToMessages,
8
+ extractUserInputHistory,
9
+ addMemoryBlockToMessage,
10
+ addCommandOutputMessage,
11
+ updateCommandOutputInMessage,
12
+ completeCommandInMessage,
13
+ type AgentToolBlockUpdateParams,
14
+ } from "../utils/messageOperations.js";
15
+ import type { Logger, Message } from "../types.js";
16
+ import {
17
+ cleanupExpiredSessions,
18
+ getLatestSession,
19
+ loadSession,
20
+ saveSession,
21
+ SessionData,
22
+ getSessionFilePath,
23
+ } from "../services/session.js";
24
+ import { ChatCompletionMessageFunctionToolCall } from "openai/resources.js";
25
+
26
+ export interface MessageManagerCallbacks {
27
+ onMessagesChange?: (messages: Message[]) => void;
28
+ onSessionIdChange?: (sessionId: string) => void;
29
+ onLatestTotalTokensChange?: (latestTotalTokens: number) => void;
30
+ onUserInputHistoryChange?: (history: string[]) => void;
31
+ // Incremental callback
32
+ onUserMessageAdded?: (
33
+ content: string,
34
+ images?: Array<{ path: string; mimeType: string }>,
35
+ ) => void;
36
+ onAssistantMessageAdded?: (
37
+ content?: string,
38
+ toolCalls?: ChatCompletionMessageFunctionToolCall[],
39
+ ) => void;
40
+ onToolBlockUpdated?: (params: AgentToolBlockUpdateParams) => void;
41
+ onDiffBlockAdded?: (filePath: string, diffResult: string) => void;
42
+ onErrorBlockAdded?: (error: string) => void;
43
+ onCompressBlockAdded?: (insertIndex: number, content: string) => void;
44
+ onCompressionStateChange?: (isCompressing: boolean) => void;
45
+ onMemoryBlockAdded?: (
46
+ content: string,
47
+ success: boolean,
48
+ type: "project" | "user",
49
+ storagePath: string,
50
+ ) => void;
51
+ // Bash command callback
52
+ onAddCommandOutputMessage?: (command: string) => void;
53
+ onUpdateCommandOutputMessage?: (command: string, output: string) => void;
54
+ onCompleteCommandMessage?: (command: string, exitCode: number) => void;
55
+ }
56
+
57
+ export interface MessageManagerOptions {
58
+ callbacks: MessageManagerCallbacks;
59
+ workdir: string;
60
+ logger?: Logger;
61
+ }
62
+
63
+ export class MessageManager {
64
+ // Private state properties
65
+ private sessionId: string;
66
+ private messages: Message[];
67
+ private latestTotalTokens: number;
68
+ private userInputHistory: string[];
69
+ private sessionStartTime: string;
70
+ private workdir: string;
71
+ private logger?: Logger; // Add optional logger property
72
+ private callbacks: MessageManagerCallbacks;
73
+
74
+ constructor(options: MessageManagerOptions) {
75
+ this.sessionId = randomUUID();
76
+ this.messages = [];
77
+ this.latestTotalTokens = 0;
78
+ this.userInputHistory = [];
79
+ this.sessionStartTime = new Date().toISOString();
80
+ this.workdir = options.workdir;
81
+ this.callbacks = options.callbacks;
82
+ this.logger = options.logger;
83
+ }
84
+
85
+ // Getter methods
86
+ public getSessionId(): string {
87
+ return this.sessionId;
88
+ }
89
+
90
+ public getMessages(): Message[] {
91
+ return [...this.messages];
92
+ }
93
+
94
+ public getlatestTotalTokens(): number {
95
+ return this.latestTotalTokens;
96
+ }
97
+
98
+ public getUserInputHistory(): string[] {
99
+ return [...this.userInputHistory];
100
+ }
101
+
102
+ public getTranscriptPath(): string {
103
+ return getSessionFilePath(this.sessionId);
104
+ }
105
+
106
+ // Setter methods, will trigger callbacks
107
+ public setSessionId(sessionId: string): void {
108
+ if (this.sessionId !== sessionId) {
109
+ this.sessionId = sessionId;
110
+ this.callbacks.onSessionIdChange?.(sessionId);
111
+ }
112
+ }
113
+
114
+ public setMessages(messages: Message[]): void {
115
+ this.messages = [...messages];
116
+ this.callbacks.onMessagesChange?.([...messages]);
117
+ }
118
+
119
+ /**
120
+ * Save current session
121
+ */
122
+ public async saveSession(): Promise<void> {
123
+ try {
124
+ await saveSession(
125
+ this.sessionId,
126
+ this.messages,
127
+ this.workdir,
128
+ this.latestTotalTokens,
129
+ this.sessionStartTime,
130
+ );
131
+ } catch (error) {
132
+ this.logger?.error("Failed to save session:", error);
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Handle session restoration logic
138
+ */
139
+ public async handleSessionRestoration(
140
+ restoreSessionId?: string,
141
+ continueLastSession?: boolean,
142
+ ): Promise<void> {
143
+ // Clean up expired sessions first
144
+ try {
145
+ await cleanupExpiredSessions(this.workdir);
146
+ } catch (error) {
147
+ console.warn("Failed to cleanup expired sessions:", error);
148
+ }
149
+
150
+ if (!restoreSessionId && !continueLastSession) {
151
+ return;
152
+ }
153
+
154
+ try {
155
+ let sessionToRestore: SessionData | null = null;
156
+
157
+ if (restoreSessionId) {
158
+ sessionToRestore = await loadSession(restoreSessionId);
159
+ if (!sessionToRestore) {
160
+ console.error(`Session not found: ${restoreSessionId}`);
161
+ process.exit(1);
162
+ }
163
+ } else if (continueLastSession) {
164
+ sessionToRestore = await getLatestSession(this.workdir);
165
+ if (!sessionToRestore) {
166
+ console.error(
167
+ `No previous session found for workdir: ${this.workdir}`,
168
+ );
169
+ process.exit(1);
170
+ }
171
+ }
172
+
173
+ if (sessionToRestore) {
174
+ console.log(`Restoring session: ${sessionToRestore.id}`);
175
+
176
+ // Initialize from session data
177
+ this.initializeFromSession(
178
+ sessionToRestore.id,
179
+ sessionToRestore.messages,
180
+ sessionToRestore.metadata.latestTotalTokens,
181
+ );
182
+ }
183
+ } catch (error) {
184
+ console.error("Failed to restore session:", error);
185
+ process.exit(1);
186
+ }
187
+ }
188
+
189
+ public setlatestTotalTokens(latestTotalTokens: number): void {
190
+ if (this.latestTotalTokens !== latestTotalTokens) {
191
+ this.latestTotalTokens = latestTotalTokens;
192
+ this.callbacks.onLatestTotalTokensChange?.(latestTotalTokens);
193
+ }
194
+ }
195
+
196
+ public setUserInputHistory(userInputHistory: string[]): void {
197
+ this.userInputHistory = [...userInputHistory];
198
+ this.callbacks.onUserInputHistoryChange?.(this.userInputHistory);
199
+ }
200
+
201
+ /**
202
+ * Clear messages and input history
203
+ */
204
+ public clearMessages(): void {
205
+ this.setMessages([]);
206
+ this.setUserInputHistory([]);
207
+ this.setSessionId(randomUUID());
208
+ this.setlatestTotalTokens(0);
209
+ this.sessionStartTime = new Date().toISOString();
210
+ }
211
+
212
+ // Initialize state from session data
213
+ public initializeFromSession(
214
+ sessionId: string,
215
+ messages: Message[],
216
+ latestTotalTokens: number,
217
+ ): void {
218
+ this.setSessionId(sessionId);
219
+ this.setMessages([...messages]);
220
+ this.setlatestTotalTokens(latestTotalTokens);
221
+
222
+ // Extract user input history from session messages
223
+ this.setUserInputHistory(extractUserInputHistory(messages));
224
+ }
225
+
226
+ // Add to input history
227
+ public addToInputHistory(input: string): void {
228
+ // Avoid adding duplicate inputs
229
+ if (
230
+ this.userInputHistory.length > 0 &&
231
+ this.userInputHistory[this.userInputHistory.length - 1] === input
232
+ ) {
233
+ return;
234
+ }
235
+ // Limit history records, keep the latest 100
236
+ this.setUserInputHistory([...this.userInputHistory, input].slice(-100));
237
+ }
238
+
239
+ // Clear input history
240
+ public clearInputHistory(): void {
241
+ this.setUserInputHistory([]);
242
+ }
243
+
244
+ // Encapsulated message operation functions
245
+ public addUserMessage(
246
+ content: string,
247
+ images?: Array<{ path: string; mimeType: string }>,
248
+ ): void {
249
+ const newMessages = addUserMessageToMessages({
250
+ messages: this.messages,
251
+ content,
252
+ images,
253
+ });
254
+ this.setMessages(newMessages);
255
+ this.callbacks.onUserMessageAdded?.(content, images);
256
+ }
257
+
258
+ public addCustomCommandMessage(
259
+ commandName: string,
260
+ content: string,
261
+ originalInput?: string,
262
+ ): void {
263
+ const newMessages = addUserMessageToMessages({
264
+ messages: this.messages,
265
+ content: "", // Empty content, as we will use CustomCommandBlock
266
+ customCommandBlock: {
267
+ type: "custom_command",
268
+ commandName,
269
+ content,
270
+ originalInput,
271
+ },
272
+ });
273
+ this.setMessages(newMessages);
274
+ this.callbacks.onUserMessageAdded?.(content);
275
+ }
276
+
277
+ public addAssistantMessage(
278
+ content?: string,
279
+ toolCalls?: ChatCompletionMessageFunctionToolCall[],
280
+ ): void {
281
+ const newMessages = addAssistantMessageToMessages(
282
+ this.messages,
283
+ content,
284
+ toolCalls,
285
+ );
286
+ this.setMessages(newMessages);
287
+ this.callbacks.onAssistantMessageAdded?.(content, toolCalls);
288
+ }
289
+
290
+ public updateToolBlock(params: AgentToolBlockUpdateParams): void {
291
+ const newMessages = updateToolBlockInMessage({
292
+ messages: this.messages,
293
+ id: params.toolId,
294
+ parameters: params.args || "",
295
+ result: params.result,
296
+ success: params.success,
297
+ error: params.error,
298
+ isRunning: params.isRunning,
299
+ name: params.name,
300
+ shortResult: params.shortResult,
301
+ compactParams: params.compactParams,
302
+ });
303
+ this.setMessages(newMessages);
304
+ this.callbacks.onToolBlockUpdated?.(params);
305
+ }
306
+
307
+ public addDiffBlock(
308
+ filePath: string,
309
+ diffResult: Array<{ value: string; added?: boolean; removed?: boolean }>,
310
+ ): void {
311
+ const newMessages = addDiffBlockToMessage({
312
+ messages: this.messages,
313
+ path: filePath,
314
+ diffResult,
315
+ });
316
+ this.setMessages(newMessages);
317
+ this.callbacks.onDiffBlockAdded?.(filePath, JSON.stringify(diffResult));
318
+ }
319
+
320
+ public addErrorBlock(error: string): void {
321
+ const newMessages = addErrorBlockToMessage({
322
+ messages: this.messages,
323
+ error,
324
+ });
325
+ this.setMessages(newMessages);
326
+ this.callbacks.onErrorBlockAdded?.(error);
327
+ }
328
+
329
+ /**
330
+ * Compress messages and update session, delete compressed messages, only keep compressed messages and subsequent messages
331
+ */
332
+ public compressMessagesAndUpdateSession(
333
+ insertIndex: number,
334
+ compressedContent: string,
335
+ ): void {
336
+ const currentMessages = this.messages;
337
+
338
+ // Create compressed message
339
+ const compressMessage: Message = {
340
+ role: "assistant",
341
+ blocks: [
342
+ {
343
+ type: "compress",
344
+ content: compressedContent,
345
+ },
346
+ ],
347
+ };
348
+
349
+ // Convert negative index to positive index
350
+ const actualIndex =
351
+ insertIndex < 0 ? currentMessages.length + insertIndex : insertIndex;
352
+
353
+ // Build new message array: keep compressed message and all messages from actualIndex onwards
354
+ const newMessages: Message[] = [
355
+ compressMessage,
356
+ ...currentMessages.slice(actualIndex),
357
+ ];
358
+
359
+ // Update sessionId
360
+ this.setSessionId(randomUUID());
361
+
362
+ // Set new message list
363
+ this.setMessages(newMessages);
364
+
365
+ // Trigger compression callback, insertIndex remains unchanged
366
+ this.callbacks.onCompressBlockAdded?.(insertIndex, compressedContent);
367
+ }
368
+
369
+ public addMemoryBlock(
370
+ content: string,
371
+ success: boolean,
372
+ type: "project" | "user",
373
+ storagePath: string,
374
+ ): void {
375
+ const newMessages = addMemoryBlockToMessage({
376
+ messages: this.messages,
377
+ content,
378
+ isSuccess: success,
379
+ memoryType: type,
380
+ storagePath,
381
+ });
382
+ this.setMessages(newMessages);
383
+ this.callbacks.onMemoryBlockAdded?.(content, success, type, storagePath);
384
+ }
385
+
386
+ // Bash command related message operations
387
+ public addCommandOutputMessage(command: string): void {
388
+ const updatedMessages = addCommandOutputMessage({
389
+ messages: this.messages,
390
+ command,
391
+ });
392
+ this.setMessages(updatedMessages);
393
+ this.callbacks.onAddCommandOutputMessage?.(command);
394
+ }
395
+
396
+ public updateCommandOutputMessage(command: string, output: string): void {
397
+ const updatedMessages = updateCommandOutputInMessage({
398
+ messages: this.messages,
399
+ command,
400
+ output,
401
+ });
402
+ this.setMessages(updatedMessages);
403
+ this.callbacks.onUpdateCommandOutputMessage?.(command, output);
404
+ }
405
+
406
+ public completeCommandMessage(command: string, exitCode: number): void {
407
+ const updatedMessages = completeCommandInMessage({
408
+ messages: this.messages,
409
+ command,
410
+ exitCode,
411
+ });
412
+ this.setMessages(updatedMessages);
413
+ this.callbacks.onCompleteCommandMessage?.(command, exitCode);
414
+ }
415
+ }