Skip to main content
Glama
IntuitiveProcessor.ts20.8 kB
/** * System 1 (Intuitive) Processor - Fast, automatic, pattern-based thinking * Implements Kahneman's System 1 thinking with pattern matching and heuristics */ import { ComponentStatus, HeuristicResult, ISystem1Processor, Pattern, } from "../interfaces/cognitive.js"; import { CognitiveInput, EmotionalState, ProcessingMode, ReasoningStep, ReasoningType, ThoughtResult, } from "../types/core.js"; interface IntuitiveConfig { pattern_threshold?: number; confidence_decay?: number; max_patterns?: number; heuristic_weight?: number; } export class IntuitiveProcessor implements ISystem1Processor { private initialized: boolean = false; private patternCache: Map<string, Pattern[]> = new Map(); private heuristicRules: Map< string, (input: string, patterns: Pattern[]) => HeuristicResult > = new Map(); private lastActivity: number = 0; private config: IntuitiveConfig = {}; async initialize(config: IntuitiveConfig): Promise<void> { this.config = { pattern_threshold: 0.3, confidence_decay: 0.1, max_patterns: 50, heuristic_weight: 0.8, ...config, }; this.initializeHeuristics(); this.initialized = true; } private initializeHeuristics(): void { // Availability heuristic - judge by ease of recall this.heuristicRules.set( "availability", (_input: string, patterns: Pattern[]) => { const recentPatterns = patterns.filter((p) => p.salience > 0.7); return { name: "availability", type: "availability", confidence: recentPatterns.length > 0 ? 0.8 : 0.3, result: `Based on ${recentPatterns.length} easily recalled patterns`, processing_time: 1, }; } ); // Representativeness heuristic - judge by similarity to prototypes this.heuristicRules.set( "representativeness", (_input: string, patterns: Pattern[]) => { const prototypeMatches = patterns.filter( (p) => p.type === "prototype" && p.confidence > 0.6 ); return { name: "representativeness", type: "representativeness", confidence: prototypeMatches.length > 0 ? 0.7 : 0.4, result: `Matches ${prototypeMatches.length} known prototypes`, processing_time: 2, }; } ); // Anchoring heuristic - influenced by initial information this.heuristicRules.set( "anchoring", (_input: string, patterns: Pattern[]) => { const firstPattern = patterns[0]; return { name: "anchoring", type: "anchoring", confidence: firstPattern ? firstPattern.confidence * 0.9 : 0.2, result: `Anchored on first impression: ${ firstPattern?.content.join(" ") ?? "none" }`, processing_time: 1, }; } ); // Affect heuristic - "how do I feel about it?" this.heuristicRules.set("affect", (_input: string, patterns: Pattern[]) => { const emotionalPatterns = patterns.filter((p) => p.type === "emotional"); const avgSalience = emotionalPatterns.reduce((sum, p) => sum + p.salience, 0) / (emotionalPatterns.length || 1); return { name: "affect", type: "affect", confidence: avgSalience > 0.5 ? 0.8 : 0.3, result: `Emotional response strength: ${avgSalience.toFixed(2)}`, processing_time: 1, }; }); } async processIntuitive(input: CognitiveInput): Promise<ThoughtResult> { const startTime = Date.now(); this.lastActivity = startTime; try { // Step 1: Pattern matching const patterns = this.matchPatterns(input.input); // Step 2: Apply heuristics const heuristicResults = this.applyHeuristics(input.input, patterns); // Step 3: Generate intuitive response const response = this.generateIntuitiveResponse( input.input, patterns, heuristicResults ); // Step 4: Assess confidence const confidence = this.getConfidence(response); // Step 5: Create reasoning path const reasoningPath = this.createReasoningPath( patterns, heuristicResults, response ); const processingTime = Date.now() - startTime; return { content: response.content, confidence: confidence, reasoning_path: reasoningPath, emotional_context: this.assessEmotionalContext(input.input, patterns), metadata: { processing_time_ms: processingTime, components_used: ["IntuitiveProcessor"], memory_retrievals: patterns.length, system_mode: ProcessingMode.INTUITIVE, temperature: input.configuration.temperature, }, }; } catch (error) { throw new Error( `Intuitive processing failed: ${(error as Error).message}` ); } } matchPatterns(input: string): Pattern[] { // Check cache first const cachedPatterns = this.patternCache.get(input); if (cachedPatterns) { return cachedPatterns; } const patterns: Pattern[] = []; const tokens = input.toLowerCase().split(/\s+/); // Simple pattern matching based on common structures patterns.push(...this.detectQuestionPatterns(tokens)); patterns.push(...this.detectEmotionalPatterns(tokens)); patterns.push(...this.detectCausalPatterns(tokens)); patterns.push(...this.detectComparisonPatterns(tokens)); patterns.push(...this.detectNegationPatterns(tokens)); // Cache results if (patterns.length > 0) { this.patternCache.set(input, patterns); // Limit cache size if (this.patternCache.size > (this.config.max_patterns ?? 50)) { const firstKey = this.patternCache.keys().next().value; if (firstKey) { this.patternCache.delete(firstKey); } } } return patterns; } private detectQuestionPatterns(tokens: string[]): Pattern[] { const questionWords = [ "what", "how", "why", "when", "where", "who", "which", ]; const patterns: Pattern[] = []; for (const qWord of questionWords) { if (tokens.includes(qWord)) { patterns.push({ type: "question", content: [ qWord, ...tokens.slice(tokens.indexOf(qWord), tokens.indexOf(qWord) + 3), ], confidence: 0.9, salience: 0.8, }); } } return patterns; } private detectEmotionalPatterns(tokens: string[]): Pattern[] { const emotionalWords = { positive: [ "good", "great", "excellent", "happy", "love", "amazing", "wonderful", ], negative: [ "bad", "terrible", "hate", "awful", "horrible", "sad", "angry", ], neutral: ["okay", "fine", "normal", "average"], }; const patterns: Pattern[] = []; for (const [valence, words] of Object.entries(emotionalWords)) { for (const word of words) { if (tokens.includes(word)) { patterns.push({ type: "emotional", content: [word], confidence: 0.7, salience: valence === "neutral" ? 0.4 : 0.8, }); } } } return patterns; } private detectCausalPatterns(tokens: string[]): Pattern[] { const causalIndicators = [ "because", "since", "due to", "caused by", "results in", "leads to", ]; const patterns: Pattern[] = []; for (const indicator of causalIndicators) { const indicatorTokens = indicator.split(" "); if (this.containsSequence(tokens, indicatorTokens)) { patterns.push({ type: "causal", content: indicatorTokens, confidence: 0.8, salience: 0.7, }); } } return patterns; } private detectComparisonPatterns(tokens: string[]): Pattern[] { const comparisonWords = [ "better", "worse", "more", "less", "than", "compared to", "versus", ]; const patterns: Pattern[] = []; for (const word of comparisonWords) { if (tokens.includes(word)) { patterns.push({ type: "comparison", content: [word], confidence: 0.6, salience: 0.6, }); } } return patterns; } private detectNegationPatterns(tokens: string[]): Pattern[] { const negationWords = ["not", "no", "never", "nothing", "none", "neither"]; const patterns: Pattern[] = []; for (const word of negationWords) { if (tokens.includes(word)) { patterns.push({ type: "negation", content: [word], confidence: 0.8, salience: 0.7, }); } } return patterns; } private containsSequence(tokens: string[], sequence: string[]): boolean { for (let i = 0; i <= tokens.length - sequence.length; i++) { if (sequence.every((token, j) => tokens[i + j] === token)) { return true; } } return false; } applyHeuristics( input: string, patterns: Pattern[] ): Record<string, HeuristicResult> { const results: Record<string, HeuristicResult> = {}; for (const [name, heuristic] of this.heuristicRules) { try { const result = heuristic(input, patterns); // Ensure the result has the correct type property results[name] = { ...result, type: name, // Add the type property that tests expect }; } catch (error) { results[name] = { name: name, type: name, // Add the type property confidence: 0.1, result: `Heuristic failed: ${(error as Error).message}`, processing_time: 0, }; } } return results; } private generateIntuitiveResponse( input: string, patterns: Pattern[], heuristicResults: Record<string, HeuristicResult> ): { content: string; confidence: number; type: string } { // Combine patterns and heuristics to generate a quick response const dominantPattern = patterns.reduce( (max, p) => (p.salience > max.salience ? p : max), patterns[0] ); const heuristicValues = Object.values(heuristicResults); const dominantHeuristic = heuristicValues.length > 0 ? heuristicValues.reduce( (max, h) => (h.confidence > max.confidence ? h : max), heuristicValues[0] ) : null; let content = ""; let responseType = "general"; if (dominantPattern) { switch (dominantPattern.type) { case "question": content = this.generateQuestionResponse(input, dominantPattern); responseType = "question_response"; break; case "emotional": content = this.generateEmotionalResponse(input, dominantPattern); responseType = "emotional_response"; break; case "causal": content = this.generateCausalResponse(input, dominantPattern); responseType = "causal_response"; break; default: content = this.generateGeneralResponse(input, dominantPattern); } } else { const heuristicType = dominantHeuristic && typeof dominantHeuristic === "object" && "type" in dominantHeuristic ? dominantHeuristic.type : "general reasoning"; const heuristicReasoning = dominantHeuristic && typeof dominantHeuristic === "object" && "reasoning" in dominantHeuristic ? dominantHeuristic.reasoning : "standard approach"; // Include the input content in the response to ensure uniqueness content = `Regarding "${input}", I sense this relates to ${heuristicType}. My initial impression suggests a ${heuristicReasoning}.`; } return { content, confidence: dominantPattern?.confidence ?? 0.5, type: responseType, }; } private generateQuestionResponse(input: string, pattern: Pattern): string { const questionWord = pattern.content[0]; switch (questionWord) { case "what": return `Based on the patterns I recognize in "${input}", this appears to be asking for identification or definition.`; case "how": return `This seems to be asking about a process or method regarding "${input}". My intuition suggests looking at the steps involved.`; case "why": return `This is asking for reasons or causes about "${input}". I sense there are underlying factors to consider.`; case "when": return `This is about timing regarding "${input}". My initial sense is that temporal context is important here.`; case "where": return `This is about location or context for "${input}". The spatial or situational aspect seems relevant.`; default: return `This appears to be an information-seeking question about "${input}" that requires careful consideration.`; } } private generateEmotionalResponse(input: string, pattern: Pattern): string { return `I detect emotional content in "${input}". The tone suggests ${pattern.content[0]} feelings, which influences how I initially perceive the situation.`; } private generateCausalResponse(input: string, pattern: Pattern): string { return `I notice causal relationships in "${input}" indicated by "${pattern.content.join( " " )}". This suggests cause-and-effect thinking is needed.`; } private generateGeneralResponse(input: string, pattern: Pattern): string { // Extract key terms from input for more specific responses const inputWords = input.toLowerCase().split(/\s+/); const keyTerms = inputWords .filter( (word) => word.length > 3 && ![ "what", "how", "why", "when", "where", "which", "that", "this", "with", "from", "they", "have", "been", "will", "would", "could", "should", ].includes(word) ) .slice(0, 3); // Add some variability based on input hash const inputHash = input.split("").reduce((a, b) => { a = (a << 5) - a + b.charCodeAt(0); return a & a; }, 0); const variations = [ `I sense this relates to ${ pattern.type }. My initial analysis of "${keyTerms.join(", ")}" suggests ${ pattern.type }-based reasoning would be most effective.`, `My intuitive response recognizes a ${ pattern.type } pattern here. The key elements "${keyTerms.join( ", " )}" indicate this requires ${pattern.type} thinking.`, `This immediately strikes me as a ${ pattern.type } situation. Based on "${keyTerms.join(", ")}", I'd approach this with ${ pattern.type } reasoning.`, `I'm getting a strong ${ pattern.type } impression from this. The terms "${keyTerms.join(", ")}" suggest ${ pattern.type } analysis is needed.`, `My first instinct identifies this as ${ pattern.type }. Looking at "${keyTerms.join(", ")}", ${ pattern.type } reasoning seems most appropriate.`, ]; const selectedVariation = variations[Math.abs(inputHash) % variations.length]; return selectedVariation; } getConfidence(result: unknown): number { // If result has a confidence property, use it if ( typeof result === "object" && result !== null && "confidence" in result ) { return Math.min(Math.max(result.confidence as number, 0.1), 0.9); } // Default confidence for System 1 return 0.6; } private createReasoningPath( patterns: Pattern[], heuristicResults: Record<string, HeuristicResult>, response: { content: string; confidence: number; type: string } ): ReasoningStep[] { const steps: ReasoningStep[] = []; // Pattern recognition step if (patterns.length > 0) { steps.push({ type: ReasoningType.PATTERN_MATCH, content: `Recognized ${patterns.length} patterns: ${patterns .map((p) => p.type) .join(", ")}`, confidence: patterns.reduce((sum, p) => sum + p.confidence, 0) / patterns.length, alternatives: patterns.slice(1, 4).map((p) => ({ content: `Alternative pattern: ${p.type}`, confidence: p.confidence, reasoning: `Pattern salience: ${p.salience}`, })), }); } // Heuristic application step - use different types based on heuristic const heuristicNames = Object.keys(heuristicResults); if (heuristicNames.length > 0) { const avgConfidence = Object.values(heuristicResults).reduce( (sum: number, h) => sum + h.confidence, 0 ) / heuristicNames.length; // Use HEURISTIC type for heuristic-based reasoning steps.push({ type: ReasoningType.HEURISTIC, content: `Applied heuristics: ${heuristicNames.join(", ")}`, confidence: avgConfidence, alternatives: Object.entries(heuristicResults) .slice(0, 3) .map(([name, result]: [string, HeuristicResult]) => ({ content: `${name}: ${result.result}`, confidence: result.confidence, reasoning: `Heuristic application`, })), }); // Add specific reasoning types based on heuristics used if (heuristicNames.includes("availability")) { steps.push({ type: ReasoningType.PROBABILISTIC, content: `Availability heuristic suggests high probability based on ease of recall`, confidence: heuristicResults.availability?.confidence ?? 0.5, alternatives: [], }); } if (heuristicNames.includes("representativeness")) { steps.push({ type: ReasoningType.ANALOGICAL, content: `Representativeness suggests similarity to known prototypes`, confidence: heuristicResults.representativeness?.confidence ?? 0.5, alternatives: [], }); } } // Contextual assessment step steps.push({ type: ReasoningType.CONTEXTUAL, content: `Contextual assessment based on immediate impressions and situational cues`, confidence: 0.7, alternatives: [], }); // Intuitive conclusion step - use INDUCTIVE for intuitive leaps steps.push({ type: ReasoningType.INDUCTIVE, content: `Intuitive response: ${response.content}`, confidence: this.getConfidence(response), alternatives: [], }); return steps; } private assessEmotionalContext( _input: string, patterns: Pattern[] ): EmotionalState { const emotionalPatterns = patterns.filter((p) => p.type === "emotional"); let valence = 0; let arousal = 0.3; // Base arousal for System 1 const dominance = 0.7; // System 1 tends to be confident if (emotionalPatterns.length > 0) { // Simple emotional assessment based on detected patterns const positiveWords = [ "good", "great", "excellent", "happy", "love", "amazing", "wonderful", ]; const negativeWords = [ "bad", "terrible", "hate", "awful", "horrible", "sad", "angry", ]; for (const pattern of emotionalPatterns) { const word = pattern.content[0]; if (positiveWords.includes(word)) { valence += 0.3; arousal += 0.2; } else if (negativeWords.includes(word)) { valence -= 0.3; arousal += 0.3; } } } return { valence: Math.max(-1, Math.min(1, valence)), arousal: Math.max(0, Math.min(1, arousal)), dominance: Math.max(0, Math.min(1, dominance)), specific_emotions: new Map([ ["confidence", dominance], ["curiosity", arousal * 0.8], ["uncertainty", 1 - dominance], ]), }; } process(input: unknown): Promise<unknown> { return this.processIntuitive(input as CognitiveInput); } reset(): void { this.patternCache.clear(); this.lastActivity = 0; } getStatus(): ComponentStatus { return { name: "IntuitiveProcessor", initialized: this.initialized, active: Date.now() - this.lastActivity < 30000, // Active if used in last 30 seconds last_activity: this.lastActivity, error: "", }; } }

Latest Blog Posts

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/keyurgolani/ThoughtMcp'

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