wave-agent-sdk 1.0.5 → 1.0.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 (202) hide show
  1. package/dist/agent.d.ts +34 -1
  2. package/dist/agent.js +49 -4
  3. package/dist/index.d.ts +3 -1
  4. package/dist/index.js +1 -1
  5. package/dist/managers/aiManager.d.ts +36 -0
  6. package/dist/managers/aiManager.js +240 -11
  7. package/dist/managers/messageManager.d.ts +2 -4
  8. package/dist/managers/messageManager.js +14 -7
  9. package/dist/managers/slashCommandManager.js +28 -0
  10. package/dist/managers/subagentManager.d.ts +0 -2
  11. package/dist/services/aiService.d.ts +2 -3
  12. package/dist/services/aiService.js +4 -18
  13. package/dist/services/configurationService.d.ts +7 -0
  14. package/dist/services/configurationService.js +10 -0
  15. package/dist/telemetry/instrumentation.d.ts +1 -1
  16. package/dist/telemetry/instrumentation.js +57 -28
  17. package/dist/tools/bashTool.js +16 -6
  18. package/dist/tools/grepTool.js +11 -3
  19. package/dist/types/core.d.ts +1 -34
  20. package/dist/types/index.d.ts +4 -0
  21. package/dist/types/messaging.d.ts +2 -0
  22. package/dist/utils/cacheControlUtils.d.ts +5 -27
  23. package/dist/utils/cacheControlUtils.js +12 -73
  24. package/dist/utils/containerSetup.js +0 -3
  25. package/dist/utils/messageOperations.d.ts +2 -1
  26. package/dist/utils/messageOperations.js +2 -1
  27. package/dist/utils/notificationXml.js +5 -0
  28. package/dist/utils/ripgrep.d.ts +4 -4
  29. package/dist/utils/ripgrep.js +4 -27
  30. package/package.json +20 -8
  31. package/bin/rg +0 -79
  32. package/dist/managers/forkedAgentManager.d.ts +0 -50
  33. package/dist/managers/forkedAgentManager.js +0 -130
  34. package/scripts/install_ripgrep.js +0 -111
  35. package/scripts/postinstall.js +0 -38
  36. package/src/agent.ts +0 -1271
  37. package/src/constants/subagents.ts +0 -4
  38. package/src/constants/toolLimits.ts +0 -15
  39. package/src/constants/tools.ts +0 -24
  40. package/src/core/plugin.ts +0 -237
  41. package/src/core/session.ts +0 -9
  42. package/src/index.ts +0 -38
  43. package/src/managers/MemoryRuleManager.ts +0 -198
  44. package/src/managers/aiManager.ts +0 -2429
  45. package/src/managers/backgroundTaskManager.ts +0 -480
  46. package/src/managers/bangManager.ts +0 -119
  47. package/src/managers/cronManager.ts +0 -401
  48. package/src/managers/foregroundTaskManager.ts +0 -30
  49. package/src/managers/forkedAgentManager.ts +0 -216
  50. package/src/managers/hookManager.ts +0 -1089
  51. package/src/managers/liveConfigManager.ts +0 -445
  52. package/src/managers/lspManager.ts +0 -470
  53. package/src/managers/mcpManager.ts +0 -1010
  54. package/src/managers/messageManager.ts +0 -1184
  55. package/src/managers/messageQueue.ts +0 -157
  56. package/src/managers/permissionManager.ts +0 -1140
  57. package/src/managers/planManager.ts +0 -112
  58. package/src/managers/pluginManager.ts +0 -330
  59. package/src/managers/pluginScopeManager.ts +0 -124
  60. package/src/managers/reversionManager.ts +0 -178
  61. package/src/managers/skillManager.ts +0 -578
  62. package/src/managers/slashCommandManager.ts +0 -564
  63. package/src/managers/subagentManager.ts +0 -915
  64. package/src/managers/toolManager.ts +0 -489
  65. package/src/managers/workflowManager.ts +0 -493
  66. package/src/prompts/autoMemory.ts +0 -33
  67. package/src/prompts/autoMemoryExtraction.ts +0 -146
  68. package/src/prompts/index.ts +0 -506
  69. package/src/prompts/planModeReminders.ts +0 -126
  70. package/src/services/GitService.ts +0 -131
  71. package/src/services/MarketplaceService.ts +0 -1052
  72. package/src/services/MemoryRuleService.ts +0 -71
  73. package/src/services/aiService.ts +0 -919
  74. package/src/services/authService.ts +0 -565
  75. package/src/services/autoMemoryService.ts +0 -280
  76. package/src/services/configurationService.ts +0 -1520
  77. package/src/services/fileWatcher.ts +0 -319
  78. package/src/services/hook.ts +0 -348
  79. package/src/services/initializationService.ts +0 -357
  80. package/src/services/interactionService.ts +0 -229
  81. package/src/services/jsonlHandler.ts +0 -295
  82. package/src/services/memory.ts +0 -234
  83. package/src/services/pluginLoader.ts +0 -252
  84. package/src/services/remoteSettingsService.ts +0 -366
  85. package/src/services/reversionService.ts +0 -122
  86. package/src/services/session.ts +0 -917
  87. package/src/services/taskManager.ts +0 -321
  88. package/src/telemetry/events.ts +0 -65
  89. package/src/telemetry/instrumentation.ts +0 -499
  90. package/src/telemetry/sessionTracing.ts +0 -348
  91. package/src/tools/agentTool.ts +0 -322
  92. package/src/tools/askUserQuestion.ts +0 -160
  93. package/src/tools/bashTool.ts +0 -621
  94. package/src/tools/buildTool.ts +0 -61
  95. package/src/tools/cronCreateTool.ts +0 -161
  96. package/src/tools/cronDeleteTool.ts +0 -51
  97. package/src/tools/cronListTool.ts +0 -47
  98. package/src/tools/editTool.ts +0 -313
  99. package/src/tools/enterPlanMode.ts +0 -124
  100. package/src/tools/enterWorktreeTool.ts +0 -190
  101. package/src/tools/exitPlanMode.ts +0 -139
  102. package/src/tools/exitWorktreeTool.ts +0 -236
  103. package/src/tools/globTool.ts +0 -167
  104. package/src/tools/grepTool.ts +0 -399
  105. package/src/tools/lspTool.ts +0 -883
  106. package/src/tools/readTool.ts +0 -426
  107. package/src/tools/skillTool.ts +0 -248
  108. package/src/tools/taskManagementTools.ts +0 -574
  109. package/src/tools/taskStopTool.ts +0 -78
  110. package/src/tools/types.ts +0 -137
  111. package/src/tools/webFetchTool.ts +0 -373
  112. package/src/tools/workflowTool.ts +0 -205
  113. package/src/tools/writeTool.ts +0 -267
  114. package/src/types/agent.ts +0 -128
  115. package/src/types/auth.ts +0 -19
  116. package/src/types/commands.ts +0 -30
  117. package/src/types/config.ts +0 -43
  118. package/src/types/configuration.ts +0 -168
  119. package/src/types/core.ts +0 -105
  120. package/src/types/cron.ts +0 -13
  121. package/src/types/environment.ts +0 -106
  122. package/src/types/fileSearch.ts +0 -4
  123. package/src/types/history.ts +0 -7
  124. package/src/types/hooks.ts +0 -256
  125. package/src/types/index.ts +0 -41
  126. package/src/types/lsp.ts +0 -98
  127. package/src/types/marketplace.ts +0 -71
  128. package/src/types/mcp.ts +0 -43
  129. package/src/types/memoryRule.ts +0 -31
  130. package/src/types/messaging.ts +0 -114
  131. package/src/types/permissions.ts +0 -80
  132. package/src/types/plugins.ts +0 -39
  133. package/src/types/processes.ts +0 -99
  134. package/src/types/reversion.ts +0 -29
  135. package/src/types/session.ts +0 -12
  136. package/src/types/skills.ts +0 -108
  137. package/src/types/tasks.ts +0 -13
  138. package/src/types/telemetry.ts +0 -98
  139. package/src/types/tools.ts +0 -44
  140. package/src/types/workflow.ts +0 -6
  141. package/src/utils/abortUtils.ts +0 -118
  142. package/src/utils/atomicWrite.ts +0 -61
  143. package/src/utils/bashParser.ts +0 -899
  144. package/src/utils/cacheControlUtils.ts +0 -426
  145. package/src/utils/commandArgumentParser.ts +0 -161
  146. package/src/utils/commandPathResolver.ts +0 -88
  147. package/src/utils/configPaths.ts +0 -220
  148. package/src/utils/configValidator.ts +0 -100
  149. package/src/utils/constants.ts +0 -39
  150. package/src/utils/container.ts +0 -92
  151. package/src/utils/containerSetup.ts +0 -371
  152. package/src/utils/convertMessagesForAPI.ts +0 -326
  153. package/src/utils/cronTasks.ts +0 -128
  154. package/src/utils/cronTasksLock.ts +0 -182
  155. package/src/utils/cronToHuman.ts +0 -99
  156. package/src/utils/customCommands.ts +0 -95
  157. package/src/utils/editUtils.ts +0 -20
  158. package/src/utils/fileFormat.ts +0 -40
  159. package/src/utils/fileSearch.ts +0 -151
  160. package/src/utils/fileUtils.ts +0 -223
  161. package/src/utils/gitUtils.ts +0 -315
  162. package/src/utils/globalLogger.ts +0 -128
  163. package/src/utils/groupMessagesByApiRound.ts +0 -121
  164. package/src/utils/hookMatcher.ts +0 -176
  165. package/src/utils/markdownParser.ts +0 -317
  166. package/src/utils/mcpUtils.ts +0 -138
  167. package/src/utils/messageOperations.ts +0 -659
  168. package/src/utils/modelCapabilities.ts +0 -30
  169. package/src/utils/nameGenerator.ts +0 -99
  170. package/src/utils/notificationXml.ts +0 -57
  171. package/src/utils/openaiClient.ts +0 -251
  172. package/src/utils/parseCronExpression.ts +0 -78
  173. package/src/utils/path.ts +0 -72
  174. package/src/utils/pathEncoder.ts +0 -400
  175. package/src/utils/pathSafety.ts +0 -40
  176. package/src/utils/promptHistory.ts +0 -168
  177. package/src/utils/ripgrep.ts +0 -35
  178. package/src/utils/shellResolver.ts +0 -190
  179. package/src/utils/skillParser.ts +0 -246
  180. package/src/utils/stringUtils.ts +0 -156
  181. package/src/utils/subagentParser.ts +0 -279
  182. package/src/utils/taskReminder.ts +0 -96
  183. package/src/utils/tokenCalculation.ts +0 -43
  184. package/src/utils/tokenEstimate.ts +0 -34
  185. package/src/utils/toolResultStorage.ts +0 -117
  186. package/src/utils/worktreeSession.ts +0 -26
  187. package/src/utils/worktreeUtils.ts +0 -786
  188. package/src/workflow/budgetTracker.ts +0 -34
  189. package/src/workflow/concurrencyLimiter.ts +0 -47
  190. package/src/workflow/journal.ts +0 -95
  191. package/src/workflow/progressReporter.ts +0 -141
  192. package/src/workflow/runState.ts +0 -65
  193. package/src/workflow/scriptRuntime.ts +0 -274
  194. package/src/workflow/structuredOutput.ts +0 -123
  195. package/src/workflow/types.ts +0 -101
  196. package/src/workflow/workflowApis.ts +0 -410
  197. package/vendor/ripgrep/linux-aarch64/rg +0 -0
  198. package/vendor/ripgrep/linux-x86_64/rg +0 -0
  199. package/vendor/ripgrep/macos-aarch64/rg +0 -0
  200. package/vendor/ripgrep/macos-x86_64/rg +0 -0
  201. package/vendor/ripgrep/windows-aarch64/rg.exe +0 -0
  202. package/vendor/ripgrep/windows-x86_64/rg.exe +0 -0
