MarketAlly.AIPlugin.Extensions/Test.Context/ContextExampleService.cs

747 lines
22 KiB
C#
Executable File

using MarketAlly.AIPlugin;
using MarketAlly.AIPlugin.Context;
using Microsoft.Extensions.Logging;
using System.Text.Json;
namespace Test.Context;
/// <summary>
/// Service class demonstrating the Context Management Suite plugins
/// Shows practical usage patterns for maintaining conversation continuity
/// </summary>
public class ContextExampleService
{
private readonly ILogger<ContextExampleService> _logger;
private readonly AIPluginRegistry _registry;
private readonly ContextClaudeService _claudeService;
private string _currentSessionId = "";
private string _currentTopic = "";
private string _currentProject = "";
public ContextExampleService(ILogger<ContextExampleService> 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");
}
/// <summary>
/// Initialize a new conversation session with context retrieval
/// </summary>
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<string, object>
{
["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");
}
}
/// <summary>
/// Store important decisions or information
/// </summary>
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<string, object>
{
["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");
}
}
/// <summary>
/// Search through stored context
/// </summary>
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<string, object>
{
["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");
}
}
/// <summary>
/// Retrieve existing context information
/// </summary>
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<string, object>
{
["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");
}
}
/// <summary>
/// Get comprehensive project context
/// </summary>
public async Task GetProjectContextAsync(string projectPath)
{
try
{
Console.WriteLine($"[INFO] Getting comprehensive project context for: {projectPath}");
var result = await _registry.CallFunctionAsync("ConversationContinuity", new Dictionary<string, object>
{
["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");
}
}
/// <summary>
/// End session with summary
/// </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<string, object>
{
["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");
}
}
/// <summary>
/// End current session (called on exit)
/// </summary>
public async Task EndSessionAsync(string summary)
{
if (!string.IsNullOrEmpty(_currentSessionId))
{
await SummarizeSessionAsync(summary, _currentTopic);
}
}
/// <summary>
/// Run a comprehensive demo of all context features
/// </summary>
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, '='));
}
/// <summary>
/// Test all context plugins individually
/// </summary>
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<string, object>
{
["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<string, object>
{
["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<string, object>
{
["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<string, object>
{
["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, '='));
}
/// <summary>
/// List all stored context entries
/// </summary>
public async Task ListStoredContextAsync()
{
try
{
Console.WriteLine("[INFO] Listing all stored context entries...");
var searchResult = await _registry.CallFunctionAsync("ContextSearch", new Dictionary<string, object>
{
["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");
}
}
/// <summary>
/// Start a Claude conversation with context management
/// </summary>
public async Task<string> StartClaudeConversationAsync(string topic, string projectPath)
{
return await _claudeService.InteractiveContextChatAsync(topic, projectPath);
}
/// <summary>
/// Start interactive Claude chat mode with full context management
/// </summary>
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);
}
/// <summary>
/// Clear all stored context (for testing/cleanup)
/// </summary>
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");
}
}
/// <summary>
/// Display formatted result data
/// </summary>
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);
}
}
}