Files
Playa/extensions/Volcanic.AgenticCore.Extensions.OpenAI/OpenAIModels.cs
EugeneTes 89623e14c2 feat(openai): chat completions provider extension
Streams POST {baseUrl}/chat/completions over SSE (System.Net.ServerSentEvents, no NuGet) and maps delta.content, delta.reasoning_content / delta.reasoning and delta.tool_calls onto AssistantMessageEvents via AssistantMessageBuilder. Configurable through OpenAIProviderOptions so one extension serves OpenAI, OpenRouter, Ollama and other compatible servers; ships the gpt-5 / gpt-5-mini / gpt-4.1 catalogue.
2026-09-25 12:45:43 +00:00

73 lines
2.6 KiB
C#

using Volcanic.AgenticCore.Abstractions.Providers;
namespace Volcanic.AgenticCore.Extensions.OpenAI;
/// <summary>
/// Default model catalogue for the <c>openai</c> provider (<c>openai-completions</c> api).
/// Models leave <see cref="Model.BaseUrl"/> unset so they inherit the provider's base URL when registered,
/// which keeps the same catalogue usable behind a proxy; <see cref="DefaultBaseUrl"/> is the upstream default.
/// </summary>
public static class OpenAIModels
{
public const string ProviderId = "openai";
public const string ApiId = "openai-completions";
public const string DefaultBaseUrl = "https://api.openai.com/v1";
/// <summary>
/// <c>reasoning_effort</c> values accepted by the GPT-5 family on the chat completions API.
/// <see cref="ThinkingLevel.XHigh"/> and <see cref="ThinkingLevel.Max"/> are not offered there and map to <c>null</c> (unsupported).
/// </summary>
public static IReadOnlyDictionary<ThinkingLevel, string?> Gpt5ThinkingLevels { get; } = new Dictionary<ThinkingLevel, string?>
{
[ThinkingLevel.Minimal] = "minimal",
[ThinkingLevel.Low] = "low",
[ThinkingLevel.Medium] = "medium",
[ThinkingLevel.High] = "high",
[ThinkingLevel.XHigh] = null,
[ThinkingLevel.Max] = null,
};
public static Model Gpt5 { get; } = new()
{
Id = "gpt-5",
Name = "GPT-5",
Provider = ProviderId,
Api = ApiId,
Reasoning = true,
Input = [ModelInput.Text, ModelInput.Image],
Cost = new ModelCost(Input: 1.25m, Output: 10m, CacheRead: 0.125m, CacheWrite: 0m),
ContextWindow = 400_000,
MaxTokens = 128_000,
ThinkingLevelMap = Gpt5ThinkingLevels,
};
public static Model Gpt5Mini { get; } = new()
{
Id = "gpt-5-mini",
Name = "GPT-5 mini",
Provider = ProviderId,
Api = ApiId,
Reasoning = true,
Input = [ModelInput.Text, ModelInput.Image],
Cost = new ModelCost(Input: 0.25m, Output: 2m, CacheRead: 0.025m, CacheWrite: 0m),
ContextWindow = 400_000,
MaxTokens = 128_000,
ThinkingLevelMap = Gpt5ThinkingLevels,
};
public static Model Gpt41 { get; } = new()
{
Id = "gpt-4.1",
Name = "GPT-4.1",
Provider = ProviderId,
Api = ApiId,
Reasoning = false,
Input = [ModelInput.Text, ModelInput.Image],
Cost = new ModelCost(Input: 2m, Output: 8m, CacheRead: 0.5m, CacheWrite: 0m),
ContextWindow = 1_047_576,
MaxTokens = 32_768,
};
public static IReadOnlyList<Model> All { get; } = [Gpt5, Gpt5Mini, Gpt41];
}