Sample ASP.NET Core application using DevExpress BI Dashboard with an integrated AI Assistant.
User requests and AI assistant responses are displayed on-screen (within the DevExtreme dxChat
component). The AI Assistant is implemented as a custom BI Dashboard item (based on the dxChat
widget).
To answer user questions, the AI Assistant reviews/analyzes all data displayed within the DevExpress BI Dashboard. You can filter available data if you select a specific Dashboard item. Click the Select widget button in the AI Assistant custom item caption and select the desired widget. Note: updates to parameters/master filters or other data changes automatically trigger recreation of the AI Assistant.
AI Assistant initialization takes time. The Assistant is ready for interaction once Microsoft Azure scans the source document (on the server side).
Note
We use the following versions of the Microsoft.Extensions.AI.*
libraries in our source code:
v24.2.6+ | 9.3.0-preview.1.25161.3
We do not guarantee compatibility or correct operation with higher versions. Refer to the following announcement for additional information: Microsoft.Extensions.AI.Abstractions NuGet Package Version Upgrade in v24.2.6.
Note
DevExpress AI-powered extensions follow the "bring your own key" principle. DevExpress does not offer a REST API and does not ship any built-in LLMs/SLMs. You need an active Azure/Open AI subscription to obtain the REST API endpoint, key, and model deployment name. These variables must be specified at application startup to register AI clients and enable DevExpress AI-powered Extensions in your application.
Create an Azure OpenAI resource in the Azure portal to use AI Assistants for DevExpress BI Dashboard. Refer to the following help topic for additional information in this regard: Microsoft - Create and deploy an Azure OpenAI Service resource.
Once you obtain a private endpoint and API key, register them as AZURE_OPENAI_ENDPOINT
and AZURE_OPENAI_APIKEY
environment variables. Open EnvSettings.cs to review the code that reads these settings. DeploymentName
in this file represents the name of your Azure model, for example, GPT4o:
public static class EnvSettings {
public static string AzureOpenAIEndpoint { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"); } }
public static string AzureOpenAIKey { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY"); } }
public static string DeploymentName { get { return "GPT4o"; } }
}
Files to Review:
Add the following code to the Program.cs file to register AI services in your application:
using DevExpress.AIIntegration;
using Azure;
using Azure.AI.OpenAI;
using Microsoft.Extensions.AI;
using System;
// ...
var azureOpenAIClient = new AzureOpenAIClient(
new Uri(EnvSettings.AzureOpenAIEndpoint),
new AzureKeyCredential(EnvSettings.AzureOpenAIKey));
var chatClient = azureOpenAIClient.AsChatClient(EnvSettings.DeploymentName);
builder.Services.AddDevExpressAI(config =>
{
config.RegisterOpenAIAssistants(azureOpenAIClient, EnvSettings.DeploymentName);
});
// ...
Note
Availability of Azure Open AI Assistants depends on region. Refer to the following article for additional information: Assistants (Preview).
Files to Review:
On the server side, the AIAssistantProvider
service manages assistants. An IAIAssistantFactory
instance creates assistants with keys specified in the previous steps.
public interface IAIAssistantProvider {
Task<string> CreateAssistant(Stream fileContent, string prompt);
IAIAssistant GetAssistant(string assistantId);
void DisposeAssistant(string assistantId);
}
You can review and tailor AI assistant instructions in the following file: AssistantHelper.cs
Files to Review:
This example implements a custom item based on the dxChat
component.
For instructions on how to implement custom BI Dashboard items, refer to the following tutorials: Create a Custom Item for the Web Dashboard](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item).
For our AI Assistant custom item implementation, review the following file: aiChatCustomItem.js.
Additional logic for the custom item is implemented in the Index.cshtml file. The itemCaptionToolbarUpdated
event is used to add a Select Widget button to the item's caption. This button allows users to select a BI Dashboard item and narrow data available to the AI Assistant. The DashboardInitialized
event handler implements one AI Assistant per dashboard logic.
Files to Review:
Register the custom item extension in the Web Dashboard:
<script type="text/javascript">
// ...
function handleBeforeRender(dashboardControl) {
chatAIItem = new AIChatItem(dashboardControl);
dashboardControl.registerExtension(chatAIItem);
// ...
}
// ...
</script>
<div style="position: relative; height: calc(100vh - 55px);">
@(Html.DevExpress().Dashboard("dashboardControl1")
.ControllerName("DefaultDashboard")
.OnBeforeRender("handleBeforeRender")
.OnDashboardInitialized("handleDashboardInitialized")
)
</div>
Once you register the extension, an AI Assistant icon will appear within the Dashboard Toolbox:
Click the item to add an AI Assistant item to the dashboard. Only one AI Assistant item is available per BI Dashboard. You can ask the assistant questions in Viewer mode.
File to Review:
Each time a Dashboard is initialized or its dashboard state changes, the application exports Dashboard data to an Excel spreadsheet and creates a new Assistant (so that the AI Assistant always processes up-to-date data).
Files to Review:
Each time a user sends a message, the onMessageEntered
event handler passes the request to the assistant:
// ...
getAnswer(chatId, question) {
const formData = new FormData();
formData.append('chatId', chatId);
formData.append('question', question);
return this._tryFetch(async () => {
const response = await fetch('/AIChat/GetAnswer', {
method: 'POST',
body: formData
});
return await response.text();
}, 'GetAnswer');
}
// ...
async getAIResponse(question) {
this.lastUserQuery = question;
if(!this.chatId)
this.chatId = await this.createChat(this.dashboardControl.getDashboardId(), this.dashboardControl.getDashboardState());
if(this.chatId)
return await this.getAnswer(this.chatId, question);
};
// ...
async onMessageEntered(e) {
const instance = e.component;
this.component.option('alerts', []);
instance.renderMessage(e.message);
instance.option({ typingUsers: [assistant] });
const userInput = e.message.text + ((this.model.selectedSheet && "\nDiscuss item " + this.model.selectedSheet)
|| "\nLet's discuss all items");
const response = await this.getAIResponse(userInput);
this.renderAssistantMessage(instance, response);
}
AIChatController.GetAnswer
receives answers from the assistant.
- Program.cs
- Index.cshtml
- aiChatCustomItem.js
- AIAssistantProvider.cs
- IAIAssistantProvider.cs
- AIChatController.cs
- AssistantHelper.cs
- AI Integration
- Create a Custom Item for the Web Dashboard
- Getting Started with JavaScript/jQuery Chat
(you will be redirected to DevExpress.com to submit your response)