namespace Deal.Ai.Llm; /// /// Эффективный конфиг LLM-провайдера на один вызов /// public sealed record LlmConfig( string ProviderId, string BaseUrl, string Model, string? ApiKey, string? ApiStyle) { /// /// Значение api_style для Anthropic Messages API /// public const string AnthropicApiStyle = "anthropic"; private static readonly IReadOnlyDictionary KnownProviderNames = new Dictionary(StringComparer.OrdinalIgnoreCase) { ["deepseek"] = "DeepSeek", ["openai"] = "OpenAI", ["openrouter"] = "OpenRouter", ["anthropic"] = "Anthropic Claude", ["ollama"] = "Ollama (локально)", ["lmstudio"] = "LM Studio (локально)", ["custom"] = "Другой (OpenAI-совместимый)", }; /// /// Истинно, когда конфиг задаёт Anthropic Messages API /// public bool IsAnthropic => string.Equals(ApiStyle, AnthropicApiStyle, StringComparison.OrdinalIgnoreCase); /// /// Имя провайдера для сообщений об ошибках и логов /// public string DisplayName => KnownProviderNames.TryGetValue(ProviderId, out string? name) ? name : ProviderId; }