@@ -1,317 +0,0 @@
1
- import { readFileSync, writeFileSync, mkdirSync } from "fs";
2
- import { exec } from "child_process";
3
- import { promisify } from "util";
4
- import { join } from "path";
5
- import { tmpdir } from "os";
6
- import type { CustomSlashCommandConfig } from "../types/index.js";
7
- import {
8
- SKILL_BASH_MAX_OUTPUT_CHARS,
9
- PREVIEW_SIZE_BYTES,
10
- } from "../constants/toolLimits.js";
11
- import { logger } from "./globalLogger.js";
12
-
13
- const execAsync = promisify(exec);
14
-
15
- interface ParsedMarkdownFile {
16
- content: string;
17
- config?: CustomSlashCommandConfig;
18
- }
19
-
20
- /**
21
- * Parse YAML frontmatter from markdown content
22
- */
23
- export function parseFrontmatter(content: string): {
24
- frontmatter?: Record<string, unknown>;
25
- content: string;
26
- } {
27
- const frontmatterRegex = /^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/;
28
- const match = content.match(frontmatterRegex);
29
-
30
- if (!match) {
31
- return { content };
32
- }
33
-
34
- const [, frontmatterStr, bodyContent] = match;
35
-
36
- try {
37
- // Simple YAML parser for our use case (supports key: value and list items)
38
- const frontmatter: Record<string, unknown> = {};
39
- const lines = frontmatterStr.split("\n");
40
- let currentKey: string | null = null;
41
-
42
- for (const line of lines) {
43
- const trimmedLine = line.trim();
44
- if (!trimmedLine || trimmedLine.startsWith("#")) continue;
45
-
46
- // Check if it's a list item
47
- if (trimmedLine.startsWith("-") && currentKey) {
48
- let value = trimmedLine.slice(1).trim();
49
- if (value) {
50
- // Remove surrounding quotes if present
51
- if (
52
- (value.startsWith('"') && value.endsWith('"')) ||
53
- (value.startsWith("'") && value.endsWith("'"))
54
- ) {
55
- value = value.slice(1, -1);
56
- }
57
- if (!Array.isArray(frontmatter[currentKey])) {
58
- frontmatter[currentKey] = [];
59
- }
60
- (frontmatter[currentKey] as unknown[]).push(value);
61
- }
62
- continue;
63
- }
64
-
65
- const colonIndex = trimmedLine.indexOf(":");
66
- if (colonIndex === -1) continue;
67
-
68
- const key = trimmedLine.slice(0, colonIndex).trim();
69
- const value = trimmedLine.slice(colonIndex + 1).trim();
70
-
71
- currentKey = key;
72
- if (value) {
73
- // Remove surrounding quotes if present
74
- const unquotedValue =
75
- (value.startsWith('"') && value.endsWith('"')) ||
76
- (value.startsWith("'") && value.endsWith("'"))
77
- ? value.slice(1, -1)
78
- : value;
79
- frontmatter[key] = unquotedValue;
80
- }
81
- }
82
-
83
- return { frontmatter, content: bodyContent };
84
- } catch {
85
- // If parsing fails, just return the content without frontmatter
86
- return { content };
87
- }
88
- }
89
-
90
- /**
91
- * Parse markdown file and extract config and content
92
- */
93
- export function parseMarkdownFile(filePath: string): ParsedMarkdownFile {
94
- try {
95
- const fileContent = readFileSync(filePath, "utf-8");
96
- const { frontmatter, content } = parseFrontmatter(fileContent);
97
-
98
- let config: CustomSlashCommandConfig | undefined;
99
-
100
- if (frontmatter) {
101
- config = {};
102
-
103
- if (frontmatter.model && typeof frontmatter.model === "string") {
104
- config.model = frontmatter.model;
105
- }
106
-
107
- if (
108
- frontmatter.description &&
109
- typeof frontmatter.description === "string"
110
- ) {
111
- config.description = frontmatter.description;
112
- }
113
-
114
- if (frontmatter["allowed-tools"]) {
115
- if (Array.isArray(frontmatter["allowed-tools"])) {
116
- config.allowedTools = frontmatter["allowed-tools"].filter(
117
- (item): item is string => typeof item === "string",
118
- );
119
- } else if (typeof frontmatter["allowed-tools"] === "string") {
120
- config.allowedTools = frontmatter["allowed-tools"]
121
- .split(",")
122
- .map((s) => s.trim())
123
- .filter((s) => s.length > 0);
124
- }
125
- }
126
- }
127
-
128
- return {
129
- content: content.trim(),
130
- config,
131
- };
132
- } catch (error) {
133
- throw new Error(
134
- `Failed to parse markdown file ${filePath}: ${error instanceof Error ? error.message : String(error)}`,
135
- );
136
- }
137
- }
138
-
139
- /**
140
- * Parse and execute bash commands in markdown content
141
- */
142
- export interface BashCommandResult {
143
- command: string;
144
- output: string;
145
- exitCode: number;
146
- }
147
-
148
- /**
149
- * Block syntax pattern: ```! command ```
150
- */
151
- const BLOCK_BASH_REGEX = /```!\s*\n?([\s\S]*?)\n?```/g;
152
-
153
- /**
154
- * Inline syntax pattern: !`command`
155
- */
156
- const INLINE_BASH_REGEX = /!`([^`]+)`/g;
157
-
158
- export function parseBashCommands(content: string): {
159
- commands: string[];
160
- processedContent: string;
161
- } {
162
- // Performance gate: skip expensive regex if no bash pattern exists
163
- // Covers the common case where 93% of skills have no bash substitution
164
- if (!content.includes("!`") && !content.includes("```!")) {
165
- return { commands: [], processedContent: content };
166
- }
167
-
168
- const commands: string[] = [];
169
-
170
- // Extract block commands
171
- let blockMatch;
172
- const blockRegex = new RegExp(
173
- BLOCK_BASH_REGEX.source,
174
- BLOCK_BASH_REGEX.flags,
175
- );
176
- while ((blockMatch = blockRegex.exec(content)) !== null) {
177
- const cmd = blockMatch[1].trim();
178
- if (cmd) {
179
- commands.push(cmd);
180
- }
181
- }
182
-
183
- // Extract inline commands
184
- let inlineMatch;
185
- const inlineRegex = new RegExp(
186
- INLINE_BASH_REGEX.source,
187
- INLINE_BASH_REGEX.flags,
188
- );
189
- while ((inlineMatch = inlineRegex.exec(content)) !== null) {
190
- const cmd = inlineMatch[1].trim();
191
- if (cmd) {
192
- commands.push(cmd);
193
- }
194
- }
195
-
196
- // For now, return the content as-is. The actual command execution
197
- // will be handled by the slash command manager
198
- return {
199
- commands,
200
- processedContent: content,
201
- };
202
- }
203
-
204
- /**
205
- * Truncate output if it exceeds the size limit.
206
- * Writes to a temp file and returns a preview + file path if truncated.
207
- */
208
- export function truncateOutput(output: string): string {
209
- if (output.length <= SKILL_BASH_MAX_OUTPUT_CHARS) {
210
- return output;
211
- }
212
-
213
- const preview = output.slice(0, PREVIEW_SIZE_BYTES);
214
- const tempDir = join(tmpdir(), "wave-skill-bash");
215
- mkdirSync(tempDir, { recursive: true });
216
-
217
- const tempFile = join(
218
- tempDir,
219
- `output-${Date.now()}-${Math.random().toString(36).slice(2, 8)}.txt`,
220
- );
221
- writeFileSync(tempFile, output, "utf-8");
222
-
223
- return `${preview}\n\n[Output truncated (${output.length} chars). Full output saved to: ${tempFile}]`;
224
- }
225
-
226
- /**
227
- * Format a bash command result for inclusion in skill content.
228
- * Failed commands (non-zero exit code) are wrapped with an error indicator.
229
- */
230
- function formatBashResult(result: BashCommandResult): string {
231
- const output = truncateOutput(result.output);
232
- if (result.exitCode !== 0) {
233
- return `<error>Command failed (exit code ${result.exitCode}): ${output}</error>`;
234
- }
235
- return output;
236
- }
237
-
238
- /**
239
- * Replace bash command placeholders with their outputs.
240
- * Uses function replacer to avoid $$, $&, $' corruption in shell output.
241
- * Handles both inline (!`cmd`) and block (```! cmd ```) syntax.
242
- */
243
- export function replaceBashCommandsWithOutput(
244
- content: string,
245
- results: BashCommandResult[],
246
- ): string {
247
- let processedContent = content;
248
- let commandIndex = 0;
249
-
250
- // Replace block syntax first: ```! command ```
251
- processedContent = processedContent.replace(BLOCK_BASH_REGEX, () => {
252
- if (commandIndex < results.length) {
253
- const result = results[commandIndex++];
254
- return formatBashResult(result);
255
- }
256
- return "";
257
- });
258
-
259
- // Replace inline syntax: !`command`
260
- processedContent = processedContent.replace(INLINE_BASH_REGEX, () => {
261
- if (commandIndex < results.length) {
262
- const result = results[commandIndex++];
263
- return formatBashResult(result);
264
- }
265
- return "";
266
- });
267
-
268
- return processedContent;
269
- }
270
-
271
- /**
272
- * Execute bash commands and return results
273
- */
274
- export async function executeBashCommands(
275
- commands: string[],
276
- workdir: string,
277
- timeout: number = 30000,
278
- ): Promise<BashCommandResult[]> {
279
- const results: BashCommandResult[] = [];
280
-
281
- for (const command of commands) {
282
- try {
283
- const { stdout, stderr } = await execAsync(command, {
284
- cwd: workdir,
285
- timeout,
286
- });
287
- results.push({
288
- command,
289
- output: (stdout + (stderr || "")).trim(),
290
- exitCode: 0,
291
- });
292
- } catch (error: unknown) {
293
- const execError = error as {
294
- stdout?: string;
295
- stderr?: string;
296
- message?: string;
297
- code?: number;
298
- };
299
- const errorOutput = (
300
- (execError.stdout || "") +
301
- (execError.stderr || "") +
302
- (execError.message || "")
303
- ).trim();
304
- const exitCode = execError.code || 1;
305
- logger?.warn(
306
- `[Skill bash] Command failed (exit code ${exitCode}): ${command}\n${errorOutput}`,
307
- );
308
- results.push({
309
- command,
310
- output: errorOutput,
311
- exitCode,
312
- });
313
- }
314
- }
315
-
316
- return results;
317
- }
@@ -1,138 +0,0 @@
1
- import { ChatCompletionFunctionTool } from "openai/resources.js";
2
- import type { ToolPlugin, ToolResult, ToolContext } from "../tools/types.js";
3
- import type { McpTool, McpServerStatus } from "../types/index.js";
4
- import { processToolResult } from "./toolResultStorage.js";
5
- import { DEFAULT_MAX_RESULT_SIZE_CHARS } from "../constants/toolLimits.js";
6
-
7
- /**
8
- * Recursively clean schema to remove unsupported fields
9
- */
10
- function cleanSchema(schema: unknown): unknown {
11
- if (typeof schema !== "object" || schema === null) {
12
- return schema;
13
- }
14
-
15
- if (Array.isArray(schema)) {
16
- return schema.map(cleanSchema);
17
- }
18
-
19
- const newSchema: Record<string, unknown> = {};
20
- const obj = schema as Record<string, unknown>;
21
-
22
- for (const key in obj) {
23
- // Remove $schema as OpenAI API doesn't accept it
24
- // Remove exclusiveMinimum/exclusiveMaximum as some models (e.g. Gemini) don't support them
25
- if (
26
- key === "$schema" ||
27
- key === "exclusiveMinimum" ||
28
- key === "exclusiveMaximum"
29
- ) {
30
- continue;
31
- }
32
-
33
- // Handle type as an array (e.g. ["string", "null"])
34
- if (key === "type" && Array.isArray(obj[key])) {
35
- const types = obj[key] as string[];
36
- const nonNullTypes = types.filter((t) => t !== "null");
37
- if (nonNullTypes.length > 0) {
38
- newSchema["type"] = nonNullTypes[0];
39
- }
40
- if (types.includes("null")) {
41
- newSchema["nullable"] = true;
42
- }
43
- continue;
44
- }
45
-
46
- newSchema[key] = cleanSchema(obj[key]);
47
- }
48
- return newSchema;
49
- }
50
-
51
- /**
52
- * Convert MCP tool to OpenAI function tool format
53
- */
54
- export function mcpToolToOpenAITool(
55
- mcpTool: McpTool,
56
- serverName: string,
57
- ): ChatCompletionFunctionTool {
58
- const cleanInputSchema = cleanSchema(mcpTool.inputSchema) as Record<
59
- string,
60
- unknown
61
- >;
62
-
63
- const prefixedName = `mcp__${serverName}__${mcpTool.name}`;
64
-
65
- return {
66
- type: "function",
67
- function: {
68
- name: prefixedName,
69
- description: `${mcpTool.description || `Tool from MCP server ${serverName}`} (MCP: ${serverName})`,
70
- parameters: cleanInputSchema,
71
- },
72
- };
73
- }
74
-
75
- /**
76
- * Create a tool plugin wrapper for an MCP tool
77
- */
78
- export function createMcpToolPlugin(
79
- mcpTool: McpTool,
80
- serverName: string,
81
- executeTool: (
82
- name: string,
83
- args: Record<string, unknown>,
84
- context?: ToolContext,
85
- ) => Promise<{
86
- success: boolean;
87
- content: string;
88
- serverName?: string;
89
- images?: Array<{ data: string; mediaType?: string }>;
90
- }>,
91
- ): ToolPlugin {
92
- const prefixedName = `mcp__${serverName}__${mcpTool.name}`;
93
- return {
94
- name: prefixedName,
95
- config: mcpToolToOpenAITool(mcpTool, serverName),
96
- async execute(
97
- args: Record<string, unknown>,
98
- context?: ToolContext,
99
- ): Promise<ToolResult> {
100
- try {
101
- const result = await executeTool(prefixedName, args, context);
102
-
103
- // Process content for size limits — only text content, not images
104
- const processedContent = processToolResult(
105
- result.content || `Executed ${mcpTool.name}`,
106
- DEFAULT_MAX_RESULT_SIZE_CHARS,
107
- `mcp_${serverName}_${mcpTool.name}`,
108
- );
109
-
110
- return {
111
- success: true,
112
- content: processedContent,
113
- images: result.images,
114
- };
115
- } catch (error) {
116
- return {
117
- success: false,
118
- content: "",
119
- error: error instanceof Error ? error.message : String(error),
120
- };
121
- }
122
- },
123
- };
124
- }
125
-
126
- /**
127
- * Find which server a tool belongs to
128
- */
129
- export function findToolServer(
130
- toolName: string,
131
- servers: McpServerStatus[],
132
- ): McpServerStatus | undefined {
133
- return servers.find(
134
- (s) =>
135
- (s.status === "connected" || s.status === "reconnecting") &&
136
- s.tools?.some((t) => t.name === toolName),
137
- );
138
- }