forked from admin/VolcanicAgenticCore
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.
48 lines
1.7 KiB
C#
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,
|
|
};
|
|
}
|