Skip to content

Repository files navigation

Devlooped AI Extensions

Icon Devlooped AI Extensions

VersionDownloadsEULAOSS

Extensions for Microsoft.Extensions.AI

Overview

This package adds configuration-driven client registration, provider resolution, tool helpers, OpenAI-specific extensions, and observability helpers for Microsoft.Extensions.AI.

It is split into two packages:

PackagePurpose
Devlooped.Extensions.AIConfiguration, providers, chat helpers, tools, OpenAI extras, and pipeline observability
Devlooped.Extensions.AI.ConsoleRich JSON console logging for chat and HTTP pipeline messages

Configuration-driven clients

Register clients from configuration with AddAIClients:

varbuilder=Host.CreateApplicationBuilder(args);builder.Configuration.AddJsonFile("appsettings.json",optional:false,reloadOnChange:true);builder.AddAIClients();varapp=builder.Build();varchat=app.Services.GetChatClient("Grok");

The default configuration prefix is ai:clients. A minimal configuration section looks like this:

{
"AI": {
"Clients": {
"Grok": {
"provider": "xai",
"apikey": "xai-...",
"modelid": "grok-4-fast"
}
}
}
}

Useful rules:

Config shapeRegistration
section has apikeykeyed IClientFactory
section has modelidkeyed IChatClient
section path ends in Grokadds Grok as an implicit lookup key
section has idadds an extra lookup key
section has lifetimecontrols the chat client lifetime

IChatClient and IClientFactory registrations are keyed by their full configuration section path and by the last section path segment. An optional id adds another lookup key without replacing the section-path key. IChatClient registrations are reloadable. IClientFactory registrations stay valid across configuration changes and create fresh clients each time you call CreateChatClient, CreateSpeechToTextClient, or CreateTextToSpeechClient.

Built-in provider support:

ProviderNameChatSpeech-to-textText-to-speechMatch
OpenAIopenaiyesyesyesexplicit provider, or https://api.openai.com/
Azure OpenAIazure.openaiyesyesyesexplicit provider, or *.openai.azure.com
Azure AI Inferenceazure.inferenceyesnonoexplicit provider, or https://ai.azure.com/
xAI / Grokxaiyesyesyesexplicit provider, or https://api.x.ai/

When provider is omitted, endpoint-based matching is used. If no endpoint is provided at all, OpenAI is the default provider.

You can also register your own provider:

builder.Services.AddAIClientProvider<MyClientProvider>();// orbuilder.Services.AddAIClientProvider(sp =>newMyClientProvider(sp));

Use useDefaultProviders: false if you want only your own providers:

builder.AddAIClients(useDefaultProviders:false);

Section-bound clients expose the provider options they were created with. Most callers can request the provider options type directly, for example:

varoptions=chat.GetService<OpenAIClientOptions>();

For keyed lookup, use GetChatClient, GetSpeechToTextClient, and GetTextToSpeechClient.

Client defaults

Use the Configure*ClientDefaults methods to apply shared pipelines without touching each registration site.

builder.ConfigureChatClientDefaults(b =>b.UseLogging()).ConfigureChatClientDefaults("AI:Clients:Grok", b =>b.UseLogging()).ConfigureSpeechToTextClientDefaults(b =>b.UseLogging()).ConfigureTextToSpeechClientDefaults(b =>b.UseLogging()).AddAIClients();

Behavior:

RuleMeaning
Global defaultsapply to every client of that modality
Section-specific defaultsmatch the exact configuration section path, case-insensitively
Section pathsuse : separators, not .
Orderregistrations run in the order they were added

Chat defaults survive reloads because they are applied outside the reloadable chat wrapper. Factory-created speech/chat clients get defaults applied on each Create* call.

Chat helpers

Chat is a convenient IList<ChatMessage> implementation with factory helpers:

varmessages=newChat{Chat.System("You are a helpful assistant."),Chat.User("What is 101 * 3?")};varoptions=newChatOptions{EndUserId="user-123"};

Chat also supports collection initializer syntax with string roles:

varchat=newChat{{"system","You are concise."},{"user","Say hello."}};

