Zaiets.OpenAI.Lite
1.0.0
dotnet add package Zaiets.OpenAI.Lite --version 1.0.0
NuGet\Install-Package Zaiets.OpenAI.Lite -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="Zaiets.OpenAI.Lite" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Zaiets.OpenAI.Lite" Version="1.0.0" />
<PackageReference Include="Zaiets.OpenAI.Lite" />
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 Zaiets.OpenAI.Lite --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: Zaiets.OpenAI.Lite, 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 Zaiets.OpenAI.Lite@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=Zaiets.OpenAI.Lite&version=1.0.0
#tool nuget:?package=Zaiets.OpenAI.Lite&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Zaiets.OpenAI.Lite
Minimal OpenAI API client for .NET 8 — GPT-4, embeddings, function calling, streaming, and multi-turn conversations without the overhead of heavy SDKs.
Author: Vladyslav Zaiets — CTO & Software Architect | sarmkadan.com
Installation
dotnet add package Zaiets.OpenAI.Lite
Quick Start
using Zaiets.OpenAI.Lite;
var client = new OpenAIClient("sk-...");
// Single question
string answer = await client.Chat.AskAsync("What is the capital of France?");
Console.WriteLine(answer); // Paris
Features
| Feature | API |
|---|---|
| Chat completions (GPT-4o, GPT-4, etc.) | client.Chat.CompleteAsync(request) |
| Single-question shortcut | client.Chat.AskAsync(message) |
| Server-Sent Events streaming | client.Chat.StreamAsync(request) |
| JSON structured output | client.Chat.AskJsonAsync<T>(message) |
| Multi-turn conversation | new ConversationBuilder(client.Chat, systemPrompt) |
| Text embeddings | client.Embeddings.EmbedAsync(text) |
| Batch embeddings | client.Embeddings.EmbedBatchAsync(texts) |
| Semantic similarity search | client.Embeddings.FindSimilarAsync(query, candidates) |
| Function / tool calling loop | client.Chat.RunToolLoopAsync(request, toolbox) |
| Dependency injection | services.AddOpenAILite(apiKey) |
| List available models | client.ListModelsAsync() |
Chat Completions
Simple request
var request = new ChatCompletionRequest
{
Model = OpenAIModels.Gpt4o,
Temperature = 0.7f,
Messages =
[
new ChatMessage(ChatRole.System, "You are a concise assistant."),
new ChatMessage(ChatRole.User, "Explain dependency injection in one sentence."),
],
};
var response = await client.Chat.CompleteAsync(request);
Console.WriteLine(response.Text);
Console.WriteLine($"Tokens used: {response.Usage?.TotalTokens}");
Fluent builder style
using Zaiets.OpenAI.Lite.Extensions;
var request = new ChatCompletionRequest { Model = OpenAIModels.Gpt4oMini }
.WithSystem("You are a code reviewer.")
.AddUserMessage("Review this method: public int Add(int a, int b) => a + b;")
.WithTemperature(0.2f)
.WithMaxTokens(512);
var response = await client.Chat.CompleteAsync(request);
Streaming
var request = new ChatCompletionRequest
{
Model = OpenAIModels.Gpt4o,
Messages = [new ChatMessage(ChatRole.User, "Write a short poem about .NET.")],
};
await foreach (var chunk in client.Chat.StreamAsync(request))
{
Console.Write(chunk); // prints tokens as they arrive
}
JSON structured output
record CityInfo(string Capital, string Population, string Language);
var city = await client.Chat.AskJsonAsync<CityInfo>(
"Return JSON with capital, population, and official language of Germany.",
model: OpenAIModels.Gpt4oMini);
Console.WriteLine(city?.Capital); // Berlin
Multi-Turn Conversations
ConversationBuilder keeps message history and sends the full context on every turn:
var conv = new ConversationBuilder(client.Chat, "You are a helpful travel assistant.")
.WithModel(OpenAIModels.Gpt4oMini)
.WithTemperature(0.7f);
string r1 = await conv.SendAsync("I want to visit Japan. Best time of year?");
string r2 = await conv.SendAsync("What about visa requirements for EU citizens?");
string r3 = await conv.SendAsync("Give me a 7-day Tokyo itinerary.");
// Stream a turn
await foreach (var chunk in conv.StreamAsync("Translate 'thank you' to Japanese."))
Console.Write(chunk);
// Reset to start a new topic (keeps system prompt)
conv.Reset();
Embeddings
// Single embedding
float[] vector = await client.Embeddings.EmbedAsync("Hello, world!");
// Cosine similarity
float similarity = EmbeddingsClient.CosineSimilarity(vectorA, vectorB);
// 1.0 = identical meaning, 0.0 = unrelated
// Semantic search
var results = await client.Embeddings.FindSimilarAsync(
query: "How do I handle errors in C#?",
candidates: new[]
{
"Exception handling with try/catch",
"Sorting algorithms in C#",
"Using ILogger for structured logging",
"Result pattern for error handling",
},
topK: 2);
foreach (var (text, score) in results)
Console.WriteLine($"{score:F3} {text}");
Function Calling
Build a FunctionToolbox, register handlers, then let the model call them:
var toolbox = new FunctionToolbox()
.Register(
name: "get_weather",
description: "Returns current weather for a city.",
parameters: ParameterSchemaBuilder.Create()
.AddString("city", "The city name")
.AddString("unit", "Temperature unit", required: false, enumValues: ["celsius", "fahrenheit"])
.Build(),
handler: (args, ct) =>
{
// parse args and call your real weather API here
using var doc = JsonDocument.Parse(args);
var city = doc.RootElement.GetProperty("city").GetString();
return Task.FromResult($"{{\"city\":\"{city}\",\"temp\":22,\"condition\":\"sunny\"}}");
})
.Register(
name: "search_web",
description: "Search the web for recent information.",
parameters: ParameterSchemaBuilder.Create()
.AddString("query", "The search query")
.Build(),
handler: (args, ct) => Task.FromResult("{\"results\": [\"result1\", \"result2\"]}"));
var request = new ChatCompletionRequest
{
Model = OpenAIModels.Gpt4oMini,
Messages = [new ChatMessage(ChatRole.User, "What's the weather like in Kyiv right now?")],
};
// Automatically loops: model calls tool → result appended → model replies
var finalResponse = await client.Chat.RunToolLoopAsync(request, toolbox, maxIterations: 5);
Console.WriteLine(finalResponse.Text);
Dependency Injection (ASP.NET Core)
// Program.cs
builder.Services.AddOpenAILite(
apiKey: builder.Configuration["OpenAI:ApiKey"]!,
options =>
{
options.Timeout = TimeSpan.FromMinutes(2);
options.OrganizationId = builder.Configuration["OpenAI:OrgId"];
});
// In your service / controller
public class MyService(OpenAIClient openAI)
{
public async Task<string> SummarizeAsync(string text)
=> await openAI.Chat.AskAsync($"Summarize: {text}", OpenAIModels.Gpt4oMini);
}
Custom Base URL (Azure, Ollama, vLLM)
// Azure OpenAI
var azureOptions = new OpenAIClientOptions
{
BaseUrl = "https://my-resource.openai.azure.com/openai/deployments/my-deployment/",
};
var azureClient = new OpenAIClient(apiKey: Environment.GetEnvironmentVariable("AZURE_OAI_KEY")!, azureOptions);
// Local Ollama
var ollamaOptions = new OpenAIClientOptions { BaseUrl = "http://localhost:11434/v1/" };
var ollamaClient = new OpenAIClient(apiKey: "ollama", ollamaOptions);
string reply = await ollamaClient.Chat.AskAsync("Hello!", model: "llama3.2");
Model Constants
OpenAIModels.Gpt4o // gpt-4o
OpenAIModels.Gpt4oMini // gpt-4o-mini (default, cheapest capable model)
OpenAIModels.Gpt4Turbo // gpt-4-turbo
OpenAIModels.O1 // o1 reasoning
OpenAIModels.O3Mini // o3-mini reasoning
OpenAIModels.TextEmbedding3Small // text-embedding-3-small (1536 dims)
OpenAIModels.TextEmbedding3Large // text-embedding-3-large (3072 dims)
Error Handling
using Zaiets.OpenAI.Lite.Exceptions;
try
{
var answer = await client.Chat.AskAsync("Hello");
}
catch (OpenAIAuthException) { /* invalid API key */ }
catch (OpenAIRateLimitException) { /* 429 - back off and retry */ }
catch (OpenAIValidationException e) { Console.WriteLine(e.Message); /* bad request */ }
catch (OpenAIException e) { Console.WriteLine($"API error {e.StatusCode}: {e.Message}"); }
License
MIT — see LICENSE.
© 2025 Vladyslav Zaiets
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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.
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.3)
- System.Text.Json (>= 8.0.5)
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 | 95 | 5/3/2026 |