wave-agent-sdk 0.11.5 → 0.11.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/builtin/skills/init/SKILL.md +2 -0
  2. package/builtin/skills/settings/SKILLS.md +3 -2
  3. package/builtin/skills/settings/SUBAGENTS.md +1 -3
  4. package/dist/agent.d.ts +6 -0
  5. package/dist/agent.d.ts.map +1 -1
  6. package/dist/agent.js +18 -1
  7. package/dist/constants/tools.d.ts +1 -1
  8. package/dist/constants/tools.d.ts.map +1 -1
  9. package/dist/constants/tools.js +1 -1
  10. package/dist/managers/MemoryRuleManager.d.ts.map +1 -1
  11. package/dist/managers/MemoryRuleManager.js +1 -9
  12. package/dist/managers/aiManager.d.ts.map +1 -1
  13. package/dist/managers/aiManager.js +22 -3
  14. package/dist/managers/mcpManager.d.ts.map +1 -1
  15. package/dist/managers/mcpManager.js +32 -13
  16. package/dist/managers/messageManager.d.ts +13 -5
  17. package/dist/managers/messageManager.d.ts.map +1 -1
  18. package/dist/managers/messageManager.js +62 -34
  19. package/dist/managers/permissionManager.js +4 -4
  20. package/dist/managers/pluginManager.d.ts.map +1 -1
  21. package/dist/managers/pluginManager.js +4 -2
  22. package/dist/managers/slashCommandManager.d.ts +2 -0
  23. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  24. package/dist/managers/slashCommandManager.js +98 -4
  25. package/dist/managers/toolManager.d.ts.map +1 -1
  26. package/dist/managers/toolManager.js +8 -2
  27. package/dist/prompts/index.d.ts +2 -0
  28. package/dist/prompts/index.d.ts.map +1 -1
  29. package/dist/prompts/index.js +5 -0
  30. package/dist/services/GitService.d.ts +1 -0
  31. package/dist/services/GitService.d.ts.map +1 -1
  32. package/dist/services/GitService.js +16 -0
  33. package/dist/services/MarketplaceService.d.ts +7 -0
  34. package/dist/services/MarketplaceService.d.ts.map +1 -1
  35. package/dist/services/MarketplaceService.js +321 -252
  36. package/dist/services/aiService.d.ts +34 -0
  37. package/dist/services/aiService.d.ts.map +1 -1
  38. package/dist/services/aiService.js +124 -1
  39. package/dist/services/initializationService.d.ts.map +1 -1
  40. package/dist/services/initializationService.js +18 -0
  41. package/dist/tools/agentTool.js +3 -3
  42. package/dist/tools/bashTool.d.ts.map +1 -1
  43. package/dist/tools/bashTool.js +4 -4
  44. package/dist/tools/editTool.d.ts.map +1 -1
  45. package/dist/tools/editTool.js +2 -0
  46. package/dist/tools/globTool.d.ts.map +1 -1
  47. package/dist/tools/globTool.js +15 -3
  48. package/dist/tools/grepTool.d.ts.map +1 -1
  49. package/dist/tools/grepTool.js +38 -12
  50. package/dist/tools/readTool.d.ts.map +1 -1
  51. package/dist/tools/readTool.js +61 -0
  52. package/dist/tools/skillTool.js +2 -2
  53. package/dist/tools/types.d.ts +16 -0
  54. package/dist/tools/types.d.ts.map +1 -1
  55. package/dist/tools/webFetchTool.d.ts +3 -0
  56. package/dist/tools/webFetchTool.d.ts.map +1 -0
  57. package/dist/tools/webFetchTool.js +171 -0
  58. package/dist/tools/writeTool.d.ts.map +1 -1
  59. package/dist/tools/writeTool.js +2 -0
  60. package/dist/types/commands.d.ts +1 -1
  61. package/dist/types/commands.d.ts.map +1 -1
  62. package/dist/types/messaging.d.ts +1 -0
  63. package/dist/types/messaging.d.ts.map +1 -1
  64. package/dist/utils/bashParser.d.ts +20 -2
  65. package/dist/utils/bashParser.d.ts.map +1 -1
  66. package/dist/utils/bashParser.js +281 -146
  67. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  68. package/dist/utils/convertMessagesForAPI.js +7 -0
  69. package/dist/utils/fileUtils.d.ts +8 -0
  70. package/dist/utils/fileUtils.d.ts.map +1 -1
  71. package/dist/utils/fileUtils.js +52 -0
  72. package/dist/utils/messageOperations.d.ts +12 -3
  73. package/dist/utils/messageOperations.d.ts.map +1 -1
  74. package/dist/utils/messageOperations.js +77 -9
  75. package/package.json +4 -2
  76. package/src/agent.ts +19 -1
  77. package/src/constants/tools.ts +1 -1
  78. package/src/managers/MemoryRuleManager.ts +1 -10
  79. package/src/managers/aiManager.ts +23 -3
  80. package/src/managers/mcpManager.ts +37 -16
  81. package/src/managers/messageManager.ts +76 -38
  82. package/src/managers/permissionManager.ts +4 -4
  83. package/src/managers/pluginManager.ts +4 -2
  84. package/src/managers/slashCommandManager.ts +130 -4
  85. package/src/managers/toolManager.ts +11 -2
  86. package/src/prompts/index.ts +6 -0
  87. package/src/services/GitService.ts +20 -0
  88. package/src/services/MarketplaceService.ts +397 -324
  89. package/src/services/aiService.ts +197 -1
  90. package/src/services/initializationService.ts +38 -0
  91. package/src/tools/agentTool.ts +3 -3
  92. package/src/tools/bashTool.ts +3 -4
  93. package/src/tools/editTool.ts +3 -0
  94. package/src/tools/globTool.ts +16 -3
  95. package/src/tools/grepTool.ts +41 -13
  96. package/src/tools/readTool.ts +69 -0
  97. package/src/tools/skillTool.ts +2 -2
  98. package/src/tools/types.ts +13 -0
  99. package/src/tools/webFetchTool.ts +194 -0
  100. package/src/tools/writeTool.ts +3 -0
  101. package/src/types/commands.ts +1 -1
  102. package/src/types/messaging.ts +1 -0
  103. package/src/utils/bashParser.ts +316 -161
  104. package/src/utils/convertMessagesForAPI.ts +8 -0
  105. package/src/utils/fileUtils.ts +69 -0
  106. package/src/utils/messageOperations.ts +84 -9
  107. package/dist/tools/taskOutputTool.d.ts +0 -3
  108. package/dist/tools/taskOutputTool.d.ts.map +0 -1
  109. package/dist/tools/taskOutputTool.js +0 -198
  110. package/src/tools/taskOutputTool.ts +0 -222
