wave-agent-sdk 0.11.6 → 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 (105) 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/messageManager.d.ts +13 -5
  15. package/dist/managers/messageManager.d.ts.map +1 -1
  16. package/dist/managers/messageManager.js +62 -34
  17. package/dist/managers/pluginManager.d.ts.map +1 -1
  18. package/dist/managers/pluginManager.js +4 -2
  19. package/dist/managers/slashCommandManager.d.ts +2 -0
  20. package/dist/managers/slashCommandManager.d.ts.map +1 -1
  21. package/dist/managers/slashCommandManager.js +98 -4
  22. package/dist/managers/toolManager.d.ts.map +1 -1
  23. package/dist/managers/toolManager.js +8 -2
  24. package/dist/prompts/index.d.ts +2 -0
  25. package/dist/prompts/index.d.ts.map +1 -1
  26. package/dist/prompts/index.js +5 -0
  27. package/dist/services/GitService.d.ts +1 -0
  28. package/dist/services/GitService.d.ts.map +1 -1
  29. package/dist/services/GitService.js +16 -0
  30. package/dist/services/MarketplaceService.d.ts +7 -0
  31. package/dist/services/MarketplaceService.d.ts.map +1 -1
  32. package/dist/services/MarketplaceService.js +321 -252
  33. package/dist/services/aiService.d.ts +34 -0
  34. package/dist/services/aiService.d.ts.map +1 -1
  35. package/dist/services/aiService.js +124 -1
  36. package/dist/services/initializationService.d.ts.map +1 -1
  37. package/dist/services/initializationService.js +18 -0
  38. package/dist/tools/agentTool.js +3 -3
  39. package/dist/tools/bashTool.d.ts.map +1 -1
  40. package/dist/tools/bashTool.js +4 -4
  41. package/dist/tools/editTool.d.ts.map +1 -1
  42. package/dist/tools/editTool.js +2 -0
  43. package/dist/tools/globTool.d.ts.map +1 -1
  44. package/dist/tools/globTool.js +15 -3
  45. package/dist/tools/grepTool.d.ts.map +1 -1
  46. package/dist/tools/grepTool.js +38 -12
  47. package/dist/tools/readTool.d.ts.map +1 -1
  48. package/dist/tools/readTool.js +61 -0
  49. package/dist/tools/skillTool.js +2 -2
  50. package/dist/tools/types.d.ts +16 -0
  51. package/dist/tools/types.d.ts.map +1 -1
  52. package/dist/tools/webFetchTool.d.ts +3 -0
  53. package/dist/tools/webFetchTool.d.ts.map +1 -0
  54. package/dist/tools/webFetchTool.js +171 -0
  55. package/dist/tools/writeTool.d.ts.map +1 -1
  56. package/dist/tools/writeTool.js +2 -0
  57. package/dist/types/commands.d.ts +1 -1
  58. package/dist/types/commands.d.ts.map +1 -1
  59. package/dist/types/messaging.d.ts +1 -0
  60. package/dist/types/messaging.d.ts.map +1 -1
  61. package/dist/utils/bashParser.d.ts +14 -0
  62. package/dist/utils/bashParser.d.ts.map +1 -1
  63. package/dist/utils/bashParser.js +243 -142
  64. package/dist/utils/convertMessagesForAPI.d.ts.map +1 -1
  65. package/dist/utils/convertMessagesForAPI.js +7 -0
  66. package/dist/utils/fileUtils.d.ts +8 -0
  67. package/dist/utils/fileUtils.d.ts.map +1 -1
  68. package/dist/utils/fileUtils.js +52 -0
  69. package/dist/utils/messageOperations.d.ts +12 -3
  70. package/dist/utils/messageOperations.d.ts.map +1 -1
  71. package/dist/utils/messageOperations.js +77 -9
  72. package/package.json +4 -2
  73. package/src/agent.ts +19 -1
  74. package/src/constants/tools.ts +1 -1
  75. package/src/managers/MemoryRuleManager.ts +1 -10
  76. package/src/managers/aiManager.ts +23 -3
  77. package/src/managers/messageManager.ts +76 -38
  78. package/src/managers/pluginManager.ts +4 -2
  79. package/src/managers/slashCommandManager.ts +130 -4
  80. package/src/managers/toolManager.ts +11 -2
  81. package/src/prompts/index.ts +6 -0
  82. package/src/services/GitService.ts +20 -0
  83. package/src/services/MarketplaceService.ts +397 -324
  84. package/src/services/aiService.ts +197 -1
  85. package/src/services/initializationService.ts +38 -0
  86. package/src/tools/agentTool.ts +3 -3
  87. package/src/tools/bashTool.ts +3 -4
  88. package/src/tools/editTool.ts +3 -0
  89. package/src/tools/globTool.ts +16 -3
  90. package/src/tools/grepTool.ts +41 -13
  91. package/src/tools/readTool.ts +69 -0
  92. package/src/tools/skillTool.ts +2 -2
  93. package/src/tools/types.ts +13 -0
  94. package/src/tools/webFetchTool.ts +194 -0
  95. package/src/tools/writeTool.ts +3 -0
  96. package/src/types/commands.ts +1 -1
  97. package/src/types/messaging.ts +1 -0
  98. package/src/utils/bashParser.ts +268 -157
  99. package/src/utils/convertMessagesForAPI.ts +8 -0
  100. package/src/utils/fileUtils.ts +69 -0
  101. package/src/utils/messageOperations.ts +84 -9
  102. package/dist/tools/taskOutputTool.d.ts +0 -3
  103. package/dist/tools/taskOutputTool.d.ts.map +0 -1
  104. package/dist/tools/taskOutputTool.js +0 -198
  105. package/src/tools/taskOutputTool.ts +0 -222
