@oh-my-pi/exa 0.5.1 → 0.6.0
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/package.json +1 -1
- package/tools/exa/shared.ts +52 -7
package/package.json
CHANGED
package/tools/exa/shared.ts
CHANGED
|
@@ -28,6 +28,29 @@ interface MCPToolsResponse {
|
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
function normalizeInputSchema(schema: unknown): Record<string, unknown> {
|
|
32
|
+
if (!schema || typeof schema !== "object") {
|
|
33
|
+
return { type: "object", properties: {}, required: [] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const normalized = { ...(schema as Record<string, unknown>) };
|
|
37
|
+
|
|
38
|
+
if (!("type" in normalized)) {
|
|
39
|
+
normalized.type = "object";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!("properties" in normalized)) {
|
|
43
|
+
normalized.properties = {};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const required = (normalized as { required?: unknown }).required;
|
|
47
|
+
if (!Array.isArray(required)) {
|
|
48
|
+
normalized.required = [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return normalized;
|
|
52
|
+
}
|
|
53
|
+
|
|
31
54
|
/**
|
|
32
55
|
* Parse a .env file and return key-value pairs
|
|
33
56
|
*/
|
|
@@ -142,7 +165,7 @@ export async function fetchExaTools(
|
|
|
142
165
|
apiKey: string,
|
|
143
166
|
toolNames: string[],
|
|
144
167
|
): Promise<MCPTool[]> {
|
|
145
|
-
const url = `${EXA_MCP_URL}?exaApiKey=${apiKey}&tools=${toolNames.join(",")}`;
|
|
168
|
+
const url = `${EXA_MCP_URL}?exaApiKey=${encodeURIComponent(apiKey)}&tools=${encodeURIComponent(toolNames.join(","))}`;
|
|
146
169
|
|
|
147
170
|
try {
|
|
148
171
|
const response = (await callMCP(url, "tools/list")) as MCPToolsResponse;
|
|
@@ -160,7 +183,7 @@ export async function fetchExaTools(
|
|
|
160
183
|
* Fetch available tools from Websets MCP server
|
|
161
184
|
*/
|
|
162
185
|
export async function fetchWebsetsTools(apiKey: string): Promise<MCPTool[]> {
|
|
163
|
-
const url = `${WEBSETS_MCP_URL}?exaApiKey=${apiKey}`;
|
|
186
|
+
const url = `${WEBSETS_MCP_URL}?exaApiKey=${encodeURIComponent(apiKey)}`;
|
|
164
187
|
|
|
165
188
|
try {
|
|
166
189
|
const response = (await callMCP(url, "tools/list")) as MCPToolsResponse;
|
|
@@ -183,7 +206,7 @@ export async function callExaTool(
|
|
|
183
206
|
toolName: string,
|
|
184
207
|
args: Record<string, unknown>,
|
|
185
208
|
): Promise<unknown> {
|
|
186
|
-
const url = `${EXA_MCP_URL}?exaApiKey=${apiKey}&tools=${toolNames.join(",")}`;
|
|
209
|
+
const url = `${EXA_MCP_URL}?exaApiKey=${encodeURIComponent(apiKey)}&tools=${encodeURIComponent(toolNames.join(","))}`;
|
|
187
210
|
return callMCPTool(url, toolName, args);
|
|
188
211
|
}
|
|
189
212
|
|
|
@@ -195,7 +218,7 @@ export async function callWebsetsTool(
|
|
|
195
218
|
toolName: string,
|
|
196
219
|
args: Record<string, unknown>,
|
|
197
220
|
): Promise<unknown> {
|
|
198
|
-
const url = `${WEBSETS_MCP_URL}?exaApiKey=${apiKey}`;
|
|
221
|
+
const url = `${WEBSETS_MCP_URL}?exaApiKey=${encodeURIComponent(apiKey)}`;
|
|
199
222
|
return callMCPTool(url, toolName, args);
|
|
200
223
|
}
|
|
201
224
|
|
|
@@ -247,10 +270,32 @@ export function createToolWrapper(
|
|
|
247
270
|
): CustomAgentTool<TSchema, unknown> {
|
|
248
271
|
return {
|
|
249
272
|
name: renamedName,
|
|
273
|
+
label: renamedName.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
|
|
250
274
|
description: mcpTool.description,
|
|
251
|
-
parameters: mcpTool.inputSchema,
|
|
252
|
-
async execute(
|
|
253
|
-
|
|
275
|
+
parameters: normalizeInputSchema(mcpTool.inputSchema) as TSchema,
|
|
276
|
+
async execute(_toolCallId, params) {
|
|
277
|
+
try {
|
|
278
|
+
const result = await callFn(
|
|
279
|
+
mcpTool.name,
|
|
280
|
+
(params ?? {}) as Record<string, unknown>,
|
|
281
|
+
);
|
|
282
|
+
const text =
|
|
283
|
+
typeof result === "string"
|
|
284
|
+
? result
|
|
285
|
+
: result == null
|
|
286
|
+
? "null"
|
|
287
|
+
: JSON.stringify(result, null, 2) ?? String(result);
|
|
288
|
+
return {
|
|
289
|
+
content: [{ type: "text" as const, text }],
|
|
290
|
+
details: result,
|
|
291
|
+
};
|
|
292
|
+
} catch (error) {
|
|
293
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
294
|
+
return {
|
|
295
|
+
content: [{ type: "text" as const, text: `Error: ${message}` }],
|
|
296
|
+
details: { error: message },
|
|
297
|
+
};
|
|
298
|
+
}
|
|
254
299
|
},
|
|
255
300
|
};
|
|
256
301
|
}
|