Skip to content

.NET (openai-dotnet) ​

The official OpenAI .NET library, NuGet package OpenAI.

Connect ​

baseUrl is http://127.0.0.1:4010/v1 and key is your plugboard key.

cs
var options = new OpenAIClientOptions { Endpoint = new Uri(baseUrl) }; // already ends in /v1
var http = new HttpClient();

ChatClient ClientFor(string model) => new(model: model, credential: new ApiKeyCredential(key), options: options);

Endpoint replaces the base URL whole, so include /v1. Pass the credential explicitly; otherwise the library reads OPENAI_API_KEY. model is an alias such as "fast" or any allowed provider/model[#variant].

Chat ​

cs
ChatCompletion completion = ClientFor(model).CompleteChat([new UserChatMessage(Prompt)]);

Tool calls ​

Plugboard returns the call. Your code runs the tool and sends the result back.

cs
ChatTool weatherTool = ChatTool.CreateFunctionTool(
    functionName: "get_weather",
    functionDescription: "Current weather for a city.",
    functionParameters: BinaryData.FromString("""
        {
            "type": "object",
            "properties": { "city": { "type": "string" } },
            "required": [ "city" ]
        }
        """));
var toolOptions = new ChatCompletionOptions();
toolOptions.Tools.Add(weatherTool);
cs
List<ChatMessage> messages = [new UserChatMessage(ToolPrompt)];
ChatCompletion first = client.CompleteChat(messages, toolOptions);
messages.Add(new AssistantChatMessage(first));
string city = "";
if (first.ToolCalls.Count > 0)
{
    ChatToolCall call = first.ToolCalls[0];
    using var argsJson = JsonDocument.Parse(call.FunctionArguments);
    city = argsJson.RootElement.GetProperty("city").GetString() ?? "";
    messages.Add(new ToolChatMessage(call.Id, $$"""{"temp_c": 18, "sky": "cloudy", "city": "{{city}}"}"""));
}
ChatCompletion final = client.CompleteChat(messages, toolOptions);

Streaming ​

cs
foreach (StreamingChatCompletionUpdate update in ClientFor(model).CompleteChatStreaming([new UserChatMessage(Prompt)]))
{
    foreach (ChatMessageContentPart part in update.ContentUpdate) text.Append(part.Text);
    if (update.FinishReason is not null) finish = FinishName(update.FinishReason.Value);
    if (update.Usage is not null) usage = update.Usage;
}

A complete console app with a text reply, a stream and a tool round trip is in examples/openai-dotnet/:

sh
cd examples/openai-dotnet
PLUGBOARD_KEY=<app key> dotnet run

What works ​

Chat Completions (ChatClient) with streaming, tools and ChatResponseFormat.CreateJsonSchemaFormat; the Responses API (ResponsesClient). One OpenAIClientOptions can be shared across clients.

Limits ​

  • Set MaxOutputTokenCount high enough (the example uses 1024) when the model reasons, so it has room to answer.