Skip to main content
Glama
intent-classifier.ts5.56 kB
interface ClassifiedIntent { action: string; target: string; confidence: number; parameters: Record<string, any>; raw_input: string; } interface ActionPattern { action: string; patterns: RegExp[]; parameters?: string[]; } export class IntentClassifier { private actionPatterns: ActionPattern[]; constructor() { this.actionPatterns = [ { action: 'turn_on', patterns: [ /turn\s+on/i, /switch\s+on/i, /enable/i, /activate/i ] }, { action: 'turn_off', patterns: [ /turn\s+off/i, /switch\s+off/i, /disable/i, /deactivate/i ] }, { action: 'set', patterns: [ /set\s+(?:the\s+)?(.+)\s+to/i, /change\s+(?:the\s+)?(.+)\s+to/i, /adjust\s+(?:the\s+)?(.+)\s+to/i ], parameters: ['brightness', 'temperature', 'color'] }, { action: 'query', patterns: [ /what\s+is/i, /get\s+(?:the\s+)?(.+)/i, /show\s+(?:the\s+)?(.+)/i, /tell\s+me/i ] } ]; } async classify( input: string, extractedEntities: { parameters: Record<string, any>; primary_target: string } ): Promise<ClassifiedIntent> { let bestMatch: ClassifiedIntent = { action: '', target: '', confidence: 0, parameters: {}, raw_input: input }; for (const actionPattern of this.actionPatterns) { for (const pattern of actionPattern.patterns) { const match = input.match(pattern); if (match) { const confidence = this.calculateConfidence(match[0], input); if (confidence > bestMatch.confidence) { bestMatch = { action: actionPattern.action, target: extractedEntities.primary_target, confidence, parameters: this.extractActionParameters(actionPattern, match, extractedEntities), raw_input: input }; } } } } // If no match found, try to infer from context if (!bestMatch.action) { bestMatch = this.inferFromContext(input, extractedEntities); } return bestMatch; } private calculateConfidence(match: string, input: string): number { // Base confidence from match length relative to input length const lengthRatio = match.length / input.length; let confidence = lengthRatio * 0.7; // Boost confidence for exact matches if (match.toLowerCase() === input.toLowerCase()) { confidence += 0.3; } // Additional confidence for specific keywords const keywords = ['please', 'can you', 'would you']; for (const keyword of keywords) { if (input.toLowerCase().includes(keyword)) { confidence += 0.1; } } return Math.min(1, confidence); } private extractActionParameters( actionPattern: ActionPattern, match: RegExpMatchArray, extractedEntities: { parameters: Record<string, any>; primary_target: string } ): Record<string, any> { const parameters: Record<string, any> = {}; // Copy relevant extracted entities if (actionPattern.parameters) { for (const param of actionPattern.parameters) { if (extractedEntities.parameters[param] !== undefined) { parameters[param] = extractedEntities.parameters[param]; } } } // Extract additional parameters from match groups if (match.length > 1 && match[1]) { parameters.raw_parameter = match[1].trim(); } return parameters; } private inferFromContext( input: string, extractedEntities: { parameters: Record<string, any>; primary_target: string } ): ClassifiedIntent { // Default to 'set' action if parameters are present if (Object.keys(extractedEntities.parameters).length > 0) { return { action: 'set', target: extractedEntities.primary_target, confidence: 0.5, parameters: extractedEntities.parameters, raw_input: input }; } // Default to 'query' for question-like inputs if (input.match(/^(what|when|where|who|how|why)/i)) { return { action: 'query', target: extractedEntities.primary_target || 'system', confidence: 0.6, parameters: {}, raw_input: input }; } // Fallback with low confidence return { action: 'unknown', target: extractedEntities.primary_target || 'system', confidence: 0.3, parameters: {}, raw_input: input }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tevonsb/homeassistant-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server