Files
Playa/extensions/Volcanic.AgenticCore.Extensions.OpenAI/OpenAIProviderExtension.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

48 lines
1.7 KiB
C#

using Volcanic.AgenticCore.Abstractions.Extensions;
using Volcanic.AgenticCore.Abstractions.Providers;
namespace Volcanic.AgenticCore.Extensions.OpenAI;
/// <summary>
/// Registers one OpenAI-compatible provider. With no options this is OpenAI itself
/// (<c>openai</c>, key from <c>OPENAI_API_KEY</c>, the <see cref="OpenAIModels"/> catalogue);
/// pass <see cref="OpenAIProviderOptions"/> to target OpenRouter, Ollama or any other compatible server.
/// </summary>
public sealed class OpenAIProviderExtension : IExtension
{
private readonly HttpClient? _http;
public OpenAIProviderExtension() : this(null, null) { }
public OpenAIProviderExtension(OpenAIProviderOptions? options = null, HttpClient? http = null)
{
Options = options ?? new OpenAIProviderOptions();
_http = http;
}
public OpenAIProviderOptions Options { get; }
public string Name => $"{Options.ProviderId}-provider";
public ValueTask ActivateAsync(IExtensionApi api, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(api);
api.RegisterProvider(CreateRegistration());
return ValueTask.CompletedTask;
}
/// <summary>The registration handed to <see cref="IExtensionApi.RegisterProvider"/>; also usable directly with a model registry.</summary>
public ProviderRegistration CreateRegistration() => new()
{
Id = Options.ProviderId,
Name = Options.EffectiveName,
Api = OpenAIModels.ApiId,
BaseUrl = Options.BaseUrl,
ApiKey = Options.EffectiveApiKeySpec,
Headers = Options.Headers,
Models = Options.EffectiveModels,
RequiresApiKey = Options.RequiresApiKey,
Stream = new OpenAICompletionsApi(Options, _http).StreamAsync,
};
}