381 lines
12 KiB
C#
Executable File
381 lines
12 KiB
C#
Executable File
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace MarketAlly.AIPlugin.ClaudeCode.Controllers;
|
|
|
|
/// <summary>
|
|
/// API controller providing Claude Code integration endpoints
|
|
/// </summary>
|
|
[ApiController]
|
|
[Route("api/[controller]")]
|
|
[Produces("application/json")]
|
|
public class ClaudeCodeLearningController : ControllerBase
|
|
{
|
|
private readonly IClaudeCodeService _claudeCodeService;
|
|
private readonly IChatService _chatService;
|
|
private readonly IContextClaudeService _contextService;
|
|
private readonly ILogger<ClaudeCodeLearningController> _logger;
|
|
|
|
public ClaudeCodeLearningController(
|
|
IClaudeCodeService claudeCodeService,
|
|
IChatService chatService,
|
|
IContextClaudeService contextService,
|
|
ILogger<ClaudeCodeLearningController> logger)
|
|
{
|
|
_claudeCodeService = claudeCodeService;
|
|
_chatService = chatService;
|
|
_contextService = contextService;
|
|
_logger = logger;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Send a chat message to Claude Code
|
|
/// </summary>
|
|
/// <param name="request">Chat request</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Claude's response</returns>
|
|
[HttpPost("chat")]
|
|
public async Task<IActionResult> SendChatMessage([FromBody] ChatRequest request, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _claudeCodeService.SendChatMessageAsync(request, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in SendChatMessage");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Analyze code or a file
|
|
/// </summary>
|
|
/// <param name="request">Analysis request</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Analysis results</returns>
|
|
[HttpPost("analyze")]
|
|
public async Task<IActionResult> AnalyzeCode([FromBody] AnalysisRequest request, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _claudeCodeService.AnalyzeCodeAsync(request, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in AnalyzeCode");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current rate limit status
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Rate limit information</returns>
|
|
[HttpGet("rate-limit/status")]
|
|
public async Task<IActionResult> GetRateLimitStatus(CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _claudeCodeService.GetRateLimitStatusAsync(cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in GetRateLimitStatus");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Search project context
|
|
/// </summary>
|
|
/// <param name="query">Search query</param>
|
|
/// <param name="projectPath">Optional project path</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Search results</returns>
|
|
[HttpGet("context/search")]
|
|
public async Task<IActionResult> SearchContext(
|
|
[FromQuery] string query,
|
|
[FromQuery] string? projectPath = null,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrWhiteSpace(query))
|
|
{
|
|
return BadRequest(new { success = false, error = "Query parameter is required" });
|
|
}
|
|
|
|
var response = await _claudeCodeService.SearchContextAsync(query, projectPath, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in SearchContext");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Store a decision or insight
|
|
/// </summary>
|
|
/// <param name="request">Decision storage request</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Success response</returns>
|
|
[HttpPost("context/store-decision")]
|
|
public async Task<IActionResult> StoreDecision([FromBody] StoreDecisionRequest request, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _claudeCodeService.StoreDecisionAsync(request, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in StoreDecision");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Start a new chat session
|
|
/// </summary>
|
|
/// <param name="request">Session start request</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>New session information</returns>
|
|
[HttpPost("sessions/start")]
|
|
public async Task<IActionResult> StartSession([FromBody] StartSessionRequest request, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _chatService.StartSessionAsync(request, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in StartSession");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get active chat sessions
|
|
/// </summary>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>List of active sessions</returns>
|
|
[HttpGet("sessions")]
|
|
public async Task<IActionResult> GetActiveSessions(CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _chatService.GetActiveSessionsAsync(cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in GetActiveSessions");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get session history
|
|
/// </summary>
|
|
/// <param name="sessionId">Session identifier</param>
|
|
/// <param name="maxMessages">Maximum messages to return</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Session message history</returns>
|
|
[HttpGet("sessions/{sessionId}/history")]
|
|
public async Task<IActionResult> GetSessionHistory(
|
|
string sessionId,
|
|
[FromQuery] int maxMessages = 50,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _chatService.GetSessionHistoryAsync(sessionId, maxMessages, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in GetSessionHistory");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// End a chat session
|
|
/// </summary>
|
|
/// <param name="sessionId">Session identifier</param>
|
|
/// <param name="cancellationToken">Cancellation token</param>
|
|
/// <returns>Success response</returns>
|
|
[HttpPost("sessions/{sessionId}/end")]
|
|
public async Task<IActionResult> EndSession(string sessionId, CancellationToken cancellationToken = default)
|
|
{
|
|
try
|
|
{
|
|
var response = await _chatService.EndSessionAsync(sessionId, cancellationToken);
|
|
|
|
if (response.Success)
|
|
{
|
|
return Ok(new
|
|
{
|
|
success = true,
|
|
data = response.Data,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
|
|
return BadRequest(new
|
|
{
|
|
success = false,
|
|
error = response.Error,
|
|
errorCode = response.ErrorCode,
|
|
rateLimitInfo = response.RateLimitInfo
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error in EndSession");
|
|
return StatusCode(500, new { success = false, error = "Internal server error" });
|
|
}
|
|
}
|
|
} |