using System.Globalization;
using System.Net.Http.Json;
using System.Text.Json;
namespace AnchorCli.OpenRouter;
///
/// Fetches and caches model pricing from the OpenRouter API.
///
internal sealed class PricingProvider
{
private const string ModelsUrl = "https://openrouter.ai/api/v1/models";
private static readonly HttpClient Http = new();
private Dictionary? _models;
///
/// Fetches the full model list from OpenRouter (cached after first call).
///
public async Task> GetAllModelsAsync(
CancellationToken ct = default)
{
if (_models != null) return _models;
var response = await Http.GetAsync(ModelsUrl, ct);
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsStringAsync(ct);
var result = JsonSerializer.Deserialize(json, AppJsonContext.Default.ModelsResponse);
_models = result?.Data?.ToDictionary(m => m.Id) ?? [];
return _models;
}
///
/// Looks up pricing for a specific model ID. Returns null if not found.
///
public async Task GetModelInfoAsync(
string modelId, CancellationToken ct = default)
{
var models = await GetAllModelsAsync(ct);
return models.GetValueOrDefault(modelId);
}
///
/// Parses a pricing string (USD per token) to decimal. Returns 0 on failure.
///
public static decimal ParsePrice(string? priceStr) =>
decimal.TryParse(priceStr, NumberStyles.Float, CultureInfo.InvariantCulture, out var v)
? v
: 0m;
}