@@ -137,7 +137,7 @@ export const skillTool: ToolPlugin = {
137
137
  () => {
138
138
  // Update shortResult
139
139
  const messages = instance.messageManager.getMessages();
140
- const tokens = instance.messageManager.getlatestTotalTokens();
140
+ const tokens = instance.messageManager.getLatestTotalTokens();
141
141
  const lastTools = instance.lastTools;
142
142
 
143
143
  const toolCount = countToolBlocks(messages);
@@ -168,7 +168,7 @@ export const skillTool: ToolPlugin = {
168
168
  subagentManager.cleanupInstance(instance.subagentId);
169
169
 
170
170
  const messages = instance.messageManager.getMessages();
171
- const tokens = instance.messageManager.getlatestTotalTokens();
171
+ const tokens = instance.messageManager.getLatestTotalTokens();
172
172
  const toolCount = countToolBlocks(messages);
173
173
  const summary = formatToolTokenSummary(toolCount, tokens);
174
174
 
@@ -81,6 +81,12 @@ export interface ToolContext {
81
81
  skillManager?: import("../managers/skillManager.js").SkillManager;
82
82
  /** Cron manager instance for scheduling tasks */
83
83
  cronManager?: import("../managers/cronManager.js").CronManager;
84
+ /** AI manager instance for AI operations */
85
+ aiManager?: import("../managers/aiManager.js").AIManager;
86
+ /** AI service instance for AI operations */
87
+ aiService?: typeof import("../services/aiService.js");
88
+ /** Message manager instance for message operations */
89
+ messageManager?: import("../managers/messageManager.js").MessageManager;
84
90
  /** Current session ID */
85
91
  sessionId?: string;
86
92
  /** The ID of the current tool call */
@@ -89,4 +95,11 @@ export interface ToolContext {
89
95
  onShortResultUpdate?: (shortResult: string) => void;
90
96
  /** Callback to update the full result of the current tool block */
91
97
  onResultUpdate?: (result: string) => void;
98
+ /** Limits for file reading operations */
99
+ fileReadingLimits?: {
100
+ maxSizeBytes: number;
101
+ maxTokens: number;
102
+ };
103
+ /** State of files read in the current session for deduplication */
104
+ readFileState?: Map<string, { mtime: number; hash: string }>;
92
105
  }
@@ -0,0 +1,194 @@
1
+ import TurndownService from "turndown";
2
+ import { WEB_FETCH_TOOL_NAME } from "../constants/tools.js";
3
+ import type { ToolPlugin, ToolResult, ToolContext } from "./types.js";
4
+ import { logger } from "../utils/globalLogger.js";
5
+
6
+ const CACHE_TTL = 15 * 60 * 1000; // 15 minutes
7
+ const cache = new Map<string, { content: string; timestamp: number }>();
8
+
9
+ function getFromCache(url: string): string | null {
10
+ const cached = cache.get(url);
11
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
12
+ return cached.content;
13
+ }
14
+ if (cached) {
15
+ cache.delete(url);
16
+ }
17
+ return null;
18
+ }
19
+
20
+ function setToCache(url: string, content: string) {
21
+ cache.set(url, { content, timestamp: Date.now() });
22
+ }
23
+
24
+ // Clean up cache every 15 minutes
25
+ setInterval(() => {
26
+ const now = Date.now();
27
+ for (const [url, cached] of cache.entries()) {
28
+ if (now - cached.timestamp >= CACHE_TTL) {
29
+ cache.delete(url);
30
+ }
31
+ }
32
+ }, CACHE_TTL);
33
+
34
+ export const webFetchTool: ToolPlugin = {
35
+ name: WEB_FETCH_TOOL_NAME,
36
+ config: {
37
+ type: "function",
38
+ function: {
39
+ name: WEB_FETCH_TOOL_NAME,
40
+ description: `IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs. Before using this tool, check if the URL points to an authenticated service (e.g. Google Docs, Confluence, Jira, GitHub). If so, look for a specialized MCP tool that provides authenticated access.
41
+
42
+ - Fetches content from a specified URL and processes it using an AI model
43
+ - Takes a URL and a prompt as input
44
+ - Fetches the URL content, converts HTML to markdown
45
+ - Processes the content with the prompt using a small, fast model
46
+ - Returns the model's response about the content
47
+ - Use this tool when you need to retrieve and analyze web content
48
+
49
+ Usage notes:
50
+ - IMPORTANT: If an MCP-provided web fetch tool is available, prefer using that tool instead of this one, as it may have fewer restrictions.
51
+ - The URL must be a fully-formed valid URL
52
+ - HTTP URLs will be automatically upgraded to HTTPS
53
+ - The prompt should describe what information you want to extract from the page
54
+ - This tool is read-only and does not modify any files
55
+ - Results may be summarized if the content is very large
56
+ - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
57
+ - When a URL redirects to a different host, the tool will inform you and provide the redirect URL in a special format. You should then make a new WebFetch request with the redirect URL to fetch the content.
58
+ - For GitHub URLs, prefer using the gh CLI via Bash instead (e.g., gh pr view, gh issue view, gh api).`,
59
+ parameters: {
60
+ type: "object",
61
+ properties: {
62
+ url: {
63
+ type: "string",
64
+ description: "The URL to fetch content from",
65
+ format: "uri",
66
+ },
67
+ prompt: {
68
+ type: "string",
69
+ description: "The prompt to run on the fetched content",
70
+ },
71
+ },
72
+ required: ["url", "prompt"],
73
+ additionalProperties: false,
74
+ },
75
+ },
76
+ },
77
+ execute: async (
78
+ args: Record<string, unknown>,
79
+ context: ToolContext,
80
+ ): Promise<ToolResult> => {
81
+ let url = args.url as string;
82
+ const prompt = args.prompt as string;
83
+
84
+ if (!url || !prompt) {
85
+ return {
86
+ success: false,
87
+ content: "",
88
+ error: "Both url and prompt parameters are required",
89
+ };
90
+ }
91
+
92
+ // Upgrade HTTP to HTTPS
93
+ if (url.startsWith("http://")) {
94
+ url = "https://" + url.substring(7);
95
+ }
96
+
97
+ // Check for GitHub URLs
98
+ if (url.includes("github.com")) {
99
+ return {
100
+ success: false,
101
+ content: "",
102
+ error:
103
+ "For GitHub URLs, please use the 'gh' CLI via the Bash tool instead (e.g., 'gh pr view', 'gh issue view', 'gh api').",
104
+ };
105
+ }
106
+
107
+ try {
108
+ let markdown = getFromCache(url);
109
+
110
+ if (!markdown) {
111
+ const response = await fetch(url, {
112
+ redirect: "manual",
113
+ headers: {
114
+ "User-Agent":
115
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
116
+ },
117
+ });
118
+
119
+ if (response.status >= 300 && response.status < 400) {
120
+ const location = response.headers.get("location");
121
+ if (location) {
122
+ const redirectUrl = new URL(location, url).toString();
123
+ const originalHost = new URL(url).host;
124
+ const redirectHost = new URL(redirectUrl).host;
125
+
126
+ if (originalHost !== redirectHost) {
127
+ return {
128
+ success: true,
129
+ content: `REDIRECT_TO: ${redirectUrl}\nThe URL redirected to a different host. Please make a new WebFetch request with this redirect URL if you wish to continue.`,
130
+ };
131
+ }
132
+ // If same host, we could follow it, but the requirement says "When a URL redirects to a different host, the tool will inform you".
133
+ // For simplicity and following the requirement strictly, let's just return the redirect for different hosts.
134
+ // If it's the same host, we can try to fetch again or just return it too.
135
+ return {
136
+ success: true,
137
+ content: `REDIRECT_TO: ${redirectUrl}\nThe URL redirected. Please make a new WebFetch request with this redirect URL.`,
138
+ };
139
+ }
140
+ }
141
+
142
+ if (!response.ok) {
143
+ return {
144
+ success: false,
145
+ content: "",
146
+ error: `Failed to fetch URL: ${response.status} ${response.statusText}`,
147
+ };
148
+ }
149
+
150
+ const html = await response.text();
151
+ const turndownService = new TurndownService();
152
+ markdown = turndownService.turndown(html);
153
+ setToCache(url, markdown);
154
+ }
155
+
156
+ // Process with AI
157
+ if (!context.aiManager || !context.aiService) {
158
+ return {
159
+ success: false,
160
+ content: markdown,
161
+ error: "AI Manager or AI Service not available for processing content",
162
+ };
163
+ }
164
+
165
+ const modelConfig = context.aiManager.getModelConfig();
166
+ const fastModel = modelConfig.fastModel;
167
+
168
+ const aiResponse = await context.aiService.processWebContent({
169
+ gatewayConfig: context.aiManager.getGatewayConfig(),
170
+ modelConfig: modelConfig,
171
+ content: markdown,
172
+ prompt: prompt,
173
+ model: fastModel,
174
+ abortSignal: context.abortSignal,
175
+ });
176
+
177
+ return {
178
+ success: true,
179
+ content: aiResponse.content || "",
180
+ shortResult: `Processed content from ${url}`,
181
+ };
182
+ } catch (error) {
183
+ logger.error(`WebFetch failed for ${url}:`, error);
184
+ return {
185
+ success: false,
186
+ content: "",
187
+ error: `WebFetch failed: ${error instanceof Error ? error.message : String(error)}`,
188
+ };
189
+ }
190
+ },
191
+ formatCompactParams: (params: Record<string, unknown>) => {
192
+ return `Fetch ${params.url}`;
193
+ },
194
+ };
@@ -66,6 +66,9 @@ Usage:
66
66
  };
67
67
  }
68
68
 
69
+ // Touch file to track it in context
70
+ context.messageManager?.touchFile(filePath);
71
+
69
72
  try {
70
73
  const resolvedPath = resolvePath(filePath, context.workdir);
71
74
 
@@ -7,7 +7,7 @@ export interface SlashCommand {
7
7
  id: string;
8
8
  name: string;
9
9
  description: string;
10
- handler: (args?: string) => Promise<void> | void;
10
+ handler: (args?: string, signal?: AbortSignal) => Promise<void> | void;
11
11
  }
12
12
 
13
13
  export interface CustomSlashCommandConfig {
@@ -16,6 +16,7 @@ export interface Message {
16
16
  blocks: MessageBlock[];
17
17
  usage?: Usage; // Usage data for this message's AI operation (assistant messages only)
18
18
  additionalFields?: Record<string, unknown>; // Additional metadata from AI responses
19
+ isMeta?: boolean; // Whether the message is a meta message (hidden from UI)
19
20
  }
20
21
 
21
22
  export type MessageBlock =