431 lines
12 KiB
C#
Executable File
431 lines
12 KiB
C#
Executable File
using MarketAlly.AIPlugin;
|
|
using MarketAlly.AIPlugin.Models;
|
|
using MarketAlly.AIPlugin.Refactoring.Plugins;
|
|
using Microsoft.Extensions.Logging;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MarketAlly.AIPlugin.Refactoring.Services;
|
|
|
|
/// <summary>
|
|
/// AI-powered service for enhancing README generation with intelligent content
|
|
/// Integrates with the AIPlugin framework to leverage Claude for content improvement
|
|
/// </summary>
|
|
public class AIReadmeEnhancementService
|
|
{
|
|
private readonly AIPluginRegistry _pluginRegistry;
|
|
private readonly ILogger<AIReadmeEnhancementService> _logger;
|
|
|
|
public AIReadmeEnhancementService(AIPluginRegistry pluginRegistry, ILogger<AIReadmeEnhancementService> logger = null)
|
|
{
|
|
_pluginRegistry = pluginRegistry;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enhances a basic README analysis with AI-powered content generation
|
|
/// </summary>
|
|
public async Task<EnhancedReadmeResult> EnhanceReadmeWithAIAsync(
|
|
ProjectAnalysisResult analysis,
|
|
List<ChatMessage> conversationHistory = null)
|
|
{
|
|
try
|
|
{
|
|
var result = new EnhancedReadmeResult
|
|
{
|
|
OriginalAnalysis = analysis,
|
|
EnhancedSections = new Dictionary<string, string>()
|
|
};
|
|
|
|
// Prepare structured project data for AI analysis
|
|
var projectSummary = PrepareProjectSummaryForAI(analysis);
|
|
|
|
// Create AI conversation for README enhancement
|
|
var messages = conversationHistory ?? new List<ChatMessage>();
|
|
|
|
if (!messages.Any())
|
|
{
|
|
messages.Add(ChatMessage.System(@"You are a senior technical writer and software architect. Your job is to analyze project structures and generate outstanding README documentation.
|
|
|
|
You have access to tools that can:
|
|
- Read project files to understand code structure
|
|
- Analyze code quality and architecture
|
|
- Generate comprehensive documentation
|
|
|
|
Focus on creating README content that is:
|
|
- Clear and professional
|
|
- Technically accurate
|
|
- Includes practical examples
|
|
- Explains the value proposition
|
|
- Provides excellent setup instructions
|
|
|
|
Always structure your analysis before writing content."));
|
|
}
|
|
|
|
// Phase 1: Analyze project architecture and purpose
|
|
messages.Add(ChatMessage.User($@"I need you to analyze this project and create an outstanding README.md file.
|
|
|
|
Project Summary:
|
|
{projectSummary}
|
|
|
|
Please start by using the ReadFile tool to examine the key files, then provide a comprehensive README that includes:
|
|
|
|
1. Project overview with clear value proposition
|
|
2. Professional installation/setup instructions
|
|
3. Practical usage examples with real code
|
|
4. API documentation for public interfaces
|
|
5. Architecture overview if applicable
|
|
6. Contributing guidelines
|
|
|
|
Key files to analyze: {string.Join(", ", analysis.KeyFiles.Take(5).Select(f => f.FilePath))}
|
|
|
|
Start by reading and analyzing the most important files to understand the project's purpose and architecture."));
|
|
|
|
// Use existing plugin system to call AI
|
|
var enhancedContent = await CallAIForReadmeEnhancement(messages);
|
|
|
|
result.EnhancedContent = enhancedContent;
|
|
result.Success = true;
|
|
result.EnhancementApplied = true;
|
|
|
|
return result;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to enhance README with AI");
|
|
return new EnhancedReadmeResult
|
|
{
|
|
Success = false,
|
|
Error = ex.Message,
|
|
OriginalAnalysis = analysis
|
|
};
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates intelligent project descriptions using AI analysis
|
|
/// </summary>
|
|
public async Task<string> GenerateIntelligentDescriptionAsync(ProjectAnalysisResult analysis)
|
|
{
|
|
try
|
|
{
|
|
var projectData = PrepareProjectSummaryForAI(analysis);
|
|
|
|
var messages = new List<ChatMessage>
|
|
{
|
|
ChatMessage.System("You are a technical writer specializing in project descriptions. Create compelling, accurate descriptions based on code analysis."),
|
|
ChatMessage.User($@"Based on this project analysis, write a clear, professional description that explains what this project does and its key benefits:
|
|
|
|
{projectData}
|
|
|
|
Keep the description:
|
|
- 2-3 sentences maximum
|
|
- Focused on value and purpose
|
|
- Professional but accessible
|
|
- Technically accurate")
|
|
};
|
|
|
|
var description = await CallAIForReadmeEnhancement(messages);
|
|
return description ?? GenerateFallbackDescription(analysis);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to generate AI description, using fallback");
|
|
return GenerateFallbackDescription(analysis);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Generates intelligent usage examples based on API analysis
|
|
/// </summary>
|
|
public async Task<string> GenerateIntelligentExamplesAsync(ProjectAnalysisResult analysis)
|
|
{
|
|
if (!analysis.PublicApis.Any())
|
|
return GenerateFallbackExamples(analysis);
|
|
|
|
try
|
|
{
|
|
var apiSummary = PrepareApiSummaryForAI(analysis);
|
|
|
|
var messages = new List<ChatMessage>
|
|
{
|
|
ChatMessage.System("You are a technical writer creating code examples. Generate practical, working examples that developers can actually use."),
|
|
ChatMessage.User($@"Create practical usage examples for this project based on its public API:
|
|
|
|
{apiSummary}
|
|
|
|
Generate examples that:
|
|
- Show real-world usage scenarios
|
|
- Are copy-pasteable and working
|
|
- Progress from basic to advanced usage
|
|
- Include error handling where appropriate
|
|
- Use meaningful variable names
|
|
|
|
Format as markdown code blocks with explanatory text.")
|
|
};
|
|
|
|
var examples = await CallAIForReadmeEnhancement(messages);
|
|
return examples ?? GenerateFallbackExamples(analysis);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to generate AI examples, using fallback");
|
|
return GenerateFallbackExamples(analysis);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Enhances API documentation with intelligent descriptions
|
|
/// </summary>
|
|
public async Task<string> EnhanceApiDocumentationAsync(ProjectAnalysisResult analysis)
|
|
{
|
|
if (!analysis.PublicApis.Any())
|
|
return "";
|
|
|
|
try
|
|
{
|
|
var apiDetails = PrepareDetailedApiSummaryForAI(analysis);
|
|
|
|
var messages = new List<ChatMessage>
|
|
{
|
|
ChatMessage.System("You are a technical writer specializing in API documentation. Create clear, comprehensive API docs that developers love to use."),
|
|
ChatMessage.User($@"Create professional API documentation for these public methods:
|
|
|
|
{apiDetails}
|
|
|
|
For each method, provide:
|
|
- Clear description of purpose
|
|
- Parameter explanations
|
|
- Return value details
|
|
- Usage examples
|
|
- Any important notes or warnings
|
|
|
|
Format as clean markdown with proper code formatting.")
|
|
};
|
|
|
|
var apiDocs = await CallAIForReadmeEnhancement(messages);
|
|
return apiDocs ?? GenerateFallbackApiDocs(analysis);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to enhance API docs with AI, using fallback");
|
|
return GenerateFallbackApiDocs(analysis);
|
|
}
|
|
}
|
|
|
|
private string PrepareProjectSummaryForAI(ProjectAnalysisResult analysis)
|
|
{
|
|
var summary = $@"Project Name: {analysis.ProjectName}
|
|
Project Type: {analysis.DetectedProjectType}
|
|
Target Framework: {analysis.TargetFramework}
|
|
Files Analyzed: {analysis.FilesAnalyzed}
|
|
|
|
Key Components:
|
|
{string.Join("\n", analysis.KeyFiles.Take(10).Select(f => $"- {f.FileName}: {f.Classes.Count} classes, {f.Interfaces.Count} interfaces, {f.LineCount} lines"))}
|
|
|
|
Public APIs: {analysis.PublicApis.Count} methods
|
|
Dependencies: {string.Join(", ", analysis.Dependencies.Take(10))}
|
|
|
|
Project Features:
|
|
- Has Tests: {analysis.HasTests}
|
|
- Has Documentation: {analysis.HasDocumentation}
|
|
- Is Solution: {analysis.IsSolution}";
|
|
|
|
if (analysis.IsSolution)
|
|
{
|
|
summary += $"\n\nSub-Projects:\n{string.Join("\n", analysis.SubProjects.Select(p => $"- {p.ProjectName} ({p.DetectedProjectType})"))}";
|
|
}
|
|
|
|
return summary;
|
|
}
|
|
|
|
private string PrepareApiSummaryForAI(ProjectAnalysisResult analysis)
|
|
{
|
|
var apiSummary = "Public API Methods:\n";
|
|
|
|
foreach (var api in analysis.PublicApis.Take(15)) // Limit for token management
|
|
{
|
|
apiSummary += $"\n{api.ReturnType} {api.Name}(";
|
|
if (api.Parameters.Any())
|
|
{
|
|
apiSummary += string.Join(", ", api.Parameters);
|
|
}
|
|
apiSummary += ")";
|
|
|
|
if (!string.IsNullOrEmpty(api.Summary))
|
|
{
|
|
apiSummary += $" // {api.Summary}";
|
|
}
|
|
|
|
if (api.IsAsync)
|
|
{
|
|
apiSummary += " [Async]";
|
|
}
|
|
}
|
|
|
|
return apiSummary;
|
|
}
|
|
|
|
private string PrepareDetailedApiSummaryForAI(ProjectAnalysisResult analysis)
|
|
{
|
|
var detailed = "Detailed API Analysis:\n";
|
|
|
|
var groupedApis = analysis.PublicApis
|
|
.GroupBy(api => ExtractClassName(api.Name))
|
|
.Take(5); // Limit classes for token management
|
|
|
|
foreach (var group in groupedApis)
|
|
{
|
|
detailed += $"\n## {group.Key} Class\n";
|
|
|
|
foreach (var api in group.Take(8)) // Limit methods per class
|
|
{
|
|
detailed += $"\n### {api.Name}\n";
|
|
detailed += $"Return Type: {api.ReturnType}\n";
|
|
detailed += $"Parameters: {(api.Parameters.Any() ? string.Join(", ", api.Parameters) : "None")}\n";
|
|
detailed += $"Async: {api.IsAsync}\n";
|
|
|
|
if (!string.IsNullOrEmpty(api.Summary))
|
|
{
|
|
detailed += $"Description: {api.Summary}\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
return detailed;
|
|
}
|
|
|
|
private string ExtractClassName(string methodName)
|
|
{
|
|
// Simple heuristic - in a real implementation, you'd track the actual containing class
|
|
return "Service"; // Default fallback
|
|
}
|
|
|
|
private async Task<string> CallAIForReadmeEnhancement(List<ChatMessage> messages)
|
|
{
|
|
try
|
|
{
|
|
// This would integrate with your existing Claude service
|
|
// For now, return a placeholder that indicates AI processing
|
|
|
|
// In a real implementation, you would:
|
|
// 1. Use your existing Claude4ExampleService pattern
|
|
// 2. Call the AI API with the prepared messages
|
|
// 3. Process tool calls if the AI wants to read files
|
|
// 4. Return the enhanced content
|
|
|
|
_logger.LogInformation("AI enhancement requested with {MessageCount} messages", messages.Count);
|
|
|
|
// Placeholder for AI integration
|
|
return await Task.FromResult("AI enhancement placeholder - integrate with Claude service");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "AI enhancement call failed");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private string GenerateFallbackDescription(ProjectAnalysisResult analysis)
|
|
{
|
|
var features = new List<string>();
|
|
|
|
if (analysis.PublicApis.Any())
|
|
features.Add($"provides {analysis.PublicApis.Count} public API methods");
|
|
|
|
if (analysis.Dependencies.Any())
|
|
features.Add($"integrates with {analysis.Dependencies.Count} external packages");
|
|
|
|
if (analysis.HasTests)
|
|
features.Add("includes comprehensive test coverage");
|
|
|
|
var description = $"A {analysis.DetectedProjectType} built with .NET {analysis.TargetFramework}";
|
|
|
|
if (features.Any())
|
|
{
|
|
description += " that " + string.Join(", ", features);
|
|
}
|
|
|
|
return description + ".";
|
|
}
|
|
|
|
private string GenerateFallbackExamples(ProjectAnalysisResult analysis)
|
|
{
|
|
if (analysis.DetectedProjectType == "library" && analysis.PublicApis.Any())
|
|
{
|
|
var firstApi = analysis.PublicApis.First();
|
|
return $@"### Basic Usage
|
|
|
|
```csharp
|
|
using {analysis.KeyFiles.FirstOrDefault()?.Namespace ?? analysis.ProjectName};
|
|
|
|
// Example usage
|
|
var service = new ServiceClass();
|
|
{(firstApi.IsAsync ? "var result = await " : "var result = ")}service.{firstApi.Name}({GenerateExampleParams(firstApi.Parameters)});
|
|
```";
|
|
}
|
|
|
|
return $@"### Getting Started
|
|
|
|
```csharp
|
|
// TODO: Add specific usage examples for {analysis.ProjectName}
|
|
// This section will be enhanced with actual usage patterns
|
|
```";
|
|
}
|
|
|
|
private string GenerateFallbackApiDocs(ProjectAnalysisResult analysis)
|
|
{
|
|
if (!analysis.PublicApis.Any()) return "";
|
|
|
|
var docs = "## API Reference\n\n";
|
|
|
|
foreach (var api in analysis.PublicApis.Take(10))
|
|
{
|
|
docs += $"### {api.Name}\n\n";
|
|
docs += $"```csharp\n{api.ReturnType} {api.Name}({string.Join(", ", api.Parameters)})\n```\n\n";
|
|
|
|
if (!string.IsNullOrEmpty(api.Summary))
|
|
{
|
|
docs += $"{api.Summary}\n\n";
|
|
}
|
|
}
|
|
|
|
return docs;
|
|
}
|
|
|
|
private string GenerateExampleParams(List<string> parameters)
|
|
{
|
|
if (!parameters.Any()) return "";
|
|
|
|
return string.Join(", ", parameters.Select(p =>
|
|
{
|
|
var type = p.Split(' ')[0].ToLower();
|
|
return type switch
|
|
{
|
|
"string" => "\"example\"",
|
|
"int" => "42",
|
|
"bool" => "true",
|
|
"double" or "decimal" => "3.14",
|
|
_ => "null"
|
|
};
|
|
}));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Result of AI-enhanced README generation
|
|
/// </summary>
|
|
public class EnhancedReadmeResult
|
|
{
|
|
public bool Success { get; set; }
|
|
public string Error { get; set; }
|
|
public ProjectAnalysisResult OriginalAnalysis { get; set; }
|
|
public string EnhancedContent { get; set; }
|
|
public Dictionary<string, string> EnhancedSections { get; set; } = new();
|
|
public bool EnhancementApplied { get; set; }
|
|
public List<string> AIInsights { get; set; } = new();
|
|
public DateTime GeneratedAt { get; set; } = DateTime.UtcNow;
|
|
} |