@simonecoelhosfo/optimizely-mcp-server
Version:
Optimizely MCP Server for AI assistants with integrated CLI tools
296 lines • 9.47 kB
JavaScript
/**
* 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