Noundry.AIG - AI Gateway

Unified AI Gateway for .NET -- access OpenAI, Anthropic, Google Gemini, and more through a single, consistent API with automatic failover, streaming, and prompt chaining.

$ dotnet add package Noundry.AIG.Client

Overview

Noundry AI Gateway (AIG) is a production-ready .NET multi-provider AI gateway. It provides a unified interface for OpenAI, Anthropic, Google Gemini, and any OpenAI-compatible endpoint. The gateway is available as a hosted BYOK (Bring Your Own Key) service at https://api.noundry.ai or can be self-hosted.

Multi-Provider Routing

Single API for OpenAI, Anthropic, Google, Nebius, Together AI, Groq, Ollama, and LM Studio.

Provider Fallback

Automatic failover using the order parameter. First successful provider wins.

Streaming Support

Real-time SSE-based streaming from all providers via IAsyncEnumerable.

Chain Prompting

Sequential prompts where each step's output feeds into the next input automatically.

TOON Serialization

Convert DataTable, DataSet, and collections to token-efficient TOON format (~40% token savings).

Built-in Analytics

SQLite-based request logging via Noundry Tuxedo with usage statistics endpoints.

Architecture

Noundry.AIG/
src/
 Noundry.AIG.Core # Models, interfaces, extensions
 Noundry.AIG.Providers # OpenAI, Anthropic, Google implementations
 Noundry.AIG.Client # Client library (NuGet package)
 Noundry.AIG.Api # ASP.NET Core Web API

Design patterns: Factory (ProviderFactory), Builder (PromptBuilder), Strategy (IAiProvider), Repository (IAnalyticsRepository).

Quick Start

using Noundry.AIG.Client;
using Noundry.AIG.Client.Builders;
using Noundry.AIG.Client.Configuration;
using Noundry.AIG.Core.Extensions;
using Noundry.AIG.Core.Models;
using Noundry.AIG.Providers;

// Configure the client
var options = new AigClientOptions
{
 UseLocalProviders = true,
 EnableRetries = true,
 MaxRetries = 3,
 ProviderConfigs = new Dictionary<string, ProviderConfig>
 {
 ["openai"] = new ProviderConfig
 {
 ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY")
 },
 ["anthropic"] = new ProviderConfig
 {
 ApiKey = Environment.GetEnvironmentVariable("ANTHROPIC_API_KEY"),
 ApiVersionHeaderValue = "2023-06-01"
 }
 }
};

var aigClient = new AigClient(new ProviderFactory(httpClientFactory), options);

// Send a request
var prompt = new PromptBuilder()
 .WithModel("openai/gpt-4")
 .WithTemperature(0.7f)
 .AddSystemMessage("You are a helpful assistant.")
 .AddUserMessage("Explain quantum computing.")
 .Build();

var response = await aigClient.SendAsync(prompt);
Console.WriteLine(response.GetTextContent());

Model String Format

Models use the format {provider}/{model}. The provider prefix routes the request to the correct API.

Provider Example Models
openaiopenai/gpt-4, openai/gpt-4-turbo, openai/gpt-3.5-turbo
anthropicanthropic/claude-sonnet-4, anthropic/claude-3-opus, anthropic/claude-3-haiku
googlegoogle/gemini-pro, google/gemini-pro-vision

Custom OpenAI-compatible endpoints (Nebius, Together AI, Groq, Ollama, LM Studio) are also supported by configuring a custom ApiEndpoint on the provider config.

PromptBuilder API

The fluent PromptBuilder constructs AiRequest objects with type-safe configuration.

Method Reference

Method Description
WithModel(string)Set single model in "provider/model" format
WithModels(params string[])Set multiple models for fallback
AddSystemMessage(string)Add system prompt message
AddUserMessage(string)Add user message
AddAssistantMessage(string)Add assistant message (multi-turn)
WithTemperature(float)0.0 (deterministic) to 2.0 (creative)
WithMaxTokens(int)Maximum tokens to generate
WithStreaming(bool)Enable/disable streaming
WithTopP(float)Top-p nucleus sampling (0.0 to 1.0)
WithStopSequences(params string[])Set stop sequences
Build()Build the AiRequest object

