Skip to main content
Glama
synthetic-stream.ts30.6 kB
/** * Synthetic Reasoning Stream * * Implements integrative, holistic thinking with: * - Pattern recognition across disparate information * - Connection identification between concepts * - Theme extraction from complex data * - Integrative thinking and synthesis * - Holistic perspective generation (big picture view) * - Progress tracking and timeout management * - Problem-specific patterns (Requirements 4.4, 15.3) */ import { KeyTermExtractor, type KeyTerms } from "../key-term-extractor"; import type { ReasoningStream, StreamProcessor } from "../stream.types"; import { StreamStatus, StreamType, type Insight, type Problem, type StreamResult } from "../types"; /** * Synthetic stream processor * * Implements the core synthetic reasoning logic with pattern recognition, * connection discovery, theme extraction, and holistic perspective generation. * Generates problem-specific patterns using key term extraction. */ export class SyntheticStreamProcessor implements StreamProcessor { private readonly keyTermExtractor: KeyTermExtractor; constructor() { this.keyTermExtractor = new KeyTermExtractor(); } /** * Process a problem using synthetic reasoning * * @param problem - Problem to analyze * @returns Promise resolving to stream result */ async process(problem: Problem): Promise<StreamResult> { const startTime = Date.now(); const reasoning: string[] = []; const insights: Insight[] = []; // Validate problem - throw for truly invalid problems if (!problem?.id || !problem.description) { throw new Error("Invalid problem: missing required fields"); } try { // Extract key terms for problem-specific patterns (Req 4.4, 15.3) const keyTerms = this.keyTermExtractor.extract(problem.description, problem.context); const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; // Step 1: Initial pattern recognition reasoning.push( `Analyzing patterns and connections in: ${problem.description.substring(0, 100)}${problem.description.length > 100 ? "..." : ""}` ); // Steps 2-5: Core synthesis analysis this.performCoreSynthesis(problem, keyTerms, primaryTerm, reasoning, insights); // Step 6: Generate holistic perspective const holisticView = this.generateHolisticPerspective(problem, insights, keyTerms); reasoning.push(`Big picture view: ${holisticView.content}`); insights.push(holisticView); // Steps 7-8: Leverage points and temporal dynamics this.analyzeLeverageAndTemporal(problem, keyTerms, primaryTerm, reasoning, insights); // Step 9: Generate conclusion const conclusion = this.generateConclusion(problem, insights, keyTerms); reasoning.push(`Therefore, ${conclusion}`); const confidence = this.calculateConfidence(problem, insights); const processingTime = Math.max(1, Date.now() - startTime); // Return top insights const finalInsights = insights .sort((a, b) => b.importance - a.importance) .slice(0, Math.min(10, insights.length)); return { streamId: `synthetic-${problem.id}`, streamType: StreamType.SYNTHETIC, conclusion, reasoning, insights: finalInsights, confidence, processingTime, status: StreamStatus.COMPLETED, }; } catch (error) { const processingTime = Math.max(1, Date.now() - startTime); return { streamId: `synthetic-${problem.id}`, streamType: StreamType.SYNTHETIC, conclusion: "", reasoning, insights, confidence: 0, processingTime, status: StreamStatus.FAILED, error: error as Error, }; } } /** * Get the stream type this processor handles * * @returns Stream type identifier */ getStreamType(): StreamType { return StreamType.SYNTHETIC; } private performCoreSynthesis( problem: Problem, keyTerms: KeyTerms, primaryTerm: string, reasoning: string[], insights: Insight[] ): void { // Step 2: Identify patterns const patterns = this.identifyPatterns(problem, keyTerms); this.addPatternReasoning(patterns, primaryTerm, reasoning, insights); // Step 3: Map connections const connections = this.mapConnections(problem, keyTerms); this.addConnectionReasoning(connections, primaryTerm, reasoning, insights); // Step 4: Extract themes const themes = this.extractThemes(problem, keyTerms); this.addThemeReasoning(themes, primaryTerm, reasoning, insights); // Step 5: Integrate information const integratedInsights = this.integrateInformation( problem, [...patterns, ...connections, ...themes], keyTerms ); this.addIntegrationReasoning(integratedInsights, primaryTerm, reasoning, insights); } private addPatternReasoning( patterns: Insight[], primaryTerm: string, reasoning: string[], insights: Insight[] ): void { if (patterns.length > 0) { reasoning.push(`Identified ${patterns.length} recurring patterns in ${primaryTerm}`); this.addFirstMatchingReasoning(patterns, ["cause", "effect"], "Pattern analysis", reasoning); insights.push(...patterns); } } private addConnectionReasoning( connections: Insight[], primaryTerm: string, reasoning: string[], insights: Insight[] ): void { if (connections.length > 0) { reasoning.push(`Mapped ${connections.length} key connections in ${primaryTerm}`); this.addFirstMatchingReasoning( connections, ["affects", "relates", "influences"], "Connection insight", reasoning ); this.addFirstMatchingReasoning( connections, ["hidden", "subtle", "indirect"], "Hidden relationship", reasoning ); this.addFirstMatchingReasoning( connections, ["interdepend", "depend", "mutual"], "Interdependency", reasoning ); insights.push(...connections); } } private addThemeReasoning( themes: Insight[], primaryTerm: string, reasoning: string[], insights: Insight[] ): void { if (themes.length > 0) { reasoning.push(`Extracted ${themes.length} unifying themes for ${primaryTerm}`); this.addFirstMatchingReasoning( themes, ["meta", "higher level", "broader"], "Meta-level theme", reasoning ); this.addFirstMatchingReasoning( themes, ["emergent", "emerge", "whole"], "Emergent insight", reasoning ); insights.push(...themes); } } private addIntegrationReasoning( integratedInsights: Insight[], primaryTerm: string, reasoning: string[], insights: Insight[] ): void { if (integratedInsights.length > 0) { reasoning.push( `Synthesized ${integratedInsights.length} integrative insights for ${primaryTerm}` ); this.addFirstMatchingReasoning( integratedInsights, ["paradox", "tension", "both"], "Integration", reasoning ); insights.push(...integratedInsights); } } private addFirstMatchingReasoning( items: Insight[], keywords: string[], prefix: string, reasoning: string[] ): void { for (const item of items) { const content = item.content.toLowerCase(); if (keywords.some((kw) => content.includes(kw))) { reasoning.push(`${prefix}: ${item.content.substring(0, 100)}`); return; } } } private analyzeLeverageAndTemporal( problem: Problem, keyTerms: KeyTerms, primaryTerm: string, reasoning: string[], insights: Insight[] ): void { // Step 7: Identify leverage points const leveragePoints = this.identifyLeveragePoints(problem, insights, keyTerms); if (leveragePoints.length > 0) { reasoning.push( `Identified ${leveragePoints.length} critical leverage points for ${primaryTerm}` ); insights.push(...leveragePoints); } // Step 8: Consider temporal dynamics if (problem.context && problem.context.length > 0) { reasoning.push(`Considering how ${primaryTerm} evolves over time`); const temporalInsights = this.considerTemporalDynamics(problem, keyTerms); insights.push(...temporalInsights); } } /** * Identify patterns across disparate information with term reference tracking * * @param problem - Problem to analyze * @param keyTerms - Extracted key terms for problem-specific patterns * @returns Array of pattern insights with referenced terms tracked */ private identifyPatterns(problem: Problem, keyTerms: KeyTerms): Insight[] { const patterns: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); const context = problem.context ?? ""; this.checkSystemicPatterns(context, primaryTerm, domainTerms, keyTerms, patterns); this.checkRecurringPatterns(problem, primaryTerm, domainTerms, keyTerms, patterns); this.addCauseEffectPattern(primaryTerm, domainTerms, keyTerms, patterns); this.checkFeedbackLoops(context, primaryTerm, domainTerms, keyTerms, patterns); return patterns; } private checkSystemicPatterns( context: string, primaryTerm: string, domainTerms: string[], keyTerms: KeyTerms, patterns: Insight[] ): void { const hasSystemicIndicators = context.includes("multiple") || context.includes("various") || context.includes("several"); if (hasSystemicIndicators) { const content = `Pattern in ${primaryTerm}: Multiple interconnected ${domainTerms[0] ?? "factors"} creating systemic complexity`; patterns.push(this.createPatternInsight(content, 0.75, 0.8, keyTerms)); } } private checkRecurringPatterns( problem: Problem, primaryTerm: string, domainTerms: string[], keyTerms: KeyTerms, patterns: Insight[] ): void { const context = problem.context ?? ""; const description = problem.description ?? ""; const hasRecurringIndicators = description.includes("recurring") || description.includes("repeated") || context.includes("again"); if (hasRecurringIndicators) { const content = `Recurring pattern in ${primaryTerm}: Similar ${domainTerms[0] ?? "issues"} manifesting across different areas`; patterns.push(this.createPatternInsight(content, 0.7, 0.75, keyTerms)); } } private addCauseEffectPattern( primaryTerm: string, domainTerms: string[], keyTerms: KeyTerms, patterns: Insight[] ): void { const causeEffectContent = `Cause-effect pattern in ${primaryTerm}: ${domainTerms[0] ?? "Issues"} lead to ${domainTerms[1] ?? "consequences"} with cascading effects`; patterns.push(this.createPatternInsight(causeEffectContent, 0.8, 0.85, keyTerms)); } private checkFeedbackLoops( context: string, primaryTerm: string, domainTerms: string[], keyTerms: KeyTerms, patterns: Insight[] ): void { const hasFeedbackIndicators = context.includes("cycle") || context.includes("loop") || context.includes("reinforc"); if (hasFeedbackIndicators) { const content = `Feedback loop in ${primaryTerm}: Self-reinforcing ${domainTerms[0] ?? "dynamics"} amplifying effects over time`; patterns.push(this.createPatternInsight(content, 0.75, 0.9, keyTerms)); } } private createPatternInsight( content: string, confidence: number, importance: number, keyTerms: KeyTerms ): Insight { return { content, source: StreamType.SYNTHETIC, confidence, importance, referencedTerms: this.keyTermExtractor.findReferencedTerms(content, keyTerms), }; } /** * Map connections between concepts with term reference tracking * * @param problem - Problem to analyze * @param keyTerms - Extracted key terms for problem-specific connections * @returns Array of connection insights with referenced terms tracked */ private mapConnections(problem: Problem, keyTerms: KeyTerms): Insight[] { const connections: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); const terms = keyTerms.terms.slice(0, 3); // Identify direct connections and relationships const directContent = `Connection mapping in ${primaryTerm}: ${terms.join(", ")} affects overall ${domainTerms[0] ?? "dynamics"}`; connections.push({ content: directContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.75, referencedTerms: this.keyTermExtractor.findReferencedTerms(directContent, keyTerms), }); // Look for interdependencies with specific terms const interdepContent = `Interdependencies in ${primaryTerm}: ${domainTerms[0] ?? "Elements"} and ${domainTerms[1] ?? "components"} mutually depend on each other`; connections.push({ content: interdepContent, source: StreamType.SYNTHETIC, confidence: 0.75, importance: 0.8, referencedTerms: this.keyTermExtractor.findReferencedTerms(interdepContent, keyTerms), }); // Identify hidden connections with specific terms const hiddenContent = `Hidden connections in ${primaryTerm}: Subtle indirect relationships linking ${terms.slice(0, 2).join(" and ") ?? "separate issues"}`; connections.push({ content: hiddenContent, source: StreamType.SYNTHETIC, confidence: 0.65, importance: 0.85, referencedTerms: this.keyTermExtractor.findReferencedTerms(hiddenContent, keyTerms), }); // Map influence networks if (problem.constraints && problem.constraints.length > 1) { const influenceContent = `Influence network in ${primaryTerm}: Constraints (${problem.constraints.slice(0, 2).join(", ")}) creating interconnected limitations`; connections.push({ content: influenceContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.75, referencedTerms: this.keyTermExtractor.findReferencedTerms(influenceContent, keyTerms), }); } return connections; } /** * Extract overarching themes with term reference tracking * * @param problem - Problem to analyze * @param keyTerms - Extracted key terms for problem-specific themes * @returns Array of theme insights with referenced terms tracked */ private extractThemes(_problem: Problem, keyTerms: KeyTerms): Insight[] { const themes: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); // Extract unifying themes with specific terms const unifyingContent = `Unifying theme for ${primaryTerm}: Balancing ${domainTerms[0] ?? "competing priorities"} and ${domainTerms[1] ?? "managing complexity"}`; themes.push({ content: unifyingContent, source: StreamType.SYNTHETIC, confidence: 0.75, importance: 0.85, referencedTerms: this.keyTermExtractor.findReferencedTerms(unifyingContent, keyTerms), }); // Meta-level insights with specific terms const metaContent = `Meta-level insight for ${primaryTerm}: Reflects broader ${domainTerms[0] ?? "systemic"} patterns requiring strategic thinking`; themes.push({ content: metaContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.8, referencedTerms: this.keyTermExtractor.findReferencedTerms(metaContent, keyTerms), }); // Emergent properties with specific terms const emergentContent = `Emergent property of ${primaryTerm}: ${domainTerms[0] ?? "System"} behaviors emerge from ${domainTerms[1] ?? "component"} interactions`; themes.push({ content: emergentContent, source: StreamType.SYNTHETIC, confidence: 0.75, importance: 0.9, referencedTerms: this.keyTermExtractor.findReferencedTerms(emergentContent, keyTerms), }); return themes; } /** * Integrate information from multiple sources with term reference tracking * * @param problem - Problem being analyzed * @param existingInsights - Insights gathered so far * @param keyTerms - Extracted key terms for problem-specific integration * @returns Array of integrated insights with referenced terms tracked */ private integrateInformation( problem: Problem, existingInsights: Insight[], keyTerms: KeyTerms ): Insight[] { const integrated: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); // Synthesize multiple perspectives if (existingInsights.length >= 3) { const synthesisContent = `Synthesis for ${primaryTerm}: Integrating ${domainTerms[0] ?? "patterns"}, ${domainTerms[1] ?? "connections"}, and themes reveals coherent view`; integrated.push({ content: synthesisContent, source: StreamType.SYNTHETIC, confidence: 0.8, importance: 0.85, referencedTerms: this.keyTermExtractor.findReferencedTerms(synthesisContent, keyTerms), }); } // Bridge different domains if (problem.context && problem.context.length > 100) { const bridgeContent = `Cross-domain integration for ${primaryTerm}: Bridging ${domainTerms.join(" and ") || "different areas"} creates comprehensive understanding`; integrated.push({ content: bridgeContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.75, referencedTerms: this.keyTermExtractor.findReferencedTerms(bridgeContent, keyTerms), }); } // Resolve contradictions with specific terms const paradoxContent = `Paradox resolution for ${primaryTerm}: Tensions between ${domainTerms[0] ?? "competing demands"} can be balanced through systems-level thinking`; integrated.push({ content: paradoxContent, source: StreamType.SYNTHETIC, confidence: 0.65, importance: 0.8, referencedTerms: this.keyTermExtractor.findReferencedTerms(paradoxContent, keyTerms), }); return integrated; } /** * Generate holistic perspective with term reference tracking * * @param problem - Problem being analyzed * @param insights - All gathered insights * @param keyTerms - Extracted key terms for problem-specific perspective * @returns Holistic perspective insight with referenced terms tracked */ private generateHolisticPerspective( problem: Problem, insights: Insight[], keyTerms: KeyTerms ): Insight { const context = problem.context ?? ""; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); const terms = keyTerms.terms.slice(0, 3); let content = `The big picture of ${primaryTerm} reveals `; // Assess complexity if (insights.length >= 5 || context.length > 150) { content += `a complex adaptive ${domainTerms[0] ?? "system"} where `; } else { content += `an interconnected ${domainTerms[0] ?? "situation"} where `; } // Add systemic view with specific terms content += `${terms.join(", ")} interact dynamically, `; // Consider boundaries if (problem.constraints && problem.constraints.length > 0) { content += `operating within ${problem.constraints[0]}, `; } // Add temporal dimension with specific terms content += `evolving through ${domainTerms[1] ?? "feedback"} mechanisms`; return { content, source: StreamType.SYNTHETIC, confidence: 0.8, importance: 0.9, referencedTerms: this.keyTermExtractor.findReferencedTerms(content, keyTerms), }; } /** * Identify leverage points for intervention with term reference tracking * * @param problem - Problem being analyzed * @param insights - All gathered insights * @param keyTerms - Extracted key terms for problem-specific leverage points * @returns Array of leverage point insights with referenced terms tracked */ private identifyLeveragePoints( problem: Problem, insights: Insight[], keyTerms: KeyTerms ): Insight[] { const leveragePoints: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerms = keyTerms.domainTerms.slice(0, 2); // Find high-impact intervention points const highImportanceInsights = insights.filter((i) => i.importance > 0.8); if (highImportanceInsights.length > 0) { const criticalContent = `Critical leverage point for ${primaryTerm}: Focus on ${highImportanceInsights.length} key ${domainTerms[0] ?? "areas"} with highest impact`; leveragePoints.push({ content: criticalContent, source: StreamType.SYNTHETIC, confidence: 0.75, importance: 0.85, referencedTerms: this.keyTermExtractor.findReferencedTerms(criticalContent, keyTerms), }); } // Consider goals with specific terms if (problem.goals && problem.goals.length > 0) { const strategicContent = `Strategic leverage for ${primaryTerm}: Align ${domainTerms[0] ?? "interventions"} with ${problem.goals[0]} to maximize effectiveness`; leveragePoints.push({ content: strategicContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.8, referencedTerms: this.keyTermExtractor.findReferencedTerms(strategicContent, keyTerms), }); } return leveragePoints; } /** * Consider temporal dynamics with term reference tracking * * @param problem - Problem being analyzed * @param keyTerms - Extracted key terms for problem-specific temporal insights * @returns Array of temporal insights with referenced terms tracked */ private considerTemporalDynamics(problem: Problem, keyTerms: KeyTerms): Insight[] { const temporal: Insight[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the system"; const domainTerm = keyTerms.domainTerms[0] ?? ""; // Time-based evolution with specific terms const evolutionContent = `Temporal dynamics of ${primaryTerm}: ${domainTerm || "The system"} changes over time, requiring adaptive ${domainTerm || "strategies"}`; temporal.push({ content: evolutionContent, source: StreamType.SYNTHETIC, confidence: 0.7, importance: 0.75, referencedTerms: this.keyTermExtractor.findReferencedTerms(evolutionContent, keyTerms), }); // Consider urgency with specific terms if (problem.urgency === "high") { const urgencyContent = `Time pressure on ${primaryTerm}: Rapid ${domainTerm || "evolution"} demands quick yet thoughtful intervention`; temporal.push({ content: urgencyContent, source: StreamType.SYNTHETIC, confidence: 0.75, importance: 0.8, referencedTerms: this.keyTermExtractor.findReferencedTerms(urgencyContent, keyTerms), }); } return temporal; } /** * Generate conclusion from synthetic analysis with validated term references * * @param problem - Original problem * @param insights - Generated insights * @param keyTerms - Extracted key terms for problem-specific conclusion * @returns Conclusion statement with guaranteed key term reference */ private generateConclusion(problem: Problem, insights: Insight[], keyTerms: KeyTerms): string { const parts: string[] = []; const primaryTerm = keyTerms.primarySubject ?? keyTerms.terms[0] ?? "the situation"; const domainTerms = keyTerms.domainTerms.slice(0, 2); // Overall synthesis with specific terms parts.push(`${primaryTerm} represents`); // Assess complexity if (insights.length >= 7) { parts.push(`a highly complex ${domainTerms[0] ?? "system"}`); } else if (insights.length >= 4) { parts.push(`a moderately complex ${domainTerms[0] ?? "system"}`); } else { parts.push(`an interconnected ${domainTerms[0] ?? "system"}`); } // Key themes with specific terms const highImportanceCount = insights.filter((i) => i.importance > 0.8).length; if (highImportanceCount > 0) { parts.push( `with ${highImportanceCount} critical ${domainTerms[1] ?? "leverage point"}${highImportanceCount > 1 ? "s" : ""}` ); } // Strategic direction with specific terms if (problem.goals && problem.goals.length > 0) { parts.push( `requiring strategic ${domainTerms[0] ?? "systems-level"} thinking to ${problem.goals[0]}` ); } else { parts.push( `requiring holistic understanding of ${domainTerms.join(" and ") || "all components"}` ); } // Validate and ensure conclusion contains at least one key term const conclusion = parts.join(" "); return this.keyTermExtractor.ensureTermReference(conclusion, keyTerms); } /** * Calculate confidence score * * @param problem - Problem being analyzed * @param insights - Generated insights * @returns Confidence score (0-1) */ private calculateConfidence(problem: Problem, insights: Insight[]): number { let confidence = 0.75; // Synthetic stream is generally confident in synthesis // Boost confidence if we have many insights if (insights.length >= 7) { confidence += 0.1; } // Boost confidence if we have high importance insights const highImportanceCount = insights.filter((i) => i.importance > 0.8).length; if (highImportanceCount >= 3) { confidence += 0.1; } // Reduce confidence if context is limited or missing if (!problem.context || problem.context.trim().length === 0) { confidence -= 0.35; // Larger penalty for missing/empty context } else if (problem.context.length < 20) { confidence -= 0.25; // Penalty for very limited context } else if (problem.context.length < 50) { confidence -= 0.15; } // Reduce confidence if problem is very constrained if (problem.constraints && problem.constraints.length > 3) { confidence -= 0.1; } return Math.max(0.1, Math.min(1.0, confidence)); } } /** * Synthetic Reasoning Stream * * Implements a reasoning stream that performs integrative, holistic thinking * with progress tracking, timeout management, and cancellation support. */ export class SyntheticReasoningStream implements ReasoningStream { public readonly id: string; public readonly type: StreamType; public readonly processor: StreamProcessor; public readonly timeout: number; private progress: number = 0; private cancelled: boolean = false; private processing: boolean = false; /** * Create synthetic reasoning stream * * @param timeout - Timeout in milliseconds (default: 10000ms) */ constructor(timeout: number = 10000) { this.id = `synthetic-stream-${Date.now()}`; this.type = StreamType.SYNTHETIC; this.processor = new SyntheticStreamProcessor(); this.timeout = timeout; } /** * Process a problem using synthetic reasoning * * @param problem - Problem to analyze * @returns Promise resolving to stream result */ async process(problem: Problem): Promise<StreamResult> { if (this.processing) { throw new Error("Stream is already processing"); } this.processing = true; this.progress = 0; this.cancelled = false; const startTime = Date.now(); try { // Create timeout promise const timeoutPromise = new Promise<StreamResult>((resolve) => { setTimeout(() => { if (!this.cancelled) { resolve({ streamId: this.id, streamType: this.type, conclusion: "Synthesis incomplete due to timeout", reasoning: ["Processing exceeded time limit"], insights: [], confidence: 0.3, processingTime: this.timeout, status: StreamStatus.TIMEOUT, }); } }, this.timeout); }); // Create processing promise with progress tracking const processingPromise = this.processWithProgress(problem); // Race between processing and timeout let result = await Promise.race([processingPromise, timeoutPromise]); // Check if cancelled after processing completes (handles late cancellation) if (this.cancelled && result.status !== StreamStatus.CANCELLED) { result = { streamId: this.id, streamType: this.type, conclusion: "", reasoning: result.reasoning || [], insights: result.insights || [], confidence: 0, processingTime: Date.now() - startTime, status: StreamStatus.CANCELLED, }; } if (result.status === StreamStatus.COMPLETED) { this.progress = 1.0; } return result; } finally { this.processing = false; } } /** * Process with progress tracking * * @param problem - Problem to analyze * @returns Promise resolving to stream result */ private async processWithProgress(problem: Problem): Promise<StreamResult> { // Simulate progress updates during processing const progressInterval = setInterval(() => { if (!this.cancelled && this.progress < 0.9) { this.progress += 0.1; } }, this.timeout / 10); try { const result = await this.processor.process(problem); clearInterval(progressInterval); // Check if cancelled after processing if (this.cancelled) { return { streamId: this.id, streamType: this.type, conclusion: "", reasoning: result.reasoning ?? [], insights: result.insights ?? [], confidence: 0, processingTime: result.processingTime, status: StreamStatus.CANCELLED, }; } this.progress = 1.0; return result; } catch (error) { clearInterval(progressInterval); throw error; } } /** * Get current processing progress * * @returns Progress value between 0 and 1 */ getProgress(): number { return this.progress; } /** * Cancel stream processing */ cancel(): void { this.cancelled = true; this.progress = 0; } }

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