@@ -16,8 +16,13 @@ import {
16
16
  replaceBashCommandsWithOutput,
17
17
  executeBashCommands,
18
18
  } from "../utils/markdownParser.js";
19
+ import {
20
+ countToolBlocks,
21
+ formatToolTokenSummary,
22
+ } from "../utils/messageOperations.js";
19
23
  import type { SkillManager } from "./skillManager.js";
20
24
  import type { SkillMetadata } from "../types/skills.js";
25
+ import type { SubagentManager } from "./subagentManager.js";
21
26
 
22
27
  import { logger } from "../utils/globalLogger.js";
23
28
 
@@ -30,6 +35,7 @@ export class SlashCommandManager {
30
35
  private customCommands = new Map<string, CustomSlashCommand>();
31
36
  private skillCommandIds = new Set<string>();
32
37
  private workdir: string;
38
+ private currentCommandAbortController: AbortController | null = null;
33
39
 
34
40
  constructor(
35
41
  private container: Container,
@@ -71,6 +77,10 @@ export class SlashCommandManager {
71
77
  return this.container.get<SkillManager>("SkillManager")!;
72
78
  }
73
79
 
80
+ private get subagentManager(): SubagentManager {
81
+ return this.container.get<SubagentManager>("SubagentManager")!;
82
+ }
83
+
74
84
  private initializeBuiltinCommands(): void {
75
85
  // Register built-in clear command
76
86
  this.registerCommand({
@@ -153,7 +163,7 @@ export class SlashCommandManager {
153
163
  id: commandId,
154
164
  name: skill.name,
155
165
  description: `Skill: ${skill.description}`,
156
- handler: async (args?: string) => {
166
+ handler: async (args?: string, signal?: AbortSignal) => {
157
167
  try {
158
168
  // 1. Prepare skill content immediately
159
169
  const prepared = await this.skillManager.prepareSkill({
@@ -176,6 +186,109 @@ export class SlashCommandManager {
176
186
  return;
177
187
  }
178
188
 
189
+ if (skill.context === "fork") {
190
+ // Forked skill execution
191
+ const subagentConfigs =
192
+ await this.subagentManager.loadConfigurations();
193
+ const subagentType = skill.agent || "general-purpose";
194
+ const config = subagentConfigs.find(
195
+ (c) => c.name === subagentType,
196
+ );
197
+ if (!config) {
198
+ throw new Error(
199
+ `Subagent configuration for ${subagentType} not found`,
200
+ );
201
+ }
202
+
203
+ // Add a ToolBlock to the initial command message for progress tracking
204
+ const toolBlockId = this.messageManager.addToolBlockToMessage(
205
+ messageId,
206
+ {
207
+ name: subagentType,
208
+ parameters: JSON.stringify({
209
+ description: skill.description,
210
+ prompt: prepared.content,
211
+ subagent_type: subagentType,
212
+ }),
213
+ stage: "running",
214
+ },
215
+ );
216
+
217
+ try {
218
+ const instance = await this.subagentManager.createInstance(
219
+ config,
220
+ {
221
+ description: skill.description,
222
+ prompt: prepared.content,
223
+ subagent_type: subagentType,
224
+ model: skill.model,
225
+ },
226
+ false,
227
+ () => {
228
+ // Update the tool block with progress
229
+ const subagent = this.subagentManager.getInstance(
230
+ instance.subagentId,
231
+ );
232
+ if (subagent) {
233
+ const messages = subagent.messages;
234
+ const tokens =
235
+ subagent.messageManager.getLatestTotalTokens();
236
+ const lastTools = subagent.lastTools;
237
+
238
+ const toolCount = countToolBlocks(messages);
239
+ const summary = formatToolTokenSummary(toolCount, tokens);
240
+
241
+ let shortResult = "";
242
+ if (toolCount > 2) {
243
+ shortResult += "... ";
244
+ }
245
+ if (lastTools.length > 0) {
246
+ shortResult += `${lastTools.join(", ")} `;
247
+ }
248
+
249
+ shortResult += summary;
250
+
251
+ this.messageManager.updateToolBlock({
252
+ id: toolBlockId,
253
+ messageId,
254
+ shortResult,
255
+ });
256
+ }
257
+ },
258
+ );
259
+
260
+ try {
261
+ const result = await this.subagentManager.executeAgent(
262
+ instance,
263
+ prepared.content,
264
+ signal,
265
+ );
266
+
267
+ // Update the ToolBlock with final result
268
+ this.messageManager.updateToolBlock({
269
+ id: toolBlockId,
270
+ messageId,
271
+ result,
272
+ success: true,
273
+ stage: "end",
274
+ });
275
+ } finally {
276
+ this.subagentManager.cleanupInstance(instance.subagentId);
277
+ }
278
+ } catch (error) {
279
+ // Update the ToolBlock with error
280
+ this.messageManager.updateToolBlock({
281
+ id: toolBlockId,
282
+ messageId,
283
+ success: false,
284
+ error: error instanceof Error ? error.message : String(error),
285
+ stage: "end",
286
+ });
287
+ throw error; // Re-throw to be caught by outer catch for logging/error block
288
+ }
289
+ return;
290
+ }
291
+
179
292
  // 3. Execute bash commands asynchronously
180
293
  const result = await this.skillManager.executeSkill({
181
294
  skill_name: skill.name,
@@ -228,7 +341,6 @@ export class SlashCommandManager {
228
341
  command.description ||
229
342
  `Plugin command: ${namespacedName}${hasParameterPlaceholders(command.content) ? " (supports parameters)" : ""}`;
230
343
 
231
- // Register as a regular command with a handler that executes the custom command
232
344
  this.registerCommand({
233
345
  id: namespacedId,
234
346
  name: namespacedName,
@@ -313,12 +425,22 @@ export class SlashCommandManager {
313
425
  return false;
314
426
  }
315
427
 
428
+ // Abort any previous command if it's still running
429
+ this.currentCommandAbortController?.abort();
430
+ this.currentCommandAbortController = new AbortController();
431
+
316
432
  try {
317
- await command.handler(args);
433
+ await command.handler(args, this.currentCommandAbortController.signal);
318
434
  return true;
319
435
  } catch (error) {
320
- console.error(`Failed to execute slash command ${commandId}:`, error);
436
+ if (error instanceof Error && error.name === "AbortError") {
437
+ logger?.debug(`Slash command ${commandId} was aborted`);
438
+ } else {
439
+ console.error(`Failed to execute slash command ${commandId}:`, error);
440
+ }
321
441
  return false;
442
+ } finally {
443
+ this.currentCommandAbortController = null;
322
444
  }
323
445
  }
324
446
 
@@ -429,5 +551,9 @@ export class SlashCommandManager {
429
551
  public abortCurrentCommand(): void {
430
552
  // Abort the AI manager if it's running
431
553
  this.aiManager.abortAIMessage();
554
+
555
+ // Abort the current slash command handler
556
+ this.currentCommandAbortController?.abort();
557
+ this.currentCommandAbortController = null;
432
558
  }
433
559
  }
@@ -1,6 +1,5 @@
1
1
  import type { ToolContext, ToolPlugin, ToolResult } from "../tools/types.js";
2
2
  import { bashTool } from "../tools/bashTool.js";
3
- import { taskOutputTool } from "../tools/taskOutputTool.js";
4
3
  import { taskStopTool } from "../tools/taskStopTool.js";
5
4
  import { editTool } from "../tools/editTool.js";
6
5
  import { writeTool } from "../tools/writeTool.js";
@@ -9,6 +8,7 @@ import { askUserQuestionTool } from "../tools/askUserQuestion.js";
9
8
  import { cronCreateTool } from "../tools/cronCreateTool.js";
10
9
  import { cronDeleteTool } from "../tools/cronDeleteTool.js";
11
10
  import { cronListTool } from "../tools/cronListTool.js";
11
+ import { webFetchTool } from "../tools/webFetchTool.js";
12
12
  // New tools
13
13
  import { globTool } from "../tools/globTool.js";
14
14
  import { grepTool } from "../tools/grepTool.js";
@@ -34,6 +34,7 @@ import type { SubagentManager } from "./subagentManager.js";
34
34
  import type { SkillManager } from "./skillManager.js";
35
35
 
36
36
  import { ReversionManager } from "./reversionManager.js";
37
+ import * as aiService from "../services/aiService.js";
37
38
 
38
39
  import { Container } from "../utils/container.js";
39
40
 
@@ -101,7 +102,6 @@ class ToolManager {
101
102
  public initializeBuiltInTools(): void {
102
103
  const builtInTools = [
103
104
  bashTool,
104
- taskOutputTool,
105
105
  taskStopTool,
106
106
  editTool,
107
107
  writeTool,
@@ -120,6 +120,7 @@ class ToolManager {
120
120
  cronCreateTool,
121
121
  cronDeleteTool,
122
122
  cronListTool,
123
+ webFetchTool,
123
124
  ];
124
125
 
125
126
  for (const tool of builtInTools) {
@@ -213,6 +214,14 @@ class ToolManager {
213
214
  "CronManager",
214
215
  )
215
216
  : undefined,
217
+ aiManager: this.container.has("AIManager")
218
+ ? this.container.get<import("./aiManager.js").AIManager>("AIManager")
219
+ : undefined,
220
+ aiService: aiService,
221
+ messageManager:
222
+ this.container.get<import("./messageManager.js").MessageManager>(
223
+ "MessageManager",
224
+ )!,
216
225
  sessionId: context.sessionId,
217
226
  toolCallId: context.toolCallId,
218
227
  };
@@ -151,6 +151,12 @@ Any promises made to the user
151
151
  Be concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task.
152
152
  Wrap your summary in <summary></summary> tags.`;
153
153
 
154
+ export const WEB_CONTENT_SYSTEM_PROMPT = `You are a helpful assistant that extracts information from web content. The content is provided in Markdown format.`;
155
+ export const BTW_SYSTEM_PROMPT = `You are a helpful assistant. Answer the user's side question based on the conversation history.
156
+ Do NOT say things like "Let me try...", "I'll now...", "Let me check...", or promise to take any action.
157
+ If you don't know the answer, say so - do not offer to look it up or investigate.
158
+ Simply answer the question with the information you have.`;
159
+
154
160
  export function buildSystemPrompt(
155
161
  basePrompt: string | undefined,
156
162
  tools: ToolPlugin[],
@@ -4,6 +4,17 @@ import { promisify } from "util";
4
4
  const execAsync = promisify(exec);
5
5
 
6
6
  export class GitService {
7
+ private getTimeout(): number {
8
+ const envTimeout = process.env.WAVE_PLUGIN_GIT_TIMEOUT_MS;
9
+ if (envTimeout) {
10
+ const parsed = parseInt(envTimeout, 10);
11
+ if (!isNaN(parsed)) {
12
+ return parsed;
13
+ }
14
+ }
15
+ return 120000; // Default 120 seconds
16
+ }
17
+
7
18
  /**
8
19
  * Checks if git is installed and available in the system path
9
20
  */
@@ -50,6 +61,7 @@ export class GitService {
50
61
  const refArgs = ref ? `-b "${ref}"` : "--depth 1";
51
62
  await execAsync(`git clone ${refArgs} "${url}" "${targetPath}"`, {
52
63
  env: { ...process.env, LC_ALL: "C" },
64
+ timeout: this.getTimeout(),
53
65
  });
54
66
  } catch (error) {
55
67
  throw this.handleGitError(urlOrRepo, error);
@@ -73,6 +85,7 @@ export class GitService {
73
85
  try {
74
86
  await execAsync(`git -C "${targetPath}" pull`, {
75
87
  env: { ...process.env, LC_ALL: "C" },
88
+ timeout: this.getTimeout(),
76
89
  });
77
90
  } catch (error) {
78
91
  throw this.handleGitError(targetPath, error);
@@ -82,6 +95,13 @@ export class GitService {
82
95
  private handleGitError(context: string, error: unknown): Error {
83
96
  const stderr = (error as { stderr?: string })?.stderr || "";
84
97
  const message = (error as Error)?.message || String(error);
98
+ const killed = (error as { killed?: boolean })?.killed || false;
99
+
100
+ if (message.includes("ETIMEDOUT") || killed) {
101
+ return new Error(
102
+ `Git operation timed out after ${this.getTimeout() / 1000}s. The repository may be too large or the network is slow. You can increase the timeout by setting the WAVE_PLUGIN_GIT_TIMEOUT_MS environment variable.`,
103
+ );
104
+ }
85
105
 
86
106
  if (
87
107
  stderr.includes("Repository not found") ||