Skip to main content
All docs
V24.2

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

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:

Extension Class Registration Method Request Type
Change Style ChangeStyleExtension ChangeStyleAsync ChangeStyleRequest
Change Tone ChangeToneExtension ChangeStyleAsync ChangeToneRequest
Expand ExpandExtension ExpandAsync ExpandRequest
Explain ExplainExtension ExplainAsync ExplainRequest
Explain Formula ExplainFormulaExtension ExplainFormulaAsync ExplainFormulaRequest
Generate Image Description GenerateImageDescriptionExtension GenerateImageDescriptionAsync GenerateImageDescriptionRequest
Proofread ProofreadExtension ProofreadAsync ProofreadRequest
Shorten ShortenExtension ShortenAsync ShortenRequest
Summarize (Abstractive) AbstractiveSummaryExtension AbstractiveSummaryAsync AbstractiveSummaryRequest
Summarize (Extractive) ExtractiveSummaryExtension ExtractiveSummaryAsync ExtractiveSummaryRequest
Translate TranslateExtension TranslateAsync TranslateRequest
Ask AI Assistant CustomPromptExtension CustomPromptAsync CustomPromptRequest
Smart Autocomplete SmartAutoCompleteExtension SmartAutoCompleteAsync SmartAutoCompleteRequest
Smart Paste SmartPasteAIExtension SmartPasteAsync SmartPasteRequest
Smart Search SmartSearchAIExtension SmartSearchAsync SmartSearchRequest

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:

Toolbar with File menu and various document actions.

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:

Use the Proofread AI Extension

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});
}
Use the Change Style AI Extension

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});
}
Use the Translate AI Extension

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);
);
Use Azure Text Analytics to Generate a Summary in a .NET Console App

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

Run Demo: WinForms AI-powered Extensions

WPF

  • AI Assistant (Change Tone, Expand, Explain, Shorten, etc.)
  • Explain Formula
  • Generate Image Description
  • Smart Autocomplete

Blazor

Reporting