UNPKG

@simonecoelhosfo/optimizely-mcp-server

Version:

Optimizely MCP Server for AI assistants with integrated CLI tools

296 lines 9.47 kB
/** * Action Pattern Definitions for RobustIntentParser * * IMPLEMENTATION STATUS: * COMPLETE: All 15 primary actions defined with patterns * * Last Updated: July 3, 2025 */ export const ACTION_PATTERNS = { // Basic retrieval actions find: { action: 'find', patterns: [ /find/i, /search\s+for/i, /look\s+for/i, /locate/i, /discover/i, /identify/i ], defaultFields: ['name', 'key', 'id'], impliesAggregation: false }, list: { action: 'list', patterns: [ /list/i, /enumerate/i, /show\s+all/i, /display\s+all/i, /get\s+all/i, /fetch\s+all/i, /retrieve\s+all/i ], defaultFields: ['name', 'key', 'status', 'created_time'], impliesAggregation: false }, show: { action: 'show', patterns: [ /show(?!\s+all)/i, /display(?!\s+all)/i, /present/i, /reveal/i, /view/i, /see/i ], defaultFields: ['name', 'key', 'status', 'description'], impliesAggregation: false }, // Aggregation actions count: { action: 'count', patterns: [ /count/i, /how\s+many/i, /number\s+of/i, /total(?:\s+number)?/i, /quantity/i, /tally/i, /amount/i ], defaultFields: ['id'], impliesAggregation: true }, group: { action: 'group', patterns: [ /group(?:ed)?\s+by/i, /categorize/i, /organize\s+by/i, /cluster/i, /breakdown\s+by/i, /segment\s+by/i ], defaultFields: ['name', 'count'], impliesAggregation: true }, aggregate: { action: 'aggregate', patterns: [ /aggregate/i, /sum(?:marize)?/i, /total\s+up/i, /combine/i, /accumulate/i, /roll\s+up/i ], defaultFields: ['value', 'count'], impliesAggregation: true }, // Analysis actions analyze: { action: 'analyze', patterns: [ /analyze/i, /analysis/i, /examine/i, /investigate/i, /study/i, /evaluate/i, /assess/i ], defaultFields: ['name', 'metrics', 'performance'], impliesAggregation: false }, compare: { action: 'compare', patterns: [ /compare/i, /contrast/i, /versus|vs\.?/i, /differ(?:ence)?/i, /match\s+against/i, /side\s+by\s+side/i ], defaultFields: ['name', 'value', 'difference'], impliesAggregation: false }, trend: { action: 'trend', patterns: [ /trend/i, /over\s+time/i, /timeline/i, /history/i, /progression/i, /evolution/i, /time\s+series/i, /by\s+(?:day|week|month|year)/i ], defaultFields: ['date', 'value', 'change'], impliesAggregation: true }, // Summary actions summarize: { action: 'summarize', patterns: [ /summar(?:y|ize)/i, /overview/i, /recap/i, /brief/i, /digest/i, /synopsis/i, /report/i ], defaultFields: ['name', 'status', 'count', 'key_metrics'], impliesAggregation: true }, // L7-11 FIX: Error action for invalid queries error: { action: 'error', patterns: [], defaultFields: [], impliesAggregation: false } }; /** * Detect the primary action from a query */ export function detectAction(query) { const normalizedQuery = query.toLowerCase(); let bestMatch = { action: 'find', confidence: 0.3, match: '' }; // Default // L7-13 FIX: Frequency-based queries should be treated as aggregation (count action) if (/most\s+frequently|most\s+often|tracked.*frequently|used.*frequently/i.test(query)) { return { action: 'count', confidence: 0.98, match: 'frequency pattern detected' }; } for (const [action, pattern] of Object.entries(ACTION_PATTERNS)) { for (const regex of pattern.patterns) { const match = normalizedQuery.match(regex); if (match) { // Higher confidence for exact word matches vs partial matches const isExactWord = new RegExp(`\\b${match[0]}\\b`, 'i').test(normalizedQuery); const confidence = isExactWord ? 0.95 : 0.85; if (confidence > bestMatch.confidence) { bestMatch = { action: action, confidence, match: match[0] }; } } } } // Special case: queries starting with "what", "which", "where" often imply find/list if (bestMatch.confidence < 0.5) { if (/^(what|which|where|who|when)\s+/i.test(normalizedQuery)) { bestMatch = { action: normalizedQuery.includes('all') ? 'list' : 'find', confidence: 0.6, match: 'implicit from question word' }; } } return bestMatch; } /** * Get the action pattern configuration with entity-aware default fields */ export function getActionPattern(action, entity) { const basePattern = ACTION_PATTERNS[action] || ACTION_PATTERNS.find; // Return entity-aware default fields if (entity) { const entityAwareFields = getEntityAwareDefaultFields(action, entity); if (entityAwareFields.length > 0) { return { ...basePattern, defaultFields: entityAwareFields }; } } return basePattern; } /** * Get entity-specific default fields for actions */ function getEntityAwareDefaultFields(action, entity) { const entityFieldMap = { // FLAGS: Use 'archived' not 'status' flags: { find: ['name', 'key', 'id'], list: ['name', 'key', 'archived', 'created_time'], show: ['name', 'key', 'archived', 'description'], count: ['id'], group: ['name', 'count'], aggregate: ['value', 'count'], analyze: ['name', 'environments', 'performance'], compare: ['name', 'value', 'difference'], trend: ['date', 'value', 'change'], summarize: ['name', 'archived', 'count', 'environments'], error: [] // L7-11 FIX }, // EXPERIMENTS: Use 'status' experiments: { find: ['name', 'id'], list: ['name', 'id', 'status', 'created_time'], show: ['name', 'id', 'status', 'description'], count: ['id'], group: ['name', 'count'], aggregate: ['value', 'count'], analyze: ['name', 'metrics', 'performance'], compare: ['name', 'value', 'difference'], trend: ['date', 'value', 'change'], summarize: ['name', 'status', 'count', 'metrics'], error: [] // L7-11 FIX }, // VARIATIONS: Use 'status' variations: { find: ['name', 'key', 'id'], list: ['name', 'key', 'status', 'weight'], show: ['name', 'key', 'status', 'description'], count: ['id'], group: ['name', 'count'], aggregate: ['value', 'count'], analyze: ['name', 'weight', 'performance'], compare: ['name', 'value', 'difference'], trend: ['date', 'value', 'change'], summarize: ['name', 'status', 'count', 'weight'], error: [] // L7-11 FIX }, // AUDIENCES: Use 'archived' audiences: { find: ['name', 'key', 'id'], list: ['name', 'id', 'archived', 'created_time'], show: ['name', 'id', 'archived', 'description'], count: ['id'], group: ['name', 'count'], aggregate: ['value', 'count'], analyze: ['name', 'conditions', 'usage'], compare: ['name', 'value', 'difference'], trend: ['date', 'value', 'change'], summarize: ['name', 'archived', 'count', 'usage'], error: [] // L7-11 FIX }, // EXPERIMENT_RESULTS: Special fields experiment_results: { find: ['experiment_id', 'start_time'], list: ['experiment_id', 'start_time', 'end_time'], show: ['experiment_id', 'start_time', 'end_time', 'confidence_threshold'], count: ['experiment_id'], group: ['experiment_id', 'count'], aggregate: ['value', 'count'], analyze: ['experiment_id', 'metrics', 'confidence'], compare: ['experiment_id', 'value', 'difference'], trend: ['date', 'value', 'change'], summarize: ['experiment_id', 'confidence', 'count', 'metrics'], error: [] // L7-11 FIX } }; return entityFieldMap[entity]?.[action] || []; } //# sourceMappingURL=ActionPatterns.js.map