Enhance UI, add AI integration, improve logging and database stats
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http.Json;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Predictalytics.Application.Interfaces;
|
||||
|
||||
namespace Predictalytics.Infrastructure.Providers.OpenRouter;
|
||||
|
||||
public class OpenRouterApiClient : IOpenRouterApiClient
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly IConfiguration _config;
|
||||
private readonly ILogger<OpenRouterApiClient> _logger;
|
||||
|
||||
public OpenRouterApiClient(HttpClient httpClient, IConfiguration config, ILogger<OpenRouterApiClient> logger)
|
||||
{
|
||||
_httpClient = httpClient;
|
||||
_config = config;
|
||||
_logger = logger;
|
||||
|
||||
var baseUrl = _config["OpenRouter:BaseUrl"] ?? "https://openrouter.ai/api/v1";
|
||||
var apiKey = _config["OpenRouter:ApiKey"];
|
||||
|
||||
_httpClient.BaseAddress = new Uri(baseUrl.EndsWith("/") ? baseUrl : baseUrl + "/");
|
||||
if (!string.IsNullOrEmpty(apiKey))
|
||||
{
|
||||
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
|
||||
}
|
||||
// OpenRouter recommends adding a referer and title for ranking
|
||||
_httpClient.DefaultRequestHeaders.Add("HTTP-Referer", "http://localhost");
|
||||
_httpClient.DefaultRequestHeaders.Add("X-Title", "Predictalytics");
|
||||
}
|
||||
|
||||
public async Task<string> GenerateChatCompletionAsync(string prompt, bool useManualModel = false, CancellationToken ct = default)
|
||||
{
|
||||
var model = useManualModel
|
||||
? _config["OpenRouter:ManualAnalysisModel"] ?? "anthropic/claude-3-opus"
|
||||
: _config["OpenRouter:DefaultModel"] ?? "google/gemini-flash-1.5";
|
||||
|
||||
var requestBody = new
|
||||
{
|
||||
model = model,
|
||||
messages = new[]
|
||||
{
|
||||
new { role = "system", content = "You are an expert crypto and prediction market analyst. You analyze a trader's history and deduce their strategy, strengths, and weaknesses." },
|
||||
new { role = "user", content = prompt }
|
||||
}
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
var response = await _httpClient.PostAsJsonAsync("chat/completions", requestBody, ct);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var result = await response.Content.ReadFromJsonAsync<OpenRouterResponse>(cancellationToken: ct);
|
||||
return result?.Choices?[0]?.Message?.Content ?? "No response generated.";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to generate chat completion from OpenRouter using model {Model}", model);
|
||||
return $"Error: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
private class OpenRouterResponse
|
||||
{
|
||||
[JsonPropertyName("choices")]
|
||||
public Choice[]? Choices { get; set; }
|
||||
}
|
||||
|
||||
private class Choice
|
||||
{
|
||||
[JsonPropertyName("message")]
|
||||
public Message? Message { get; set; }
|
||||
}
|
||||
|
||||
private class Message
|
||||
{
|
||||
[JsonPropertyName("content")]
|
||||
public string? Content { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user