fix(tools): return error objects instead of throwing in registry tools
All tool executions now return error objects instead of throwing exceptions. This allows the AI model to see errors and respond appropriately instead of causing the entire stream to fail silently.
This commit is contained in:
parent
88e66d54ce
commit
9fc928adae
2 changed files with 148 additions and 103 deletions
|
|
@ -49,17 +49,26 @@ export const registryExecuteTool = tool({
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
}),
|
}),
|
||||||
async execute({ toolId, params, env }) {
|
async execute({ toolId, params, env }) {
|
||||||
|
try {
|
||||||
// Parse toolId format: "package::name"
|
// Parse toolId format: "package::name"
|
||||||
const separatorIndex = toolId.lastIndexOf('::');
|
const separatorIndex = toolId.lastIndexOf('::');
|
||||||
if (separatorIndex === -1) {
|
if (separatorIndex === -1) {
|
||||||
throw new Error(`Invalid toolId format. Expected "package::name", got "${toolId}"`);
|
return {
|
||||||
|
error: true,
|
||||||
|
message: `Invalid toolId format. Expected "package::name", got "${toolId}"`,
|
||||||
|
toolId,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const packageName = toolId.substring(0, separatorIndex);
|
const packageName = toolId.substring(0, separatorIndex);
|
||||||
const name = toolId.substring(separatorIndex + 2);
|
const name = toolId.substring(separatorIndex + 2);
|
||||||
|
|
||||||
if (!packageName || !name) {
|
if (!packageName || !name) {
|
||||||
throw new Error(`Invalid toolId format. Expected "package::name", got "${toolId}"`);
|
return {
|
||||||
|
error: true,
|
||||||
|
message: `Invalid toolId format. Expected "package::name", got "${toolId}"`,
|
||||||
|
toolId,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch tool metadata to get version and importUrl
|
// Fetch tool metadata to get version and importUrl
|
||||||
|
|
@ -70,7 +79,11 @@ export const registryExecuteTool = tool({
|
||||||
const metaResponse = await fetch(`${TPMJS_API_URL}/api/tools/search?${metaParams}`);
|
const metaResponse = await fetch(`${TPMJS_API_URL}/api/tools/search?${metaParams}`);
|
||||||
|
|
||||||
if (!metaResponse.ok) {
|
if (!metaResponse.ok) {
|
||||||
throw new Error(`Failed to fetch tool metadata: ${metaResponse.statusText}`);
|
return {
|
||||||
|
error: true,
|
||||||
|
message: `Failed to fetch tool metadata: ${metaResponse.statusText}`,
|
||||||
|
toolId,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: API response types vary
|
// biome-ignore lint/suspicious/noExplicitAny: API response types vary
|
||||||
|
|
@ -84,7 +97,11 @@ export const registryExecuteTool = tool({
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!toolMeta) {
|
if (!toolMeta) {
|
||||||
throw new Error(`Tool not found: ${toolId}`);
|
return {
|
||||||
|
error: true,
|
||||||
|
message: `Tool not found: ${toolId}. Try using registrySearchTool to find available tools.`,
|
||||||
|
toolId,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const version = toolMeta.package.npmVersion;
|
const version = toolMeta.package.npmVersion;
|
||||||
|
|
@ -108,7 +125,12 @@ export const registryExecuteTool = tool({
|
||||||
const result = (await response.json()) as any;
|
const result = (await response.json()) as any;
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.error || 'Tool execution failed');
|
return {
|
||||||
|
error: true,
|
||||||
|
message: result.error || 'Tool execution failed',
|
||||||
|
toolId,
|
||||||
|
executionTimeMs: result.executionTimeMs,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -116,5 +138,12 @@ export const registryExecuteTool = tool({
|
||||||
executionTimeMs: result.executionTimeMs,
|
executionTimeMs: result.executionTimeMs,
|
||||||
output: result.output,
|
output: result.output,
|
||||||
};
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
message: error instanceof Error ? error.message : 'Unknown execution error',
|
||||||
|
toolId,
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ export const registrySearchTool = tool({
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
}),
|
}),
|
||||||
async execute({ query, category, limit = 5 }) {
|
async execute({ query, category, limit = 5 }) {
|
||||||
|
try {
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
q: query,
|
q: query,
|
||||||
limit: String(limit),
|
limit: String(limit),
|
||||||
|
|
@ -68,7 +69,13 @@ export const registrySearchTool = tool({
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
throw new Error(`Search failed: ${response.statusText}`);
|
return {
|
||||||
|
error: true,
|
||||||
|
message: `Search failed: ${response.statusText}`,
|
||||||
|
query,
|
||||||
|
matchCount: 0,
|
||||||
|
tools: [],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// biome-ignore lint/suspicious/noExplicitAny: API response types vary
|
// biome-ignore lint/suspicious/noExplicitAny: API response types vary
|
||||||
|
|
@ -98,5 +105,14 @@ export const registrySearchTool = tool({
|
||||||
qualityScore: t.qualityScore,
|
qualityScore: t.qualityScore,
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
error: true,
|
||||||
|
message: error instanceof Error ? error.message : 'Unknown search error',
|
||||||
|
query,
|
||||||
|
matchCount: 0,
|
||||||
|
tools: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue