From ca2c7c1ea04bce090b09c4d7167bcf09923260d4 Mon Sep 17 00:00:00 2001 From: Polina Tyureva Date: Tue, 4 Mar 2025 18:28:43 +0400 Subject: [PATCH 01/20] update example --- CS/Data/Dashboards/Financial.xml | 24 ++++++++++-------------- CS/Pages/Index.cshtml | 4 +++- CS/Services/AssistantHelper.cs | 2 +- CS/wwwroot/js/aiChatCustomItem.js | 14 +++++++------- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/CS/Data/Dashboards/Financial.xml b/CS/Data/Dashboards/Financial.xml index 7391bd0..641ee05 100644 --- a/CS/Data/Dashboards/Financial.xml +++ b/CS/Data/Dashboards/Financial.xml @@ -125,7 +125,7 @@ - + @@ -241,7 +241,7 @@ - + @@ -319,7 +319,7 @@ - + @@ -342,23 +342,19 @@ - - - - + + + + - - + + - + - - ["The dashboard shows stock prices for different vendors during a specified trading period. ","You can see detailed data for a specified vendor by selecting a card. The dashboard parameters allow you to change the trading period."] - [{"href":"https://docs.devexpress.com/Dashboard/117163/web-dashboard/create-dashboards-on-the-web/dashboard-item-settings/cards","text":"Cards"},{"href":"https://docs.devexpress.com/Dashboard/14758/winforms-dashboard/winforms-designer/create-dashboards-in-the-winforms-designer/dashboard-item-settings/chart/series/financial-series","text":"Financial Series"},{"href":"https://docs.devexpress.com/Dashboard/117159/web-dashboard/create-dashboards-on-the-web/dashboard-item-settings/chart","text":"Charts"},{"href":"https://docs.devexpress.com/Dashboard/402204/web-dashboard/create-dashboards-on-the-web/dashboard-item-settings/grid/conditional-formatting","text":"Conditional Formatting "},{"href":"https://docs.devexpress.com/Dashboard/117062/web-dashboard/create-dashboards-on-the-web/data-analysis/dashboard-parameters","text":"Dashboard Parameters"}] - \ No newline at end of file diff --git a/CS/Pages/Index.cshtml b/CS/Pages/Index.cshtml index 203bfa0..029dee3 100644 --- a/CS/Pages/Index.cshtml +++ b/CS/Pages/Index.cshtml @@ -1,4 +1,5 @@ @page +@using DevExpress.DashboardWeb + +
+@(Html.DevExpress().Dashboard("dashboardControl1") + .ControllerName("DefaultDashboard") + .OnBeforeRender("handleBeforeRender") + .OnDashboardInitialized("handleDashboardInitialized") +) +
+``` + +After you registered the extension the Assistant icon appears in the Dashboard Toolbox: + +![DevExpress BI Dashboard - AI Assistant Custom Item Icon](images/dashboard-toolbar-ai-assistant-item.png) + +Click the item to add an AI Assistant to the dashboard. Only one AI Assistant item is available per dashboard. You can ask the assistant questions in the Viewer mode. + +File to Review: +- [Index.cshtml](./CS/Pages/Index.cshtml) + +### Communicate with Assistant + +Each time a user sends a message, the [`onMessageEntered`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/Configuration/#onMessageEntered) event handler passes the request to the assistant: + +```js +// ... +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 sheet " + this.model.selectedSheet) + || "\nLet's discuss all sheets"); + const response = await this.getAIResponse(userInput); + this.renderAssistantMessage(instance, response); +} +``` + +[`AIChatController.GetAnswer`]() receives answers from the assistant. ## Files to Review -- link.cs (VB: link.vb) -- link.js -- ... +- [AIAssistantProvider.cs](./CS/Services/AIAssistantProvider.cs) +- [IAIAssistantProvider.cs](./CS/IAIAssistantProvider.cs) +- [Program.cs](./CS/Program.cs) ## Documentation -- link -- link -- ... +- [AI Integration](https://docs.devexpress.com/CoreLibraries/405204/ai-powered-extensions) +- [Create a Custom Item for the Web Dashboard](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) +- [Getting Started with JavaScript/jQuery Chat](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/Chat/Getting_Started_with_Chat/) ## More Examples -- link -- link -- ... +- [DevExtreme Chat - Getting Started](https://github.com/DevExpress-Examples/devextreme-getting-started-with-chat) +- [Reporting for ASP.NET Core - Integrate AI Assistant based on Azure OpenAI](https://github.com/DevExpress-Examples/web-reporting-integrate-ai-assistant) + ## Does this example address your development requirements/objectives? [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=example-repository-template&~~~was_helpful=yes) [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=example-repository-template&~~~was_helpful=no) (you will be redirected to DevExpress.com to submit your response) - + \ No newline at end of file diff --git a/images/dashboard-ai-assistant.png b/images/dashboard-ai-assistant.png new file mode 100644 index 0000000000000000000000000000000000000000..311379913c6b3ca05a9dad0fa9c56d9979f42ccc GIT binary patch literal 67076 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 OF$|urelF{r5}E*1{Nm#P literal 0 HcmV?d00001 From 3c58e8402d867c8b76d81f8ad3718f8bd28f8ebd Mon Sep 17 00:00:00 2001 From: DevExpressExampleBot Date: Tue, 4 Mar 2025 16:35:59 +0200 Subject: [PATCH 03/20] Created a new file vale.yml [skip ci] --- .github/workflows/vale.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/vale.yml diff --git a/.github/workflows/vale.yml b/.github/workflows/vale.yml new file mode 100644 index 0000000..068c35b --- /dev/null +++ b/.github/workflows/vale.yml @@ -0,0 +1,28 @@ +name: vale-validation +on: + pull_request: + paths: + - README.md + +jobs: + vale: + name: runner / vale + runs-on: ubuntu-latest + steps: + - name: clone repo + uses: actions/checkout@v4 + - name: clone vale-styles repo + uses: actions/checkout@v4 + with: + repository: DevExpress/vale-styles + path: vale-styles + ssh-key: ${{ secrets.VALE_STYLES_ACCESS_KEY }} + - name: copy vale rules to the root repo + run: shopt -s dotglob && cp -r ./vale-styles/vale/* . + - name: vale linter check + uses: DevExpress/vale-action@reviewdog + with: + files: README.md + fail_on_error: true + filter_mode: nofilter + reporter: github-check From 7480452c47edc18ca8cc603af1a7b91e305cd9da Mon Sep 17 00:00:00 2001 From: DevExpressExampleBot Date: Tue, 4 Mar 2025 18:36:04 +0400 Subject: [PATCH 04/20] README auto update [skip ci] --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 32997de..6467b4d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T1026838) +[![](https://img.shields.io/badge/Open_in_DevExpress_Support_Center-FF7200?style=flat-square&logo=DevExpress&logoColor=white)](https://supportcenter.devexpress.com/ticket/details/T1279614) [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) @@ -183,7 +183,7 @@ async onMessageEntered(e) { ## Does this example address your development requirements/objectives? -[](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=example-repository-template&~~~was_helpful=yes) [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=example-repository-template&~~~was_helpful=no) +[](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=asp-net-core-dashboard-integrate-ai-assistant&~~~was_helpful=yes) [](https://www.devexpress.com/support/examples/survey.xml?utm_source=github&utm_campaign=asp-net-core-dashboard-integrate-ai-assistant&~~~was_helpful=no) (you will be redirected to DevExpress.com to submit your response) - \ No newline at end of file + From df345ba7e4ac3f3c1c7fa8a854c7f2141e4718bc Mon Sep 17 00:00:00 2001 From: Polina Tyureva Date: Wed, 5 Mar 2025 15:45:26 +0400 Subject: [PATCH 05/20] update readme --- CS/Program.cs | 7 +------ README.md | 53 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/CS/Program.cs b/CS/Program.cs index 8aec5cb..921552a 100644 --- a/CS/Program.cs +++ b/CS/Program.cs @@ -1,22 +1,17 @@ using Azure; using Azure.AI.OpenAI; +using DashboardAIAssistant.Services; using DevExpress.AIIntegration; using DevExpress.AspNetCore; using DevExpress.DashboardAspNetCore; using DevExpress.DashboardCommon; using DevExpress.DashboardWeb; using DevExpress.DataAccess.Excel; -using DevExpress.DataAccess.Sql; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.AI; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; -using Microsoft.Extensions.Hosting.Internal; -using DashboardAIAssistant; -using DashboardAIAssistant.Services; -using System; -using System.IO; var builder = WebApplication.CreateBuilder(args); builder.Services diff --git a/README.md b/README.md index 32997de..c4ddf8b 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@ [![](https://img.shields.io/badge/📖_How_to_use_DevExpress_Examples-e9f6fc?style=flat-square)](https://docs.devexpress.com/GeneralInformation/403183) [![](https://img.shields.io/badge/💬_Leave_Feedback-feecdd?style=flat-square)](#does-this-example-address-your-development-requirementsobjectives) -# Dashboard for ASP.NET Core -- Integrate AI Assistant based on Azure OpenAI +# Dashboard for ASP.NET Core — Integrate AI Assistant based on Azure OpenAI -This example is an ASP.NET Core application with integrated DevExpress Reports and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. +This example is an ASP.NET Core application with integrated DevExpress Reports and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. An AI Assistant [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) is based on the `dxChat` widget. -![DevExpress BI Dashboard - Integrate AI Assistant](images/dashboard-ai-assistant.png) +![DevExpress BI Dashboard - Integrate an AI Assistant](images/dashboard-ai-assistant.png) -The AI Assistant reviews and analyzes all the data displayed in the dashboard to answer your questions. For a more focused analysis, you can select a specific dashboard item. Simply click the **Values** button in the AI Assistant custom item's caption and choose the desired widget. Any changes to dashboard data—such as updates to parameters or master filters—will automatically trigger a recreation of the AI Assistant. +The AI Assistant reviews and analyzes all the data displayed in the dashboard to answer your questions. For a more focused analysis, you can select a specific dashboard item. Click the **Values** button in the AI Assistant custom item's caption and choose the desired widget. Any changes to dashboard data—such as updates to parameters or master filters—will automatically trigger a recreation of the AI Assistant. The dashboard data is exported in Excel format and passed to the AI Assistant. **Please note that AI Assistant initialization takes time. The assistant is ready for interaction once Microsoft Azure scans the source document on the server side.** @@ -20,9 +20,9 @@ The AI Assistant reviews and analyzes all the data displayed in the dashboard to > [!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. -You need to create an Azure OpenAI resource in the Azure portal to use AI Assistants for DevExpress BI Dashboard. Refer to the following help topic for details: [Microsoft - Create and deploy an Azure OpenAI Service resource](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal). +Create an Azure OpenAI resource in the Azure portal to use AI Assistants for DevExpress BI Dashboard. Refer to the following help topic for details: [Microsoft - Create and deploy an Azure OpenAI Service resource](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal). -Once you obtain a private endpoint and an API key, register them as `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_APIKEY` environment variables. The [EnvSettings.cs](./CS/ReportingApp/EnvSettings.cs) reads these settings. `DeploymentName` in this file is a name of your Azure model, for example, `GPT4o`: +Once you obtain a private endpoint and an API key, register them as `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_APIKEY` environment variables. The [EnvSettings.cs](./CS/EnvSettings.cs) reads these settings. `DeploymentName` in this file is a name of your Azure model, for example, `GPT4o`: ```cs public static class EnvSettings { @@ -32,9 +32,6 @@ public static class EnvSettings { } ``` ->[!NOTE] -> Availability of Azure Open AI Assistants depends on the region. Refer to the following article for more details: [Assistants (Preview)](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models?tabs=global-standard%2Cstandard-chat-completions#assistants-preview). - Files to Review: - [EnvSettings.cs](./CS/EnvSettings.cs) @@ -62,6 +59,9 @@ builder.Services.AddDevExpressAI(config => // ... ``` +>[!NOTE] +> Availability of Azure Open AI Assistants depends on the region. Refer to the following article for more details: [Assistants (Preview)](https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models?tabs=global-standard%2Cstandard-chat-completions#assistants-preview). + Files to Review: - [Program.cs](./CS/Program.cs) @@ -82,11 +82,19 @@ Files to Review: - [AIAssistantProvider.cs](./CS/Services/AIAssistantProvider.cs) - [IAIAssistantProvider.cs](./CS/IAIAssistantProvider.cs) -### Create a Custom Item with AI Assistant +### Create a AI Assistant Custom Item + +This example implements a [custom item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the [`dxChat`](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/Chat/Overview/) component. The + +For instructions on how to implement a custom dashboard items, refer to tutorials in the following section: [Create a Custom Item for the Web Dashboard](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item). -This example implements a [custom item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the [`dxChat`](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/Chat/Overview/) component. +For the **AI Assistant** custom item implementation, review to the following file: [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) -For the **AI Assistant** custom item implementation, refer to the following file: [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) +The additional logic for the custom item is implemented in `handleDashboardInitialized` and `customizeChatCustomItemCaptionToolbar` in the [Index.cshtml](./CS/Pages/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 dashboard item for the AI Assistant. The `DashboardInitialized` event is handled to implement the one AI Assistant per dashboard logic. + +Files to Review: +- [Index.cshtml](./CS/Pages/Index.cshtml) +- [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) ### Register the Custom Item @@ -112,15 +120,25 @@ Register the created custom item extension in the Wen Dashboard: ``` -After you registered the extension the Assistant icon appears in the Dashboard Toolbox: +After you registered the extension the AI Assistant icon appears in the Dashboard Toolbox: ![DevExpress BI Dashboard - AI Assistant Custom Item Icon](images/dashboard-toolbar-ai-assistant-item.png) -Click the item to add an AI Assistant to the dashboard. Only one AI Assistant item is available per dashboard. You can ask the assistant questions in the Viewer mode. +Click the item to add an AI Assistant item to the dashboard. Only one AI Assistant item is available per dashboard. You can ask the assistant questions in the Viewer mode. File to Review: - [Index.cshtml](./CS/Pages/Index.cshtml) +### Access the Assistant + +Each time a dashboard is initialized or its [dashboard state](https://docs.devexpress.com/Dashboard/DevExpress.DashboardCommon.DashboardState) changes, a new assistant is created and the dashboard data is exported in Excel format. This way the AI assistant is always provided with up-to-date data. + +Files to Review: + +- [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) +- [AIAssistantProvider.cs](./CS/Services/AIAssistantProvider.cs) +- [AIChatController](./CS/Controllers/AIChatController.cs) + ### Communicate with Assistant Each time a user sends a message, the [`onMessageEntered`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/Configuration/#onMessageEntered) event handler passes the request to the assistant: @@ -161,13 +179,16 @@ async onMessageEntered(e) { } ``` -[`AIChatController.GetAnswer`]() receives answers from the assistant. +[`AIChatController.GetAnswer`](./CS/Controllers/AIChatController.cs#L38) receives answers from the assistant. ## Files to Review +- [Program.cs](./CS/Program.cs) +- [Index.cshtml](./CS/Pages/Index.cshtml) +- [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) - [AIAssistantProvider.cs](./CS/Services/AIAssistantProvider.cs) - [IAIAssistantProvider.cs](./CS/IAIAssistantProvider.cs) -- [Program.cs](./CS/Program.cs) +- [AIChatController](./CS/Controllers/AIChatController.cs) ## Documentation From 8ed6c3965b34d8bff3624622b2a72c1f49d4c4f4 Mon Sep 17 00:00:00 2001 From: Polina Tyureva Date: Wed, 5 Mar 2025 15:51:21 +0400 Subject: [PATCH 06/20] update readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 577cfcb..a360677 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ # Dashboard for ASP.NET Core — Integrate AI Assistant based on Azure OpenAI -This example is an ASP.NET Core application with integrated DevExpress Reports and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. An AI Assistant [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) is based on the `dxChat` widget. +This example is an ASP.NET Core application with integrated DevExpress BI Dashboard and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. An AI Assistant [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) is based on the `dxChat` widget. ![DevExpress BI Dashboard - Integrate an AI Assistant](images/dashboard-ai-assistant.png) -The AI Assistant reviews and analyzes all the data displayed in the dashboard to answer your questions. For a more focused analysis, you can select a specific dashboard item. Click the **Values** button in the AI Assistant custom item's caption and choose the desired widget. Any changes to dashboard data—such as updates to parameters or master filters—will automatically trigger a recreation of the AI Assistant. The dashboard data is exported in Excel format and passed to the AI Assistant. +The AI Assistant reviews and analyzes all the data displayed in the dashboard to answer your questions. For a more focused analysis, you can select a specific dashboard item. Click the **Select widget** button in the AI Assistant custom item's caption and choose the desired widget. Any changes to dashboard data—such as updates to parameters or master filters—will automatically trigger a recreation of the AI Assistant. The dashboard data is exported in Excel format and passed to the AI Assistant. **Please note that AI Assistant initialization takes time. The assistant is ready for interaction once Microsoft Azure scans the source document on the server side.** @@ -90,7 +90,7 @@ For instructions on how to implement a custom dashboard items, refer to tutorial For the **AI Assistant** custom item implementation, review to the following file: [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) -The additional logic for the custom item is implemented in `handleDashboardInitialized` and `customizeChatCustomItemCaptionToolbar` in the [Index.cshtml](./CS/Pages/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 dashboard item for the AI Assistant. The `DashboardInitialized` event is handled to implement the one AI Assistant per dashboard logic. +The additional logic for the custom item is implemented in the [Index.cshtml](./CS/Pages/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 dashboard item for the AI Assistant. The `DashboardInitialized` event is handled to implement the *one AI Assistant per dashboard* logic. Files to Review: - [Index.cshtml](./CS/Pages/Index.cshtml) @@ -131,7 +131,7 @@ File to Review: ### Access the Assistant -Each time a dashboard is initialized or its [dashboard state](https://docs.devexpress.com/Dashboard/DevExpress.DashboardCommon.DashboardState) changes, a new assistant is created and the dashboard data is exported in Excel format. This way the AI assistant is always provided with up-to-date data. +Each time a dashboard is initialized or its [dashboard state](https://docs.devexpress.com/Dashboard/DevExpress.DashboardCommon.DashboardState) changes, a new assistant is created and the dashboard data is exported in Excel format. This way the AI Assistant is always provided with up-to-date data. Files to Review: From 1fc8ac9e666c3af2012eb20dd901262a93bb7286 Mon Sep 17 00:00:00 2001 From: Polina Tyureva Date: Wed, 5 Mar 2025 15:54:03 +0400 Subject: [PATCH 07/20] update readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a360677..0f2751e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Dashboard for ASP.NET Core — Integrate AI Assistant based on Azure OpenAI -This example is an ASP.NET Core application with integrated DevExpress BI Dashboard and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. An AI Assistant [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) is based on the `dxChat` widget. +This example is an ASP.NET Core application with integrated DevExpress BI Dashboard and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. The AI Assistant is implemented as a [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the `dxChat` widget. ![DevExpress BI Dashboard - Integrate an AI Assistant](images/dashboard-ai-assistant.png) @@ -84,7 +84,7 @@ Files to Review: ### Create a AI Assistant Custom Item -This example implements a [custom item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the [`dxChat`](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/Chat/Overview/) component. The +This example implements a [custom item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the [`dxChat`](https://js.devexpress.com/jQuery/Documentation/Guide/UI_Components/Chat/Overview/) component. T For instructions on how to implement a custom dashboard items, refer to tutorials in the following section: [Create a Custom Item for the Web Dashboard](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item). @@ -96,9 +96,9 @@ Files to Review: - [Index.cshtml](./CS/Pages/Index.cshtml) - [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) -### Register the Custom Item +### Register the Custom Item Extension -Register the created custom item extension in the Wen Dashboard: +Register the created custom item extension in the Web Dashboard: ```html @@ -191,7 +190,7 @@ async onMessageEntered(e) { - [Index.cshtml](./CS/Pages/Index.cshtml) - [aiChatCustomItem.js](./CS/wwwroot/js/aiChatCustomItem.js) - [AIAssistantProvider.cs](./CS/Services/AIAssistantProvider.cs) -- [IAIAssistantProvider.cs](./CS/IAIAssistantProvider.cs) +- [IAIAssistantProvider.cs](./CS/Services/IAIAssistantProvider.cs) - [AIChatController.cs](./CS/Controllers/AIChatController.cs) - [AssistantHelper.cs](./CS/Services/AssistantHelper.cs) From 60c6c5db74f1d7dacf13c31775f7d93bf3090107 Mon Sep 17 00:00:00 2001 From: pollyndos <56310766+pollyndos@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:08:16 +0400 Subject: [PATCH 19/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8e08c1e..5c1b197 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ This example is an ASP.NET Core application with integrated DevExpress BI Dashbo ![DevExpress BI Dashboard - Integrate an AI Assistant](images/dashboard-ai-assistant.png) -The AI Assistant reviews and analyzes all the data displayed in the dashboard to answer your questions. For a more focused analysis, you can select a specific dashboard item. Click the **Select widget** button in the AI Assistant custom item's caption and choose the desired widget. Any changes to dashboard data—such as updates to parameters or master filters—will automatically trigger a recreation of the AI Assistant. The dashboard data is exported in Excel format and passed to the AI Assistant. +The AI Assistant reviews and analyzes all data displayed in the dashboard to answer your questions. You can narrow down available data if you select a specific dashboard item. Click the **Select widget** button in the AI Assistant custom item's caption and choose the desired widget. Note that updates to parameters or master filters, or any other data changes automatically trigger the AI Assistant recreation. **Please note that AI Assistant initialization takes time. The assistant is ready for interaction once Microsoft Azure scans the source document on the server side.** From d79d4cd2cab320f0d6da3a9b8ea4a4fa014699bf Mon Sep 17 00:00:00 2001 From: pollyndos <56310766+pollyndos@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:30:20 +0400 Subject: [PATCH 20/20] Apply suggestions from code review Co-authored-by: DirkPieterse --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5c1b197..47f83d3 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,11 @@ # Dashboard for ASP.NET Core — Integrate AI Assistant based on Azure OpenAI -This example is an ASP.NET Core application with integrated DevExpress BI Dashboard and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. The AI Assistant is implemented as a [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the `dxChat` widget. +This is an example of an ASP.NET Core application with an integrated DevExpress BI Dashboard and an AI assistant. User requests and assistant responses are displayed on-screen using the DevExtreme [`dxChat`](https://js.devexpress.com/jQuery/Documentation/24_2/ApiReference/UI_Components/dxChat/) component. The AI Assistant is implemented as a [custom dashboard item](https://docs.devexpress.com/Dashboard/117546/web-dashboard/advanced-customization/create-a-custom-item) based on the `dxChat` widget. ![DevExpress BI Dashboard - Integrate an AI Assistant](images/dashboard-ai-assistant.png) -The AI Assistant reviews and analyzes all data displayed in the dashboard to answer your questions. You can narrow down available data if you select a specific dashboard item. Click the **Select widget** button in the AI Assistant custom item's caption and choose the desired widget. Note that updates to parameters or master filters, or any other data changes automatically trigger the AI Assistant recreation. +The AI Assistant reviews and analyzes all data displayed in the dashboard to answer your questions. You can filter the available data if you select a specific dashboard item. Click the **Select widget** button in the AI Assistant custom item's caption and choose the desired widget. Note that updates to parameters or master filters or any other data changes automatically trigger the AI Assistant recreation. **Please note that AI Assistant initialization takes time. The assistant is ready for interaction once Microsoft Azure scans the source document on the server side.** @@ -22,7 +22,7 @@ The AI Assistant reviews and analyzes all data displayed in the dashboard to ans Create an Azure OpenAI resource in the Azure portal to use AI Assistants for DevExpress BI Dashboard. Refer to the following help topic for details: [Microsoft - Create and deploy an Azure OpenAI Service resource](https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/create-resource?pivots=web-portal). -Once you obtain a private endpoint and an API key, register them as `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_APIKEY` environment variables. Open [EnvSettings.cs](./CS/EnvSettings.cs) to review code that reads these settings. `DeploymentName` in this file is a name of your Azure model, for example, `GPT4o`: +Once you obtain a private endpoint and API key, register them as `AZURE_OPENAI_ENDPOINT` and `AZURE_OPENAI_APIKEY` environment variables. Open [EnvSettings.cs](./CS/EnvSettings.cs) to review the code that reads these settings. `DeploymentName` in this file is a name of your Azure model, for example, `GPT4o`: ```cs public static class EnvSettings { @@ -37,7 +37,7 @@ Files to Review: ### Register AI Services -Register AI services in your application. Add the following code to the _Program.cs_ file: +Add the following code to the _Program.cs_ file to register AI services in your application: ```cs using DevExpress.AIIntegration; @@ -123,7 +123,7 @@ Register the created custom item extension in the Web Dashboard: ``` -After you registered the extension, the AI Assistant icon appears in the Dashboard Toolbox: +After you register the extension, the AI Assistant icon appears in the Dashboard Toolbox: ![DevExpress BI Dashboard - AI Assistant Custom Item Icon](images/dashboard-toolbar-ai-assistant-item.png)