Multi-Turn Conversation

var request = new PromptBuilder()
 .WithModel("anthropic/claude-sonnet-4")
 .AddSystemMessage("You are a creative storyteller.")
 .AddUserMessage("Start a story about a robot.")
 .AddAssistantMessage("In a world of circuits and steel...")
 .AddUserMessage("What happens next?")
 .Build();

ChainPromptBuilder

Chain multiple AI calls where each step's output feeds into the next. Each step can use a different model.

var chain = new ChainPromptBuilder()
 .WithDefaultModel("anthropic/claude-sonnet-4")
 .AddStep("Generate Idea", _ =>
 new PromptBuilder()
 .AddUserMessage("Give me a random creative writing topic."))
 .AddStep("Write Content", previousOutput =>
 new PromptBuilder()
 .AddUserMessage($"Write a short paragraph about: {previousOutput}"))
 .AddStep("Translate", previousOutput =>
 new PromptBuilder()
 .WithModel("openai/gpt-4")
 .AddUserMessage($"Translate to Spanish:\n{previousOutput}"));

var result = await chain.ExecuteAsync(aigClient);

if (result.Success)
{
 Console.WriteLine($"Final output: {result.FinalOutput}");
 // Access individual step results
 foreach (var step in result.Steps)
 Console.WriteLine($"{step.StepName}: {step.Output}");
}

Multi-Provider Fallback

Try multiple providers in order until one succeeds. Useful for high-availability scenarios.

var prompt = new PromptBuilder()
 .WithModels(
 "openai/gpt-4",
 "anthropic/claude-sonnet-4",
 "google/gemini-pro"
 )
 .AddUserMessage("Generate a story idea.")
 .Build();

var response = await aigClient.SendMultiAsync(prompt);

if (response.HasSuccess)
{
 Console.WriteLine($"Response from: {response.FirstSuccess.Provider}");
 Console.WriteLine(response.FirstSuccess.GetTextContent());
}

Streaming

var prompt = new PromptBuilder()
 .WithModel("openai/gpt-4")
 .WithStreaming(true)
 .AddUserMessage("Write a poem about nature.")
 .Build();

await foreach (var chunk in aigClient.SendStreamAsync(prompt))
{
 Console.Write(chunk.GetTextContent());
}

TOON Serialization

Convert data structures to TOON (Token-Oriented Object Notation) format for efficient LLM consumption. TOON reduces token usage by ~40% compared to JSON while maintaining data fidelity.

using Noundry.AIG.Core.Extensions;

// DataTable to TOON
var table = new DataTable("sales");
table.Columns.Add("product", typeof(string));
table.Columns.Add("qty", typeof(int));
table.Rows.Add("Widget", 10);

var toonData = table.ToToon();
// Output: sales[1]{product,qty}:
// Widget,10

// Collection to TOON
var users = new List<User> { new { Id = 1, Name = "Alice" } };
var toon = users.ToToon(new ToonOptions { RootName = "users" });

Hosted API

The AI Gateway is deployed at https://api.noundry.ai as a BYOK service. You provide your own provider API keys via the X-API-KEY header.

# Simple request via cURL
curl -X POST "https://api.noundry.ai/v1/chat/completions" \
 -H "Authorization: Bearer YOUR_GATEWAY_KEY" \
 -H "X-API-KEY: Bearer YOUR_OPENAI_KEY" \
 -H "Content-Type: application/json" \
 -d '{
 "model": "openai/gpt-4",
 "messages": [{"role": "user", "content": "Hello!"}]
 }'
Endpoint Method Description
/v1/chat/completionsPOSTChat completion request
/v1/analytics/logsGETRequest logs
/v1/analytics/usageGETUsage statistics
/healthGETHealth check (no auth)

Supported Providers

OpenAI
GPT-4, GPT-3.5
Anthropic
Claude 4, 3.5
Google
Gemini Pro
Extensible
Add your own

Related Packages