using MarketAlly.AIPlugin; using MarketAlly.AIPlugin.Context; using Microsoft.Extensions.Logging; using System.Text.Json; namespace Test.Context; /// /// Service class demonstrating the Context Management Suite plugins /// Shows practical usage patterns for maintaining conversation continuity /// public class ContextExampleService { private readonly ILogger _logger; private readonly AIPluginRegistry _registry; private readonly ContextClaudeService _claudeService; private string _currentSessionId = ""; private string _currentTopic = ""; private string _currentProject = ""; public ContextExampleService(ILogger logger, AIPluginRegistry registry, ContextClaudeService claudeService) { _logger = logger; _registry = registry; _claudeService = claudeService; RegisterContextPlugins(); } private void RegisterContextPlugins() { // Register all context management plugins _registry.RegisterPlugin(new ContextRetrievalPlugin()); _registry.RegisterPlugin(new ContextStoragePlugin()); _registry.RegisterPlugin(new ContextSearchPlugin()); _registry.RegisterPlugin(new ConversationContinuityPlugin()); _logger.LogInformation("Context management plugins registered successfully"); } /// /// Initialize a new conversation session with context retrieval /// public async Task InitializeSessionAsync(string topic, string projectPath) { try { Console.WriteLine($"[INFO] Initializing session for topic: {topic}"); Console.WriteLine($"[INFO] Project path: {projectPath}"); _currentTopic = topic; _currentProject = projectPath; var result = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary { ["action"] = "initialize", ["topic"] = topic, ["projectPath"] = projectPath }); if (result.Success) { _currentSessionId = ((dynamic)result.Data).SessionId?.ToString() ?? Guid.NewGuid().ToString(); Console.WriteLine($"[SUCCESS] Session initialized: {_currentSessionId}"); Console.WriteLine(); // Display retrieved context var initData = (dynamic)result.Data; if (initData?.RecentContext != null) { Console.WriteLine("=== Recent Context Found ==="); DisplayFormattedResult(initData.RecentContext); } if (initData?.RelatedDiscussions != null) { Console.WriteLine("=== Related Previous Discussions ==="); DisplayFormattedResult(initData.RelatedDiscussions); } } else { Console.WriteLine($"[ERROR] Failed to initialize session: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Session initialization failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during session initialization: {ex.Message}"); _logger.LogError(ex, "Session initialization error"); } } /// /// Store important decisions or information /// public async Task StoreDecisionAsync(string contextType, string summary, string content, string priority, string tags) { try { Console.WriteLine($"[INFO] Storing {contextType}: {summary}"); var result = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary { ["action"] = "store_decision", ["information"] = content, ["summary"] = summary, ["priority"] = priority, ["tags"] = tags ?? contextType, ["projectPath"] = _currentProject }); if (result.Success) { Console.WriteLine($"[SUCCESS] Stored successfully"); Console.WriteLine($"[INFO] Entry ID: {((dynamic)result.Data).EntryId}"); Console.WriteLine($"[INFO] Priority: {priority}"); Console.WriteLine($"[INFO] Tags: {tags ?? contextType}"); } else { Console.WriteLine($"[ERROR] Failed to store information: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Context storage failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during storage: {ex.Message}"); _logger.LogError(ex, "Context storage error"); } } /// /// Search through stored context /// public async Task SearchContextAsync(string query, string contextType, int maxResults) { try { Console.WriteLine($"[INFO] Searching for: {query}"); Console.WriteLine($"[INFO] Context type: {contextType}, Max results: {maxResults}"); var result = await _registry.CallFunctionAsync("ContextSearch", new Dictionary { ["query"] = query, ["contextType"] = contextType, ["maxResults"] = maxResults, ["projectPath"] = _currentProject, ["includeContent"] = true }); if (result.Success) { Console.WriteLine($"[SUCCESS] Search completed"); Console.WriteLine(); Console.WriteLine("=== Search Results ==="); DisplayFormattedResult(result.Data); } else { Console.WriteLine($"[ERROR] Search failed: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Context search failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during search: {ex.Message}"); _logger.LogError(ex, "Context search error"); } } /// /// Retrieve existing context information /// public async Task RetrieveContextAsync(string contextType, string projectPath) { try { projectPath ??= _currentProject; Console.WriteLine($"[INFO] Retrieving {contextType} context for: {projectPath}"); var result = await _registry.CallFunctionAsync("ContextRetrieval", new Dictionary { ["contextType"] = contextType, ["projectPath"] = projectPath, ["conversationLimit"] = 10, ["includeFileSummaries"] = true, ["includeGitHistory"] = true }); if (result.Success) { Console.WriteLine($"[SUCCESS] Context retrieved"); Console.WriteLine(); Console.WriteLine("=== Retrieved Context ==="); DisplayFormattedResult(result.Data); } else { Console.WriteLine($"[ERROR] Context retrieval failed: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Context retrieval failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during context retrieval: {ex.Message}"); _logger.LogError(ex, "Context retrieval error"); } } /// /// Get comprehensive project context /// public async Task GetProjectContextAsync(string projectPath) { try { Console.WriteLine($"[INFO] Getting comprehensive project context for: {projectPath}"); var result = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary { ["action"] = "get_project_context", ["projectPath"] = projectPath }); if (result.Success) { Console.WriteLine($"[SUCCESS] Project context retrieved"); Console.WriteLine(); Console.WriteLine("=== Project Context ==="); DisplayFormattedResult(result.Data); } else { Console.WriteLine($"[ERROR] Project context retrieval failed: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Project context retrieval failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during project context retrieval: {ex.Message}"); _logger.LogError(ex, "Project context retrieval error"); } } /// /// End session with summary /// public async Task SummarizeSessionAsync(string sessionSummary, string topic) { try { Console.WriteLine($"[INFO] Ending session with summary"); var result = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary { ["action"] = "summarize_session", ["sessionSummary"] = sessionSummary, ["topic"] = topic ?? _currentTopic, ["projectPath"] = _currentProject }); if (result.Success) { Console.WriteLine($"[SUCCESS] Session summarized and stored"); Console.WriteLine(); Console.WriteLine("=== Session Summary ==="); DisplayFormattedResult(result.Data); } else { Console.WriteLine($"[ERROR] Session summary failed: {result.Message}"); if (result.Error != null) { _logger.LogError(result.Error, "Session summary failed"); } } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during session summary: {ex.Message}"); _logger.LogError(ex, "Session summary error"); } } /// /// End current session (called on exit) /// public async Task EndSessionAsync(string summary) { if (!string.IsNullOrEmpty(_currentSessionId)) { await SummarizeSessionAsync(summary, _currentTopic); } } /// /// Run a comprehensive demo of all context features /// public async Task RunContextDemoAsync() { Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine("COMPREHENSIVE CONTEXT MANAGEMENT DEMO"); Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine(); // Step 1: Initialize session Console.WriteLine("Step 1: Initialize Session"); Console.WriteLine("-".PadRight(30, '-')); await InitializeSessionAsync("Context Management Demo", Directory.GetCurrentDirectory()); Console.WriteLine(); // Step 2: Store some decisions Console.WriteLine("Step 2: Store Important Decisions"); Console.WriteLine("-".PadRight(30, '-')); await StoreDecisionAsync("decision", "Database Selection", "We chose PostgreSQL over MongoDB for better ACID compliance and complex query support", "high", "database,architecture,postgresql"); await StoreDecisionAsync("insight", "Performance Optimization", "Discovered that connection pooling reduces latency by 40%", "medium", "performance,optimization,database"); await StoreDecisionAsync("codechange", "Authentication Refactor", "Refactored authentication system to use JWT tokens instead of session cookies", "high", "authentication,security,jwt,refactoring"); Console.WriteLine(); // Step 3: Search for context Console.WriteLine("Step 3: Search Stored Context"); Console.WriteLine("-".PadRight(30, '-')); await SearchContextAsync("database performance", "all", 3); Console.WriteLine(); // Step 4: Get project context Console.WriteLine("Step 4: Retrieve Project Context"); Console.WriteLine("-".PadRight(30, '-')); await GetProjectContextAsync(Directory.GetCurrentDirectory()); Console.WriteLine(); // Step 5: Summarize session Console.WriteLine("Step 5: Summarize Demo Session"); Console.WriteLine("-".PadRight(30, '-')); await SummarizeSessionAsync("Completed comprehensive demo of context management features. Tested initialization, storage, search, and project context retrieval.", "Context Management Demo"); Console.WriteLine(); Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine("DEMO COMPLETED SUCCESSFULLY"); Console.WriteLine("=".PadRight(60, '=')); } /// /// Test all context plugins individually /// public async Task TestAllContextPluginsAsync() { Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine("TESTING ALL CONTEXT PLUGINS"); Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine(); // Test ContextRetrievalPlugin Console.WriteLine("Testing ContextRetrievalPlugin..."); try { var retrievalResult = await _registry.CallFunctionAsync("ContextRetrieval", new Dictionary { ["contextType"] = "project", ["projectPath"] = Directory.GetCurrentDirectory() }); Console.WriteLine($"✅ ContextRetrievalPlugin: {(retrievalResult.Success ? "SUCCESS" : "FAILED")}"); if (!retrievalResult.Success) Console.WriteLine($" Error: {retrievalResult.Message}"); } catch (Exception ex) { Console.WriteLine($"❌ ContextRetrievalPlugin: EXCEPTION - {ex.Message}"); } // Test ContextStoragePlugin Console.WriteLine("Testing ContextStoragePlugin..."); try { var storageResult = await _registry.CallFunctionAsync("ContextStorage", new Dictionary { ["contextType"] = "test", ["content"] = "This is a test entry for plugin validation", ["summary"] = "Plugin Test Entry", ["priority"] = "low", ["tags"] = "test,validation" }); Console.WriteLine($"✅ ContextStoragePlugin: {(storageResult.Success ? "SUCCESS" : "FAILED")}"); if (!storageResult.Success) Console.WriteLine($" Error: {storageResult.Message}"); } catch (Exception ex) { Console.WriteLine($"❌ ContextStoragePlugin: EXCEPTION - {ex.Message}"); } // Test ContextSearchPlugin Console.WriteLine("Testing ContextSearchPlugin..."); try { var searchResult = await _registry.CallFunctionAsync("ContextSearch", new Dictionary { ["query"] = "test", ["maxResults"] = 1 }); Console.WriteLine($"✅ ContextSearchPlugin: {(searchResult.Success ? "SUCCESS" : "FAILED")}"); if (!searchResult.Success) Console.WriteLine($" Error: {searchResult.Message}"); } catch (Exception ex) { Console.WriteLine($"❌ ContextSearchPlugin: EXCEPTION - {ex.Message}"); } // Test ConversationContinuityPlugin Console.WriteLine("Testing ConversationContinuityPlugin..."); try { var continuityResult = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary { ["action"] = "get_project_context", ["projectPath"] = Directory.GetCurrentDirectory() }); Console.WriteLine($"✅ ConversationContinuityPlugin: {(continuityResult.Success ? "SUCCESS" : "FAILED")}"); if (!continuityResult.Success) Console.WriteLine($" Error: {continuityResult.Message}"); } catch (Exception ex) { Console.WriteLine($"❌ ConversationContinuityPlugin: EXCEPTION - {ex.Message}"); } Console.WriteLine(); Console.WriteLine("=".PadRight(60, '=')); Console.WriteLine("PLUGIN TESTING COMPLETED"); Console.WriteLine("=".PadRight(60, '=')); } /// /// List all stored context entries /// public async Task ListStoredContextAsync() { try { Console.WriteLine("[INFO] Listing all stored context entries..."); var searchResult = await _registry.CallFunctionAsync("ContextSearch", new Dictionary { ["query"] = "*", // Special query to get all entries ["contextType"] = "all", ["maxResults"] = 50, ["includeContent"] = false // Just summaries for listing }); if (searchResult.Success) { Console.WriteLine($"[SUCCESS] Found stored context entries"); Console.WriteLine(); Console.WriteLine("=== All Stored Context ==="); DisplayFormattedResult(searchResult.Data); } else { Console.WriteLine($"[ERROR] Failed to list context: {searchResult.Message}"); } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during context listing: {ex.Message}"); _logger.LogError(ex, "Context listing error"); } } /// /// Start a Claude conversation with context management /// public async Task StartClaudeConversationAsync(string topic, string projectPath) { return await _claudeService.InteractiveContextChatAsync(topic, projectPath); } /// /// Start interactive Claude chat mode with full context management /// public async Task StartInteractiveClaudeChatAsync() { Console.Write("Enter conversation topic: "); var topic = Console.ReadLine()?.Trim(); if (string.IsNullOrEmpty(topic)) topic = "General development discussion"; Console.Write("Enter project path (or press Enter for current directory): "); var projectPath = Console.ReadLine()?.Trim(); if (string.IsNullOrEmpty(projectPath)) projectPath = Directory.GetCurrentDirectory(); await _claudeService.InteractiveContextChatAsync(topic, projectPath); } /// /// Clear all stored context (for testing/cleanup) /// public async Task ClearContextAsync() { try { Console.Write("Are you sure you want to clear all stored context? (yes/no): "); var confirmation = Console.ReadLine()?.Trim().ToLower(); if (confirmation == "yes") { var contextDir = Path.Combine(Directory.GetCurrentDirectory(), ".context"); if (Directory.Exists(contextDir)) { Directory.Delete(contextDir, true); Console.WriteLine("[SUCCESS] Context storage cleared"); } else { Console.WriteLine("[INFO] No context storage found to clear"); } } else { Console.WriteLine("[INFO] Clear operation cancelled"); } } catch (Exception ex) { Console.WriteLine($"[ERROR] Exception during context clearing: {ex.Message}"); _logger.LogError(ex, "Context clearing error"); } } /// /// Display formatted result data /// private void DisplayFormattedResult(object data) { try { if (data == null) { Console.WriteLine("No data available"); return; } var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping }); // Try to make the output more readable for common structures if (data.ToString().Contains("Results") || data.ToString().Contains("Entries")) { // This is likely search results or context entries DisplaySearchResults(data); } else if (data.ToString().Contains("ProjectInfo") || data.ToString().Contains("CodebaseInfo")) { // This is project/codebase context DisplayProjectContext(data); } else { // Generic JSON display Console.WriteLine(json); } } catch (Exception ex) { Console.WriteLine($"Error displaying result: {ex.Message}"); Console.WriteLine("Raw data:"); Console.WriteLine(data?.ToString() ?? "null"); } } private void DisplaySearchResults(dynamic data) { try { if (data?.Results != null) { var results = data.Results; Console.WriteLine($"Found {results.Count} results:"); Console.WriteLine(); int index = 1; foreach (var result in results) { Console.WriteLine($"Result {index}:"); Console.WriteLine($" Type: {result.Type}"); Console.WriteLine($" Summary: {result.Summary}"); Console.WriteLine($" Priority: {result.Priority}"); Console.WriteLine($" Timestamp: {result.Timestamp}"); if (result.Tags != null && result.Tags.Count > 0) { Console.WriteLine($" Tags: {string.Join(", ", result.Tags)}"); } if (result.Relevance != null) { Console.WriteLine($" Relevance: {result.Relevance:F2}"); } if (result.Content != null && !string.IsNullOrEmpty(result.Content.ToString())) { var content = result.Content.ToString(); if (content.Length > 200) { content = content.Substring(0, 200) + "..."; } Console.WriteLine($" Content: {content}"); } Console.WriteLine(); index++; } } else { Console.WriteLine("No results found in data structure"); } } catch (Exception ex) { Console.WriteLine($"Error displaying search results: {ex.Message}"); // Fallback to JSON var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(json); } } private void DisplayProjectContext(dynamic data) { try { Console.WriteLine("Project Context Summary:"); Console.WriteLine("-".PadRight(30, '-')); if (data?.ProjectInfo != null) { var projectInfo = data.ProjectInfo; Console.WriteLine($"Project Name: {projectInfo.Name}"); Console.WriteLine($"Project Path: {projectInfo.Path}"); if (projectInfo.DirectoryStructure != null && projectInfo.DirectoryStructure.Count > 0) { Console.WriteLine($"Directories: {string.Join(", ", projectInfo.DirectoryStructure)}"); } if (projectInfo.ConfigurationFiles != null && projectInfo.ConfigurationFiles.Count > 0) { Console.WriteLine("Configuration Files Found:"); foreach (var kvp in projectInfo.ConfigurationFiles) { Console.WriteLine($" - {kvp.Key}"); } } } if (data?.CodebaseInfo != null) { var codebaseInfo = data.CodebaseInfo; Console.WriteLine($"Root Path: {codebaseInfo.RootPath}"); Console.WriteLine($"Last Analyzed: {codebaseInfo.LastAnalyzed}"); if (codebaseInfo.ProjectFiles != null) { Console.WriteLine($"Project Files: {codebaseInfo.ProjectFiles.Count}"); } if (codebaseInfo.SourceFiles != null) { Console.WriteLine($"Source Files: {codebaseInfo.SourceFiles.Count}"); // Show first few source files with summaries var filesToShow = codebaseInfo.SourceFiles.Take(5); foreach (var file in filesToShow) { Console.WriteLine($" - {file.Path}"); if (!string.IsNullOrEmpty(file.Summary?.ToString())) { Console.WriteLine($" {file.Summary}"); } } } } if (data?.RecentChanges != null) { var recentChanges = data.RecentChanges; if (recentChanges.ModifiedFiles != null && recentChanges.ModifiedFiles.Count > 0) { Console.WriteLine($"Recent File Changes: {recentChanges.ModifiedFiles.Count}"); foreach (var change in recentChanges.ModifiedFiles.Take(5)) { Console.WriteLine($" - {change.Path} ({change.ModifiedDate})"); } } if (recentChanges.GitCommits != null && recentChanges.GitCommits.Count > 0) { Console.WriteLine($"Recent Git Commits: {recentChanges.GitCommits.Count}"); foreach (var commit in recentChanges.GitCommits.Take(3)) { Console.WriteLine($" - {commit.Hash}: {commit.Message} ({commit.Author})"); } } } if (data?.RecentDecisions != null) { var decisions = data.RecentDecisions; if (decisions.Results != null && decisions.Results.Count > 0) { Console.WriteLine($"Recent Decisions: {decisions.Results.Count}"); foreach (var decision in decisions.Results.Take(3)) { Console.WriteLine($" - {decision.Summary} ({decision.Priority})"); } } } Console.WriteLine(); } catch (Exception ex) { Console.WriteLine($"Error displaying project context: {ex.Message}"); // Fallback to JSON var json = JsonSerializer.Serialize(data, new JsonSerializerOptions { WriteIndented = true }); Console.WriteLine(json); } } }