AI Integration
- 12 minutes to read
DevExpress AI-powered APIs allow you to integrate the following AI services into your DevExpress-powered WinForms, WPF, and Blazor applications:
- OpenAI
- Azure OpenAI
- Semantic Kernel
- Ollama (self-hosted models)
Note
DevExpress does not provide a REST API or include built-in LLMs/SLMs. To use AI services, you need an active Azure/OpenAI subscription to obtain the necessary REST API endpoint and key. This information must be provided at application startup to register AI clients and enable DevExpress AI-powered Extensions.
Prerequisites
- .NET 8 SDK / .NET Framework v4.7.2
- OpenAI
- An active Open AI subscription
- OpenAI API key
- Microsoft.Extensions.AI.OpenAI
- Azure OpenAI
- An active Azure subscription.
- Azure Open AI Service resource
- Azure OpenAI .NET SDK
- Microsoft.Extensions.AI.OpenAI
- Semantic Kernel
- Microsoft.SemanticKernel
- An active account/subscription to the AI service of your choice
- Microsoft.SemanticKernel.Connectors.* NuGet package (a connector to the AI service of your choice)
- Ollama (self-hosted models)
Register AI Clients
Install the DevExpress.AIIntegration
NuGet package to use DevExpress AI-powered Extensions in a .NET console application. This package contains APIs that implement core functionality for DevExpress AI-powered Extensions and services.
DevExpress AI-powered Extensions operate within an AIExtensionsContainerDefault container. This container manages registered AI clients. Use the AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer method to create a container for AI-powered extensions and register a chat client in a .NET console application.
Tip
Read the following help topics for information on how to register AI Clients in WinForms, WPF, and Blazor applications:
Azure OpenAI
The following code snippets register an Azure OpenAI chat client:
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
OpenAI
The following example registers an OpenAI chat client in a console application:
using OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterOpenAIClient(
Environment.GetEnvironmentVariable("OPENAI_KEY")
);
AIExtensionsContainerDefault RegisterOpenAIClient(string openAIKey) {
IChatClient client = new OpenAIClient(openAIKey)
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("OPENAI_KEY", {SPECIFY_YOU_OPENAI_KEY});
}
Semantic Kernel
Install the connector package for the AI service. This example uses Microsoft.SemanticKernel.Connectors.Google.
using Microsoft.Extensions.AI;
using Microsoft.SemanticKernel;
using Microsoft.SemanticKernel.ChatCompletion;
using Microsoft.SemanticKernel.Connectors.Google;
var builder = Kernel.CreateBuilder().AddGoogleAIGeminiChatCompletion("YOUR_MODEL_ID", "YOUR_API_KEY", GoogleAIVersion.V1_Beta);
Kernel kernel = builder.Build();
IChatClient googleChatClient = kernel.GetRequiredService<IChatCompletionService>().AsChatClient();
Ollama
The following code snippet registers an Ollama client:
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
IChatClient client = new OllamaChatClient(new Uri("http://localhost:11434/"), "MODEL_NAME");
AIExtensionsContainerDefault defaultAIExtensionsContainer = AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
AI-powered Extensions
The following table lists DevExpress AI-powered Extensions, registration methods, and request types:
Use DevExpress-Powered Extensions
Once you register an AI client, you can utilize DevExpress AI-powered Extensions.
The following example registers an Azure OpenAI client to use the AI-powered extension in an .NET Console application to generate a description for the following image:
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
string imageBase64 = "iVBORw0KGgoAAAANSUhEUgAABhgAAAF+CAMAAABHxuB6AAAABGdBTUEAALGPC...";
var response = await defaultAIExtensionsContainer.GenerateImageDescriptionAsync(
new GenerateImageDescriptionRequest(imageBase64)
);
Console.WriteLine(response);
/* Output:
* Toolbar with File menu and various document actions.
*/
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
Expand the following sections for additional examples:
The following example registers an Azure OpenAI client and uses the AI-powered extension to proofread originalText
in a .NET console application:
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
string originalText = "DevExpress AI APIs allaw to yuo register and used multiple AI services within WinForms WPF or Blazor aplication.";
var response = await defaultAIExtensionsContainer.ProofreadAsync(
new ProofreadRequest(originalText)
);
Console.WriteLine(response);
/* Output:
* DevExpress AI APIs allow you to register and use multiple AI services within WinForms, WPF, or Blazor applications.
*/
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
The following example registers an Azure OpenAI client and uses the AI-powered extension to change the writing style of originalText
:
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
string originalText = "DevExpress released Universal v24.2 - the award-winning software development platform for .NET and Visual Studio developers.";
var response = await defaultAIExtensionsContainer.ChangeStyleAsync(
new ChangeStyleRequest(originalText, WritingStyle.Academic)
);
Console.WriteLine(response);
/* Output:
* DevExpress has announced the release of Universal v24.2, an acclaimed software development platform
* designed specifically for .NET and Visual Studio developers.
*/
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
The following example registers an Azure OpenAI client and uses the AI-powered extension to translate the specified text into Italian in a .NET console application:
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
string textToTranslate = "\"A slow sort of country!\" said the Queen.";
var response = await defaultAIExtensionsContainer.TranslateAsync(
new TranslateRequest(textToTranslate, "Italian")
);
Console.WriteLine(response);
/* Output:
* "Un tipo di paese un po' lento!" disse la Regina.
*/
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
Azure AI Translator & AI Language Support
Install the following NuGet packages to use Azure AI Language services (including Azure AI Translator and Azure AI Language for text summarization):
DevExpress.AIIntegration.Azure.TextAnalytics
DevExpress.AIIntegration.Azure.Translation
using Azure;
using Azure.AI.Translation.Text;
using Azure.AI.TextAnalytics;
string azureTranslatorEndpoint = GetEnvironmentVariable("AZURE_TRANSLATOR_ENDPOINT");
string azureTranslatorKey = GetEnvironmentVariable("AZURE_TRANSLATOR_API_KEY");
var translationClient = new TextTranslationClient(new AzureKeyCredential(azureTranslatorKey), new Uri(azureTranslatorEndpoint));
string azureTextAnalyticsEndpoint = GetEnvironmentVariable("AZURE_TEXT_ANALYTICS_ENDPOINT");
string azureTextAnalyticsKey = GetEnvironmentVariable("AZURE_TEXT_ANALYTICS_API_KEY");
var textAnalyticsClient = new TextAnalyticsClient(new Uri(azureTextAnalyticsEndpoint), new AzureKeyCredential(azureTextAnalyticsKey));
The following code snippets register Azure AI Language services in desktop and Web applications.
WinForms / WPF:
//Register an Azure.TextTranslation client.
AIExtensionsContainerDesktop.Default.RegisterTranslatorAzureAIService(translationClient);
//Register an Azure.TextAnalytics client.
AIExtensionsContainerDesktop.Default.RegisterTextAnalyticsAzureAIService(textAnalyticsClient);
Blazor / ASP.NET Core:
services.AddDevExpressAI(config =>
config.RegisterTranslatorAzureAIService(translationClient);
config.RegisterTextAnalyticsAzureAIService(textAnalyticsClient);
);
The following example registers an Azure Text Analytics client and uses the AI-powered extension to generate a summary for originalText
:
using Azure;
using Azure.AI.TextAnalytics;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
AIExtensionsContainerDefault defaultAIExtensionsContainer;
RegisterTextAnalyticsService(
Environment.GetEnvironmentVariable("AZURE_TEXT_ANALYTICS_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_TEXT_ANALYTICS_API_KEY")
);
string originalText = "This must be a long text...";
var response = await defaultAIExtensionsContainer.AbstractiveSummaryAsync(
new AbstractiveSummaryRequest(originalText) { Language = "de", SentenceCount = 3 }
);
Console.WriteLine(response);
void RegisterTextAnalyticsService(string azureTextAnalyticsEndpoint, string azureTextAnalyticsAIKey)
{
defaultAIExtensionsContainer = new AIExtensionsContainerDefault();
var textAnalyticsClient = new TextAnalyticsClient(
new Uri(azureTextAnalyticsEndpoint),
new AzureKeyCredential(azureTextAnalyticsAIKey)
);
defaultAIExtensionsContainer.RegisterTextAnalyticsAzureAIService(textAnalyticsClient);
}
Process Long Input Text and AI Responses
AI-powered Extensions automatically split large content into manageable chunks to ensure accurate processing. Use the following settings to configure size limits for text content and images:
Property Name | Description | Default Value |
---|---|---|
ChatMaxTokensDefault | Specifies the maximum number of tokens that can be processed by a model request. Applies to all DevExpress AI-powered Extensions. | |
ChatTemperatureDefault | Specifies the default temperature for chat-based AI-powered Extensions. | |
ChunkMaxLength | Specifies the maximum number of characters allowed in each chunk of text. | 6,000 |
ImageBufferMaxSize | Specifies the maximum size of the Base64 image per request, in bytes. | 2MB |
TextBufferMaxSize | Specifies the maximum size of the input text per request, in bytes. | 64KB |
The following example manages large text blocks and handles AI service responses:
public async Task<string> GetTranslation(string textToTranslate, string language) {
TextResponse result = await defaultAIContainer.TranslateAsync(new TranslateRequest(textToTranslate, language));
if(result.IsCompleted)
return result.Response;
if(!result.IsRestrictedOrFailed) {
string translatedText = result.Response;
while(result.IsContinuationRequired){
await result.ContinueAsync();
translatedText += result.Response
}
return translatedText;
}
//Something unexpected happened.
switch (result.Status) {
case ResponseStatus.MaxTokenLimitExceeded:
case ResponseStatus.InputSizeLimitExceeded:
return "The text you're trying to send within a request is too long and exceeds the allowed limit.";
case ResponseStatus.ContentFiltered:
return "Potentially harmful content was detected in your request.";
case ResponseStatus.Error:
return "An error occurred while processing the request.";
}
throw new NotSupportedException();
}
Customize DevExpress AI-powered Extensions
AI-powered Extensions ship with pre-built prompts. The following example creates a custom extension. The WilliamShakespeareStyleExtension
is based on the DevExpress ChangeStyleExtension
. The example overrides the GetSystemPrompt
method to customize the prompt:
//Register the WilliamShakespeareStyleExtension within the default container.
//This extension overrides the DevExpress ChangeStyleExtension.
AIExtensionsContainerDesktop.Default.Register<ChangeStyleRequest, WilliamShakespeareStyleExtension>();
public class WilliamShakespeareStyleExtension : ChangeStyleExtension {
public WilliamShakespeareStyleExtension(IServiceProvider serviceProvider) : base(serviceProvider) { }
protected override string GetSystemPrompt(ChangeStyleRequest request) {
return "Rewrite this text in the William Shakespeare style.";
}
}
Error Logging and Handling
Implement the IAIExceptionHandler
interface to display AI-related error messages (for example, errors encountered when sending requests/receiving responses from an AI service).
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Extensions;
public class AIExceptionHandler : IAIExceptionHandler {
private readonly ILogger _logger;
public AIExceptionHandler(ILogger logger) {
this._logger = logger;
}
public Exception ProcessException(Exception exception) {
_logger.LogInformation($"An error occurred: {exception.Message}");
return new Exception ("Something went wrong. Please try again later.", exception);
}
}
Use the RegisterAIExceptionHandler method to register the exception handler in the AIExtensionsContainerDefault:
AIExtensionsContainerDesktop.Default.RegisterAIExceptionHandler(new AIExceptionHandler(new MyFavoriteLogger()));
Tip
To log AI service requests and completions in your application, implement the IChatClient
as demonstrated in the following GitHub repository: AI Samples for .NET.
Localization
DevExpress AI-powered Extensions support localization. By localizing AI-powered Extensions, you can adapt the user interface and any predefined content to meet the linguistic and cultural preferences of your end users. You can also customize prompts based on regional preferences (for example, when using single-language AI models).
Example: Respond in the Language of the Current Culture
The following example creates a custom localizer (CustomAILocalizer
) that derives from AIIntegrationLocalizer. The example overrides the GetLocalizedString
method to return a localized “Change Style” prompt based on the current locale in a .NET console application. Finally, the example assigns the CustomAILocalizer
to the AIIntegrationLocalizer.Active property.
No matter what language the original text is written in, the answer will be in the language of the current culture.
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.Localization;
using DevExpress.AIIntegration.Extensions;
using System.Globalization;
SetEnvironmentVariables();
// Register an Azure OpenAI client
AIExtensionsContainerDefault defaultAIExtensionsContainer = RegisterAzureOpenAIClient(
Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"),
Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
);
//Set the Spanish culture as the current culture.
CultureInfo.CurrentUICulture = new CultureInfo("es-ES");
//Enable a custom localizer.
AIIntegrationLocalizer.Active = new CustomAILocalizer();
string originalText = "Specify the original text...";
var response = await defaultAIExtensionsContainer.ChangeStyleAsync(new ChangeStyleRequest(originalText, WritingStyle.Academic));
Console.WriteLine(response);
AIExtensionsContainerDefault RegisterAzureOpenAIClient(string azureOpenAIEndpoint, string azureOpenAIKey) {
IChatClient client = new AzureOpenAIClient(
new Uri(azureOpenAIEndpoint),
new AzureKeyCredential(azureOpenAIKey))
.AsChatClient("gpt-4o-mini");
return AIExtensionsContainerConsole.CreateDefaultAIExtensionContainer(client);
}
void SetEnvironmentVariables() {
Environment.SetEnvironmentVariable("AZURE_OPENAI_ENDPOINT", {SPECIFY_YOUR_AZURE_ENDPOINT});
Environment.SetEnvironmentVariable("AZURE_OPENAI_APIKEY", {SPECIFY_YOU_AZURE_KEY});
}
public class CustomAILocalizer : AIIntegrationLocalizer {
public override string GetLocalizedString(AIIntegrationStringId id) {
switch (id) {
case AIIntegrationStringId.ChangeStyleSystemPrompt:
return GetChangeStyleLocalizedPrompt(CultureInfo.CurrentUICulture.EnglishName);
default:
return base.GetLocalizedString(id);
}
}
private string GetChangeStyleLocalizedPrompt(string cultureName) {
return "Rewrite the text provided to match the {0} writing style. Ensure the rewritten text follows the grammatical rules and stylistic conventions of the specified style. Preserve the original meaning and context. Use complete sentences and a professional tone. " + $"Translate answer to {cultureName} with no markdown formatting.";
}
}
Example: Respond in the Language of the Original Text
The following example creates a custom localizer that overrides the GetLocalizedString
method to return a custom prompt. Our AI-powered Extensions return answers in the language of the original text.
public class CustomAILocalizer : AIIntegrationLocalizer {
public override string GetLocalizedString(AIIntegrationStringId id) {
return GetLocalizedPrompt(id);
}
private string GetLocalizedPrompt(AIIntegrationStringId id) {
string prompt = "Recognize the language in this text. Reply directly using the recognized language. ";
prompt += base.GetLocalizedString(id);
return prompt;
}
}
Tip
See the following help topic for general information about UI localization: DevExpress Products: UI Localization Overview.
AI-powered Extensions in UI Controls
WinForms
- Introduction to AI-powered Extensions for WinForms
- AI Assistant (Change Style, Proofread, Summarize, Translate, etc.)
- AI Chat Control
- Explain Formula
- Generate Image Description
- Smart Autocomplete
- Smart Paste
- Smart Search
WPF
- AI Assistant (Change Tone, Expand, Explain, Shorten, etc.)
- Explain Formula
- Generate Image Description
- Smart Autocomplete