189 lines
6.1 KiB
C#
189 lines
6.1 KiB
C#
using ChatBot.Models.Configuration;
|
|
using Microsoft.Extensions.Options;
|
|
using ServiceStack;
|
|
|
|
namespace ChatBot.Services
|
|
{
|
|
public class ModelService
|
|
{
|
|
private readonly ILogger<ModelService> _logger;
|
|
private readonly OpenRouterSettings _openRouterSettings;
|
|
private readonly JsonApiClient _client;
|
|
private List<string> _availableModels = new();
|
|
private int _currentModelIndex = 0;
|
|
|
|
public ModelService(
|
|
ILogger<ModelService> logger,
|
|
IOptions<OpenRouterSettings> openRouterSettings
|
|
)
|
|
{
|
|
_logger = logger;
|
|
_openRouterSettings = openRouterSettings.Value;
|
|
_client = new JsonApiClient(_openRouterSettings.Url)
|
|
{
|
|
BearerToken = _openRouterSettings.Token,
|
|
};
|
|
}
|
|
|
|
public async Task InitializeAsync()
|
|
{
|
|
try
|
|
{
|
|
var models = await LoadModelsFromApiAsync();
|
|
_availableModels = models.Any()
|
|
? models
|
|
: _openRouterSettings.AvailableModels.ToList();
|
|
|
|
SetDefaultModel();
|
|
_logger.LogInformation("Current model: {Model}", GetCurrentModel());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to initialize models, using configuration fallback");
|
|
_availableModels = _openRouterSettings.AvailableModels.ToList();
|
|
_currentModelIndex = 0;
|
|
}
|
|
}
|
|
|
|
private async Task<List<string>> LoadModelsFromApiAsync()
|
|
{
|
|
var response = await _client.GetAsync<dynamic>("/v1/models");
|
|
if (response == null)
|
|
{
|
|
_logger.LogInformation(
|
|
"Using {Count} models from configuration (API unavailable)",
|
|
_openRouterSettings.AvailableModels.Count
|
|
);
|
|
return new List<string>();
|
|
}
|
|
|
|
var models = ParseModelsFromResponse(response);
|
|
if (models.Any())
|
|
{
|
|
_logger.LogInformation(
|
|
"Loaded {Count} models from OpenRouter API",
|
|
(int)models.Count
|
|
);
|
|
return models;
|
|
}
|
|
|
|
_logger.LogInformation(
|
|
"Using {Count} models from configuration",
|
|
_openRouterSettings.AvailableModels.Count
|
|
);
|
|
return new List<string>();
|
|
}
|
|
|
|
private static List<string> ParseModelsFromResponse(dynamic response)
|
|
{
|
|
var models = new List<string>();
|
|
|
|
if (response is not System.Text.Json.JsonElement jsonElement)
|
|
return models;
|
|
|
|
if (
|
|
!jsonElement.TryGetProperty("data", out var dataElement)
|
|
|| dataElement.ValueKind != System.Text.Json.JsonValueKind.Array
|
|
)
|
|
return models;
|
|
|
|
foreach (var modelElement in dataElement.EnumerateArray())
|
|
{
|
|
if (modelElement.TryGetProperty("id", out var idElement))
|
|
{
|
|
var modelId = idElement.GetString();
|
|
if (!string.IsNullOrEmpty(modelId))
|
|
{
|
|
models.Add(modelId);
|
|
}
|
|
}
|
|
}
|
|
|
|
return models;
|
|
}
|
|
|
|
private void SetDefaultModel()
|
|
{
|
|
if (
|
|
string.IsNullOrEmpty(_openRouterSettings.DefaultModel)
|
|
|| !_availableModels.Contains(_openRouterSettings.DefaultModel)
|
|
)
|
|
{
|
|
_currentModelIndex = 0;
|
|
return;
|
|
}
|
|
|
|
_currentModelIndex = _availableModels.IndexOf(_openRouterSettings.DefaultModel);
|
|
}
|
|
|
|
public string GetCurrentModel()
|
|
{
|
|
return _availableModels.Count > 0 ? _availableModels[_currentModelIndex] : string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Получает настройки для текущей модели
|
|
/// </summary>
|
|
/// <returns>Настройки модели или настройки по умолчанию</returns>
|
|
public ModelSettings GetCurrentModelSettings()
|
|
{
|
|
var currentModel = GetCurrentModel();
|
|
if (string.IsNullOrEmpty(currentModel))
|
|
{
|
|
return GetDefaultModelSettings();
|
|
}
|
|
|
|
// Ищем настройки для текущей модели
|
|
var modelConfig = _openRouterSettings.ModelConfigurations.FirstOrDefault(m =>
|
|
m.Name.Equals(currentModel, StringComparison.OrdinalIgnoreCase)
|
|
);
|
|
|
|
if (modelConfig != null)
|
|
{
|
|
return modelConfig;
|
|
}
|
|
|
|
// Если настройки не найдены, возвращаем настройки по умолчанию
|
|
return GetDefaultModelSettings();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Получает настройки по умолчанию
|
|
/// </summary>
|
|
/// <returns>Настройки по умолчанию</returns>
|
|
private ModelSettings GetDefaultModelSettings()
|
|
{
|
|
return new ModelSettings
|
|
{
|
|
Name = GetCurrentModel(),
|
|
MaxTokens = _openRouterSettings.MaxTokens,
|
|
Temperature = _openRouterSettings.Temperature,
|
|
IsEnabled = true,
|
|
};
|
|
}
|
|
|
|
public bool TrySwitchToNextModel()
|
|
{
|
|
if (_availableModels.Count <= 1)
|
|
{
|
|
_logger.LogWarning("No alternative models available for switching");
|
|
return false;
|
|
}
|
|
|
|
_currentModelIndex = (_currentModelIndex + 1) % _availableModels.Count;
|
|
_logger.LogInformation("Switched to model: {Model}", GetCurrentModel());
|
|
return true;
|
|
}
|
|
|
|
public List<string> GetAvailableModels()
|
|
{
|
|
return _availableModels.ToList();
|
|
}
|
|
|
|
public bool HasAlternativeModels()
|
|
{
|
|
return _availableModels.Count > 1;
|
|
}
|
|
}
|
|
}
|