use zod schema for copilot tool search

This commit is contained in:
Ramnique Singh 2025-08-14 05:37:05 +05:30
parent c0180e2779
commit f56ee650cf

View file

@ -59,6 +59,16 @@ const ZDoneEvent = z.object({
const ZEvent = z.union([ZTextEvent, ZToolCallEvent, ZToolResultEvent, ZDoneEvent]); const ZEvent = z.union([ZTextEvent, ZToolCallEvent, ZToolResultEvent, ZDoneEvent]);
const composioToolSearchToolSuggestion = z.object({
toolkit: z.string(),
tool_slug: z.string(),
description: z.string(),
});
const composioToolSearchResponseSchema = z.object({
results: z.array(composioToolSearchToolSuggestion),
related_tools: z.array(composioToolSearchToolSuggestion),
});
function getContextPrompt(context: z.infer<typeof CopilotChatContext> | null): string { function getContextPrompt(context: z.infer<typeof CopilotChatContext> | null): string {
let prompt = ''; let prompt = '';
switch (context?.type) { switch (context?.type) {
@ -127,47 +137,29 @@ async function searchRelevantTools(query: string): Promise<string> {
arguments: { use_case: query }, arguments: { use_case: query },
}); });
if (!searchResult.successful || !Array.isArray(searchResult.data?.results)) { if (!searchResult.successful) {
logger.log("tool search was not successful or returned no results"); logger.log(`tool search failed: ${searchResult.error}`)
console.log("❌ TOOL CALL FAILED: COMPOSIO_SEARCH_TOOLS", { return 'No tools found!';
successful: searchResult.successful,
results: searchResult.data?.results
});
return '';
} }
// Log the actual response structure to debug // parse results
logger.log("Raw search results:", JSON.stringify(searchResult.data.results, null, 2)); const result = composioToolSearchResponseSchema.safeParse(searchResult.data);
if (!result.success) {
// Extract tool slugs with defensive handling for different possible field names logger.log(`tool search response is invalid: ${result.error}`);
const toolSlugs: string[] = searchResult.data.results return 'No tools found!';
.map((result: any) => { }
// Try different possible field names for the tool slug if (!result.data.results.length) {
const slug = result.tool || result.slug || result.tool_slug || result.name; logger.log(`tool search yielded no results`);
logger.log(`Processing result:`, { result, extractedSlug: slug }); return 'No tools found!';
return slug;
})
.filter((slug): slug is string => {
const isValid = typeof slug === 'string' && slug.length > 0;
if (!isValid) {
logger.log(`Filtering out invalid slug:`, slug);
} }
return isValid;
});
const toolSlugs = result.data.results.map((item) => item.tool_slug);
logger.log(`found tool slugs: ${toolSlugs.join(', ')}`); logger.log(`found tool slugs: ${toolSlugs.join(', ')}`);
console.log("✅ TOOL CALL SUCCESS: COMPOSIO_SEARCH_TOOLS", { console.log("✅ TOOL CALL SUCCESS: COMPOSIO_SEARCH_TOOLS", {
toolSlugs, toolSlugs,
resultCount: toolSlugs.length resultCount: toolSlugs.length
}); });
// Check if we have any valid tool slugs before proceeding
if (toolSlugs.length === 0) {
logger.log("No valid tool slugs found after filtering");
console.log("⚠️ TOOL CALL WARNING: No valid tools found after filtering");
return 'No valid tools found for the given query. The search returned results but they contained invalid tool identifiers.';
}
// Enrich tools with full details // Enrich tools with full details
console.log("🔧 TOOL CALL: getTool (multiple calls)", { toolSlugs }); console.log("🔧 TOOL CALL: getTool (multiple calls)", { toolSlugs });
const composioTools = await Promise.all(toolSlugs.map(slug => getTool(slug))); const composioTools = await Promise.all(toolSlugs.map(slug => getTool(slug)));