MarketAlly.AIPlugin.Extensions/MarketAlly.AIPlugin.Learning/Services/UnifiedContextService.cs

272 lines
12 KiB
C#
Executable File

using MarketAlly.AIPlugin.Learning.Configuration;
using MarketAlly.AIPlugin.Learning.Exceptions;
using MarketAlly.AIPlugin.Learning.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Concurrent;
using System.Text.Json;
namespace MarketAlly.AIPlugin.Learning.Services
{
/// <summary>
/// Simplified unified service for learning context operations.
/// Method Index and RefactorIQ operations have been moved to direct RefactorIQ integration in Aizia.
/// </summary>
public interface IUnifiedContextService
{
Task<ComprehensiveContext> PrepareFullContextAsync(string query, string? filePath = null, int maxTokens = 8000);
Task<LearningSessionContext> InitializeLearningSessionAsync(string projectPath, string topic);
Task StoreLearningInsightAsync(string insight, string category, string? filePath = null, Dictionary<string, object>? metadata = null);
Task<List<HistoricalInsight>> FindSimilarPastIssuesAsync(string currentIssue, string? projectPath = null);
Task<List<PreviousDecision>> GetRelatedDecisionsAsync(string symbolName, string? operationType = null);
Task StoreRefactoringDecisionAsync(string decision, string reasoning, string filePath, bool successful);
Task<SessionSummary> FinalizeLearningSessionAsync(string sessionSummary, Dictionary<string, object> metrics);
}
public class UnifiedContextService : IUnifiedContextService
{
private readonly ILLMContextService? _llmContextService;
private readonly AIPluginRegistry _contextRegistry;
private readonly AIConfiguration _config;
private readonly ILogger<UnifiedContextService> _logger;
private readonly string _correlationId;
private readonly ConcurrentDictionary<string, ComprehensiveContext> _sessionCache;
private string? _currentProjectPath;
private string? _currentSessionId;
public UnifiedContextService(
IOptions<LearningConfiguration> options,
ILogger<UnifiedContextService> logger)
{
_config = options.Value.AI;
_logger = logger;
_correlationId = Guid.NewGuid().ToString("N")[..8];
_sessionCache = new ConcurrentDictionary<string, ComprehensiveContext>();
// Initialize Context project plugins
_contextRegistry = new AIPluginRegistry(CreateNullLogger());
RegisterContextPlugins();
_logger.LogInformation("UnifiedContextService initialized [CorrelationId: {CorrelationId}]", _correlationId);
}
private static ILogger<AIPluginRegistry> CreateNullLogger()
{
using var loggerFactory = LoggerFactory.Create(builder => { });
return loggerFactory.CreateLogger<AIPluginRegistry>();
}
private void RegisterContextPlugins()
{
try
{
_logger.LogDebug("Context plugins registration placeholder [CorrelationId: {CorrelationId}]", _correlationId);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to register context plugins [CorrelationId: {CorrelationId}]", _correlationId);
}
}
public async Task<ComprehensiveContext> PrepareFullContextAsync(string query, string? filePath = null, int maxTokens = 8000)
{
try
{
_logger.LogInformation("Preparing comprehensive context for query: {Query} [CorrelationId: {CorrelationId}]",
query, _correlationId);
var context = new ComprehensiveContext
{
Query = query,
FilePath = filePath,
MaxTokens = maxTokens,
CorrelationId = _correlationId,
ProjectPath = _currentProjectPath,
SessionId = _currentSessionId,
Timestamp = DateTime.UtcNow,
RelevantContext = new Dictionary<string, object>()
};
// Cache the context for session continuity
if (!string.IsNullOrEmpty(_currentSessionId))
{
_sessionCache.TryAdd(_currentSessionId, context);
}
return context;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to prepare full context [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to prepare context: {ex.Message}", ex);
}
}
public async Task<LearningSessionContext> InitializeLearningSessionAsync(string projectPath, string topic)
{
try
{
_currentProjectPath = projectPath;
_currentSessionId = Guid.NewGuid().ToString("N");
_logger.LogInformation("Initializing learning session for project: {ProjectPath}, Topic: {Topic} [SessionId: {SessionId}]",
projectPath, topic, _currentSessionId);
return new LearningSessionContext
{
SessionId = _currentSessionId,
ProjectPath = projectPath,
Topic = topic,
StartTime = DateTime.UtcNow,
Insights = new List<string>(),
Decisions = new List<string>(),
Metadata = new Dictionary<string, object>
{
["correlationId"] = _correlationId,
["topic"] = topic
}
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to initialize learning session [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to initialize session: {ex.Message}", ex);
}
}
public async Task StoreLearningInsightAsync(string insight, string category, string? filePath = null, Dictionary<string, object>? metadata = null)
{
try
{
_logger.LogInformation("Storing learning insight in category: {Category} [SessionId: {SessionId}]",
category, _currentSessionId);
var insightData = new
{
Insight = insight,
Category = category,
FilePath = filePath,
Metadata = metadata ?? new Dictionary<string, object>(),
Timestamp = DateTime.UtcNow,
SessionId = _currentSessionId,
CorrelationId = _correlationId
};
// In a real implementation, this would persist to a database
_logger.LogDebug("Insight stored: {InsightData}", JsonSerializer.Serialize(insightData));
await Task.CompletedTask;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to store learning insight [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to store insight: {ex.Message}", ex);
}
}
public async Task<List<HistoricalInsight>> FindSimilarPastIssuesAsync(string currentIssue, string? projectPath = null)
{
try
{
_logger.LogInformation("Finding similar past issues for: {Issue} [CorrelationId: {CorrelationId}]",
currentIssue, _correlationId);
// Simplified implementation - in production, this would query a database
var insights = new List<HistoricalInsight>();
return await Task.FromResult(insights);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to find similar past issues [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to find similar issues: {ex.Message}", ex);
}
}
public async Task<List<PreviousDecision>> GetRelatedDecisionsAsync(string symbolName, string? operationType = null)
{
try
{
_logger.LogInformation("Getting related decisions for symbol: {Symbol}, Operation: {Operation} [CorrelationId: {CorrelationId}]",
symbolName, operationType, _correlationId);
// Simplified implementation - in production, this would query a database
var decisions = new List<PreviousDecision>();
return await Task.FromResult(decisions);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to get related decisions [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to get decisions: {ex.Message}", ex);
}
}
public async Task StoreRefactoringDecisionAsync(string decision, string reasoning, string filePath, bool successful)
{
try
{
_logger.LogInformation("Storing refactoring decision for file: {FilePath}, Success: {Success} [SessionId: {SessionId}]",
filePath, successful, _currentSessionId);
var decisionData = new
{
Decision = decision,
Reasoning = reasoning,
FilePath = filePath,
Successful = successful,
Timestamp = DateTime.UtcNow,
SessionId = _currentSessionId,
CorrelationId = _correlationId
};
// In a real implementation, this would persist to a database
_logger.LogDebug("Decision stored: {DecisionData}", JsonSerializer.Serialize(decisionData));
await Task.CompletedTask;
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to store refactoring decision [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to store decision: {ex.Message}", ex);
}
}
public async Task<SessionSummary> FinalizeLearningSessionAsync(string sessionSummary, Dictionary<string, object> metrics)
{
try
{
_logger.LogInformation("Finalizing learning session [SessionId: {SessionId}]", _currentSessionId);
var summary = new SessionSummary
{
SessionId = _currentSessionId ?? "unknown",
ProjectPath = _currentProjectPath ?? "unknown",
Summary = sessionSummary,
Metrics = metrics,
StartTime = DateTime.UtcNow.AddHours(-1), // Placeholder
EndTime = DateTime.UtcNow,
TotalInsights = metrics.GetValueOrDefault("insights", 0),
TotalDecisions = metrics.GetValueOrDefault("decisions", 0),
Success = true
};
// Clear session cache
if (!string.IsNullOrEmpty(_currentSessionId))
{
_sessionCache.TryRemove(_currentSessionId, out _);
}
_currentSessionId = null;
_currentProjectPath = null;
return await Task.FromResult(summary);
}
catch (Exception ex)
{
_logger.LogError(ex, "Failed to finalize learning session [CorrelationId: {CorrelationId}]", _correlationId);
throw new LearningServiceException($"Failed to finalize session: {ex.Message}", ex);
}
}
}
}