BYOK.OpenAI 1.0.0

dotnet add package BYOK.OpenAI --version 1.0.0
                    
NuGet\Install-Package BYOK.OpenAI -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="BYOK.OpenAI" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="BYOK.OpenAI" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="BYOK.OpenAI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add BYOK.OpenAI --version 1.0.0
                    
#r "nuget: BYOK.OpenAI, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package BYOK.OpenAI@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=BYOK.OpenAI&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=BYOK.OpenAI&version=1.0.0
                    
Install as a Cake Tool

BYOK RX — Bring Your Own Key

MIT License NuGet

OpenAI Anthropic Groq DeepSeek Ollama OpenRouter

One interface client, multiple providers.

Route AI requests across multiple LLM providers with automatic fallback, all through a unified IChatClient interface.

Features

  • Unified interface — single IChatClient that routes to OpenAI, Anthropic, Groq, DeepSeek, Ollama, OpenRouter, and any OpenAI-compatible provider
  • Automatic fallback — define fallback chains per model; if a provider fails, BYOK tries the next one
  • Model aliases — friendly names like "fast" or "cheap" that resolve to real model paths
  • Per-provider key rotation — each provider gets its own API key provider; keys can rotate at runtime without restart
  • Function calling — built-in support through Microsoft.Extensions.AI.FunctionInvokingChatClient
  • OpenTelemetry ready — providers expose ChatClientMetadata for observability instrumentation
  • Dependency injectionAddBYOKClient() extension for IServiceCollection

Install

dotnet add package BYOK.Core
dotnet add package BYOK.OpenAI
dotnet add package BYOK.Anthropic

Quick Start

using Microsoft.Extensions.AI;
using BYOK.Core;
using BYOK.OpenAI;
using BYOK.Anthropic;

var openAiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY") ?? "";
var anthropicKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY") ?? "";
var groqKey = Environment.GetEnvironmentVariable("GROQ_API_KEY") ?? "";

var byok = BYOKClient.Create(options =>
{
    options.UseOpenAI(openAiKey);
    options.UseAnthropic(anthropicKey);
    options.UseGroq(groqKey);

    options.Routing.ForModelId("openai:gpt-5.4-mini")
        .FallbackTo("groq:llama-4-maverick");

    options.Routing.ForAlias("fast")
        .Try("anthropic:claude-sonnet-5");

    options.DefaultTimeout = TimeSpan.FromSeconds(100);
});

var messages = new List<ChatMessage>
{
    new(ChatRole.System, "You are a helpful assistant."),
    new(ChatRole.User, "Hello!")
};

var chatOptions = new ChatOptions
{
    ModelId = "openai:gpt-5.4-mini"
};

var response = await byok.GetResponseAsync(messages, chatOptions);

Console.WriteLine($"Result: {response.Text}");

Dependency injection

services.AddBYOKClient(options =>
{
    options.UseOpenAI(openAiKey);
    options.UseAnthropic(anthropicKey);

    options.Routing.ForModelId("openai:gpt-5.4-mini")
        .FallbackTo("groq:llama-4-maverick");
});

Then inject IChatClient anywhere:

public class MyService(IChatClient chatClient)
{
    public async Task RunAsync()
    {
        var response = await chatClient.GetResponseAsync(messages, new ChatOptions
        {
            ModelId = "openai:gpt-5.4-mini"
        });
    }
}

Usage

Route format

Set ModelId to "{providerName}:{modelId}" and BYOK routes to the right provider:

ModelId = "openai:gpt-5.4-mini"
Route Provider Model
openai:gpt-5.4-mini openai gpt-5.4-mini
groq:llama-4-maverick groq llama-4-maverick
deepseek:deepseek-v4-flash deepseek deepseek-v4-flash
ollama:llama4 ollama llama4
anthropic:claude-sonnet-5 anthropic claude-sonnet-5

The provider name must match one registered via UseOpenAICompatible(), UseAnthropicCompatible(), or one of the built-in extensions.

Built-in providers

Extension Provider name (default) Notes
UseOpenAI() openai api.openai.com/v1
UseOpenAICompatible() custom Any OpenAI-compatible endpoint
UseGroq() groq api.groq.com/openai/v1
UseOpenRouter() openrouter openrouter.ai/api/v1
UseOllama() ollama localhost:11434/v1 (no API key needed)
UseDeepSeek() deepseek api.deepseek.com/v1
UseAnthropic() anthropic api.anthropic.com
UseAnthropicCompatible() custom Any Anthropic-compatible endpoint
UseDeepSeekAnthropic() deepseek-anthropic api.deepseek.com/anthropic
UseOllamaAnthropic() ollama-anthropic localhost:11434 (Anthropic-compatible)

Fallback

options.Routing.ForModelId("openai:gpt-5.4-mini")
    .FallbackTo("groq:llama-4-maverick")
    .FallbackTo("anthropic:claude-sonnet-5");

If the primary fails, BYOK tries fallbacks in order.

Aliases

options.Routing.ForAlias("fast").Try("anthropic:claude-sonnet-5");
options.Routing.ForAlias("cheap").Try("groq:deepseek-v4-flash");

Use anywhere a route is expected: ModelId = "fast".

Custom providers

options.UseOpenAICompatible(
    providerName: "myprovider"
    apiKey: openAiKey,
    configure: config =>
    {
        config.BaseUrl = "https://my-custom-endpoint.com/v1";
        config.AddHeader("X-Custom", "value");
        config.NativeOptions.ClientLoggingOptions.LogLevel = OpenAI.Diagnostics.ClientLogLevel.Informational;
    });

options.UseAnthropicCompatible(
    providerName: "myanthropic"
    apiKey: anthropicKey,
    configure: config =>
    {
        config.BaseUrl = "https://my-custom-anthropic.com";
    });

Then use ModelId = "myprovider:some-model" or ModelId = "myanthropic:some-model".

Or register any custom IChatClient with a factory:

options.UseProvider("my-custom", () => new MyChatClient(apiKey));

Streaming

await foreach (var update in byok.GetStreamingResponseAsync(messages, chatOptions))
{
    Console.Write(update.Text);
}

Function calling

var fcMessages = new List<ChatMessage>
{
    new(ChatRole.System, "You are a helpful assistant that can use tools."),
    new(ChatRole.User, "What time is it?")
};

var fcOptions = new ChatOptions
{
    ModelId = "groq:llama-4-maverick",
    Tools = [AIFunctionFactory.Create(GetCurrentTime)]
};

var response = await byok.GetResponseAsync(fcMessages, fcOptions);
Console.WriteLine($"Result: {response.Text}");

Define your function tool:

[Description("Returns the current time")]
static string GetCurrentTime() => DateTime.Now.ToString("HH:mm:ss");

Architecture

┌──────────────────────────────────────────┐
│              BYOKClient                   │
│  Routing → Provider Factory → IChatClient │
└──────────────────────────────────────────┘
         │                     │
         ▼                     ▼
  BYOK.OpenAI           BYOK.Anthropic
  OpenAICompatibleClient AnthropicChatClient
  (IChatClient)          (IChatClient)

Each provider client caches the underlying SDK client and only rebuilds when the API key changes.

License

MIT © BracoZS

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 86 7/3/2026