|
| 1 | +import { z } from "zod"; |
| 2 | + |
| 3 | +// Search arguments schema for ChatGPT MCP |
| 4 | +export const SearchArgumentsSchema = z.object({ |
| 5 | + query: z.string().describe("Search query string"), |
| 6 | + limit: z.number().optional().describe("Maximum number of results to return"), |
| 7 | +}); |
| 8 | + |
| 9 | +export type SearchArguments = z.infer<typeof SearchArgumentsSchema>; |
| 10 | + |
| 11 | +// Search result interface |
| 12 | +interface SearchResult { |
| 13 | + title: string; |
| 14 | + content: string; |
| 15 | + url?: string; |
| 16 | + metadata?: Record<string, any>; |
| 17 | +} |
| 18 | + |
| 19 | +// Main search handler that ChatGPT expects |
| 20 | +export async function handleSearch( |
| 21 | + args: SearchArguments, |
| 22 | + token: string, |
| 23 | + customerContext?: string |
| 24 | +): Promise<{ results: SearchResult[] }> { |
| 25 | + const { query, limit = 10 } = args; |
| 26 | + |
| 27 | + // Search across DoiT resources based on query |
| 28 | + const results: SearchResult[] = []; |
| 29 | + |
| 30 | + try { |
| 31 | + // Search in reports |
| 32 | + if (query.toLowerCase().includes('report') || query.toLowerCase().includes('cost') || query.toLowerCase().includes('analytics')) { |
| 33 | + try { |
| 34 | + const { handleReportsRequest } = await import("../../src/tools/reports.js"); |
| 35 | + const reportsResponse = await handleReportsRequest({ customerContext }, token); |
| 36 | + |
| 37 | + if (reportsResponse.content?.[0]?.text) { |
| 38 | + const reports = JSON.parse(reportsResponse.content[0].text); |
| 39 | + reports.slice(0, Math.min(3, limit)).forEach((report: any) => { |
| 40 | + results.push({ |
| 41 | + title: `Report: ${report.name || report.id}`, |
| 42 | + content: `DoiT Analytics Report - ${report.description || 'Cloud cost and usage analytics'}`, |
| 43 | + metadata: { type: 'report', id: report.id } |
| 44 | + }); |
| 45 | + }); |
| 46 | + } |
| 47 | + } catch (error) { |
| 48 | + console.error('Reports search error:', error); |
| 49 | + } |
| 50 | + } |
| 51 | + |
| 52 | + // Search in anomalies |
| 53 | + if (query.toLowerCase().includes('anomaly') || query.toLowerCase().includes('alert') || query.toLowerCase().includes('unusual')) { |
| 54 | + try { |
| 55 | + const { handleAnomaliesRequest } = await import("../../src/tools/anomalies.js"); |
| 56 | + const anomaliesResponse = await handleAnomaliesRequest({ customerContext }, token); |
| 57 | + |
| 58 | + if (anomaliesResponse.content?.[0]?.text) { |
| 59 | + const anomalies = JSON.parse(anomaliesResponse.content[0].text); |
| 60 | + anomalies.slice(0, Math.min(3, limit - results.length)).forEach((anomaly: any) => { |
| 61 | + results.push({ |
| 62 | + title: `Anomaly: ${anomaly.title || anomaly.id}`, |
| 63 | + content: `Cost anomaly detected - ${anomaly.description || 'Unusual spending pattern identified'}`, |
| 64 | + metadata: { type: 'anomaly', id: anomaly.id } |
| 65 | + }); |
| 66 | + }); |
| 67 | + } |
| 68 | + } catch (error) { |
| 69 | + console.error('Anomalies search error:', error); |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + // Search in cloud incidents |
| 74 | + if (query.toLowerCase().includes('incident') || query.toLowerCase().includes('issue') || query.toLowerCase().includes('outage')) { |
| 75 | + try { |
| 76 | + const { handleCloudIncidentsRequest } = await import("../../src/tools/cloudIncidents.js"); |
| 77 | + const incidentsResponse = await handleCloudIncidentsRequest({ customerContext }, token); |
| 78 | + |
| 79 | + if (incidentsResponse.content?.[0]?.text) { |
| 80 | + const incidents = JSON.parse(incidentsResponse.content[0].text); |
| 81 | + incidents.slice(0, Math.min(3, limit - results.length)).forEach((incident: any) => { |
| 82 | + results.push({ |
| 83 | + title: `Incident: ${incident.title || incident.id}`, |
| 84 | + content: `Cloud service incident - ${incident.description || 'Service disruption or issue'}`, |
| 85 | + metadata: { type: 'incident', id: incident.id } |
| 86 | + }); |
| 87 | + }); |
| 88 | + } |
| 89 | + } catch (error) { |
| 90 | + console.error('Incidents search error:', error); |
| 91 | + } |
| 92 | + } |
| 93 | + |
| 94 | + // Search in tickets |
| 95 | + if (query.toLowerCase().includes('ticket') || query.toLowerCase().includes('support')) { |
| 96 | + try { |
| 97 | + const { handleListTicketsRequest } = await import("../../src/tools/tickets.js"); |
| 98 | + const ticketsResponse = await handleListTicketsRequest({ customerContext }, token); |
| 99 | + |
| 100 | + if (ticketsResponse.content?.[0]?.text) { |
| 101 | + const tickets = JSON.parse(ticketsResponse.content[0].text); |
| 102 | + tickets.slice(0, Math.min(3, limit - results.length)).forEach((ticket: any) => { |
| 103 | + results.push({ |
| 104 | + title: `Ticket: ${ticket.subject || ticket.id}`, |
| 105 | + content: `Support ticket - ${ticket.description || 'Customer support request'}`, |
| 106 | + metadata: { type: 'ticket', id: ticket.id } |
| 107 | + }); |
| 108 | + }); |
| 109 | + } |
| 110 | + } catch (error) { |
| 111 | + console.error('Tickets search error:', error); |
| 112 | + } |
| 113 | + } |
| 114 | + |
| 115 | + // If no specific matches, provide general DoiT information |
| 116 | + if (results.length === 0) { |
| 117 | + results.push({ |
| 118 | + title: "DoiT Platform Overview", |
| 119 | + content: `DoiT provides cloud cost optimization, analytics, and support services. Available data includes cost reports, anomaly detection, cloud incidents, and support tickets. Try searching for specific terms like 'reports', 'anomalies', 'incidents', or 'tickets'.`, |
| 120 | + metadata: { type: 'general' } |
| 121 | + }); |
| 122 | + } |
| 123 | + |
| 124 | + } catch (error) { |
| 125 | + console.error('Search error:', error); |
| 126 | + results.push({ |
| 127 | + title: "Search Error", |
| 128 | + content: `Unable to complete search for "${query}". Please check your authentication and try again.`, |
| 129 | + metadata: { type: 'error' } |
| 130 | + }); |
| 131 | + } |
| 132 | + |
| 133 | + return { results: results.slice(0, limit) }; |
| 134 | +} |
| 135 | + |
| 136 | +// Export the search tool definition |
| 137 | +export const searchTool = { |
| 138 | + name: "search", |
| 139 | + description: "Search across DoiT platform data including reports, anomalies, incidents, and tickets", |
| 140 | +}; |
0 commit comments