272 lines
12 KiB
C#
Executable File
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);
|
|
}
|
|
}
|
|
}
|
|
} |