Chat.Developer(...) is also available for developer-role messages.

For source-generated serialization, use ChatJsonContext.DefaultOptions.

Tool calling helpers

ToolFactory.Create turns a delegate into an AIFunction with safe, snake_case tool names:

staticMyResultRunTool(stringname,stringdescription,stringcontent)=>new(name,description,content);AIFunctiontool=ToolFactory.Create(RunTool);

ToolExtensions.FindCalls locates tool invocations and their results in ChatResponse or message histories:

varresponse=awaitclient.GetResponseAsync(messages,options);varcall=response.FindCalls<MyResult>(tool).FirstOrDefault();if(callis not null){Console.WriteLine(call.Result);}

If you only need the raw call/result pair, use the untyped FindCalls overload and inspect Outcome.Exception.

ToolJsonOptions.Default provides the serializer settings used by the tool helpers.

OpenAI extras

The Devlooped.Extensions.AI.OpenAI namespace adds OpenAI-specific helpers on top of ChatOptions.

Verbosity

Verbosity is available as an extension property on ChatOptions:

usingDevlooped.Extensions.AI.OpenAI;varoptions=newChatOptions{Verbosity=Verbosity.Low};

Verbosity is supported by GPT-5+ models. Setting it automatically configures the raw response factory, so do not set a custom RawRepresentationFactory yourself when using it.

If you want a bindable options type, use OpenAIChatOptions.

Web search

WebSearchTool wraps the OpenAI Responses API web search tool with typed location and domain controls:

varoptions=newChatOptions{Tools=[newWebSearchTool("AR"){Region="Bariloche",TimeZone="America/Argentina/Buenos_Aires",AllowedDomains=["catedralaltapatagonia.com"]}]};

Supported properties:

PropertyMeaning
CountryISO alpha-2 country code
RegionFree-text region
CityFree-text city
TimeZoneIANA time zone
AllowedDomainsDomain allow-list for search results

Observability

ClientPipelineExtensions adds low-level request/response observation for any ClientPipelineOptions-derived type:

varrequests=newList<JsonNode>();varresponses=newList<JsonNode>();varoptions=OpenAIClientOptions.Observable(requests.Add,responses.Add);

Observe adds the pipeline policy to an existing options instance; Observable creates a configured instance in one call. Non-JSON payloads are ignored.

Console logging

Install Devlooped.Extensions.AI.Console to get rich JSON console logging.

Chat pipeline logging

usingDevlooped.Extensions.AI;usingMicrosoft.Extensions.AI;varchat=someChatClient.AsBuilder().UseJsonConsoleLogging(newJsonConsoleOptions{InteractiveOnly=false,TruncateLength=200}).Build();

HTTP pipeline logging

varclient=newOpenAIClient(apiKey,newOpenAIClientOptions().UseJsonConsoleLogging());

JsonConsoleOptions lets you control:

OptionMeaning
Border / BorderStylepanel appearance
IncludeAdditionalPropertiesinclude extra message/response data
InteractiveConfirmask before enabling logging in interactive consoles
InteractiveOnlysuppress output when the console is not interactive
TruncateLengthtrim long text
WrapLengthwrap long text

The default settings favor interactive development sessions and keep non-interactive output quiet.

Open Source Maintenance Fee

To ensure the long-term sustainability of this project, users of this package who generate revenue must pay an Open Source Maintenance Fee. While the source code is freely available under the terms of the License, this package and other aspects of the project require adherence to the Maintenance Fee.

To pay the Maintenance Fee, become a Sponsor at the proper OSMF tier. A single fee covers all of Devlooped packages.

Sponsors

Clarius OrgMFB Technologies, Inc.SandRockDRIVE.NET, Inc.Keith PickfordThomas BolonKori FrancisReuben SwartzJacob FosheeEric JohnsonJonathan Ken BonnySimon Croppagileworks-euZheyu ShenVezelChilliCream4OTCdomischellAdrian AlonsotorutekRyan McCafferySeika LogicielAndrew Granteska-gmbhGeodata AS

Sponsor this project

Learn more about GitHub Sponsors

About

Extensions for Microsoft.Extensions.AI

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

4 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages