-
[DX_WPF] AI Chat ControlDevExpress/DX_WPF 2025. 12. 18. 09:03
view
<UserControl x:Class="LS.CommonUI.EngSearch.Com.Views.EngCopilotView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm" xmlns:ViewModels="clr-namespace:LS.CommonUI.EngSearch.Com.ViewModels" xmlns:dxaichat="http://schemas.devexpress.com/winfx/2008/xaml/aichat" xmlns:chat="clr-namespace:DevExpress.AIIntegration.Blazor.Chat;assembly=DevExpress.AIIntegration.Blazor.Chat.v25.2" xmlns:system="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="600"> <Grid> <dxaichat:AIChatControl x:Name="aiChatControl" ContentFormat="Markdown" UseStreaming="True" InputEnabled="True" FileUploadEnabled="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10"> <dxmvvm:Interaction.Behaviors> <dxmvvm:EventToCommand SourceName="aiChatControl" EventName="MarkdownConvert" Command="{Binding MarkdownConvertCommand}" PassEventArgsToCommand="True"/> <dxmvvm:EventToCommand SourceName="aiChatControl" EventName="MessageSent" Command="{Binding MessageSentCommand}" PassEventArgsToCommand="True"/> </dxmvvm:Interaction.Behaviors> <dxaichat:AIChatControl.FileUploadSettings> <chat:DxAIChatFileUploadSettings MaxFileSize="5000000" MaxFileCount="5"> <chat:DxAIChatFileUploadSettings.AllowedFileExtensions> <system:String>.png</system:String> <system:String>.pdf</system:String> <system:String>.txt</system:String> </chat:DxAIChatFileUploadSettings.AllowedFileExtensions> <chat:DxAIChatFileUploadSettings.FileTypeFilter> <system:String>image/png</system:String> <system:String>application/pdf</system:String> <system:String>text/plain</system:String> </chat:DxAIChatFileUploadSettings.FileTypeFilter> </chat:DxAIChatFileUploadSettings> </dxaichat:AIChatControl.FileUploadSettings> <dxaichat:AIChatControl.PromptSuggestions> <chat:DxAIChatPromptSuggestion Title="Birthday Wish" Text="A warm and cheerful birthday greeting message." PromptMessage="Write a heartfelt birthday message for a close friend." /> <chat:DxAIChatPromptSuggestion Title="Thank You Note" Text="A polite thank you note to express gratitude." PromptMessage="Compose a short thank you note to a colleague who helped with a project." /> </dxaichat:AIChatControl.PromptSuggestions> </dxaichat:AIChatControl> </Grid> </UserControl>viewModel
using Azure.AI.OpenAI; using DevExpress.AIIntegration; using DevExpress.AIIntegration.Blazor.Chat.WebView; using DevExpress.Data.Utils; using DevExpress.Mvvm; using LS.CommonUI.EngSearch.Com.Models; using Microsoft.AspNetCore.Components; using Microsoft.Extensions.AI; using Microsoft.Extensions.Logging; using ModelContextProtocol.Client; using OpenAI.Chat; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; using ChatMessage = Microsoft.Extensions.AI.ChatMessage; namespace LS.CommonUI.EngSearch.Com.ViewModels; public class EngCopilotViewModel : ViewModelBase { public string Header { get; set; } = "XGPilot"; IChatClient asChatClient = null; List<Microsoft.Extensions.AI.ChatMessage> messages = []; public EngCopilotViewModel() { RegisterAIChatClient(); //var tools = GetMCPToolTest(); //ApplyToolsToChatClient(); } private DelegateCommand<object> markdownConvertCommand; public DelegateCommand<object> MarkdownConvertCommand => markdownConvertCommand ?? (markdownConvertCommand = new DelegateCommand<object>(ExecuteMarkdownConvertCommand)); void ExecuteMarkdownConvertCommand(object obj) { var e = obj as AIChatControlMarkdownConvertEventArgs; e.HtmlText = (MarkupString)Markdig.Markdown.ToHtml(e.MarkdownText); } private DelegateCommand<object> messageSentCommand; public DelegateCommand<object> MessageSentCommand => messageSentCommand ?? (messageSentCommand = new DelegateCommand<object>(ExecuteMessageSentCommand)); async void ExecuteMessageSentCommand(object obj) { var e = obj as AIChatControlMessageSentEventArgs; var message = e.Content; var messages = await ApplyToolsToChatClient(message, e); //await e.SendMessage(, ChatRole.Assistant); } async Task<IList<McpClientTool>> GetMCPToolTest() { var client = McpClientCollection.GetAxMcpClient(); var tools = await client.ListToolsAsync(); return tools; } async Task<List<ChatMessage>> ApplyToolsToChatClient(string message, AIChatControlMessageSentEventArgs eventArgs) { //Console.Write("Q: "); messages.Add(new(ChatRole.User, message)); List<ChatResponseUpdate> updates = []; string updateText = string.Empty; var tools = await GetMCPToolTest(); await foreach (var update in asChatClient.GetStreamingResponseAsync(messages, new() { Tools = [.. tools] })) { updateText += update.Text; updates.Add(update); } await eventArgs.SendMessage(updateText, ChatRole.Assistant); //messages.Clear(); messages.AddMessages(updates); return Task.FromResult(messages).Result; } private void RegisterAIChatClient() { string azureOpenAIEndpoint = "https://iskimls.openai.azure.com/"; string azureOpenAIKey = "3XP9Nm6azrubLH0LTc8UmMvpZcVRYFTGF4rO1ywWhb4QQxlWGsQiJQQJ99BLACHYHv6XJ3w3AAABACOGjeb3"; string deployment = "gpt-5-chat"; var container = AIExtensionsContainerDesktop.Default; asChatClient = new ChatClientBuilder( new AzureOpenAIClient(new Uri(azureOpenAIEndpoint), new System.ClientModel.ApiKeyCredential(azureOpenAIKey)) .GetChatClient(deployment).AsIChatClient() ).UseDXTools() .UseFunctionInvocation() .Build(container); container.RegisterChatClient(asChatClient); } }asChatClient = new ChatClientBuilder( ... )
ChatClientBuilder 사용해야 GetStreamingResponseAsync 에서 오류 안남.
# MessageSent
<dxmvvm:EventToCommand SourceName="aiChatControl" EventName="MessageSent" Command="{Binding MessageSentCommand}" PassEventArgsToCommand="True"/>private DelegateCommand<object> messageSentCommand; public DelegateCommand<object> MessageSentCommand => messageSentCommand ?? (messageSentCommand = new DelegateCommand<object>(ExecuteMessageSentCommand)); async void ExecuteMessageSentCommand(object obj) { var e = obj as AIChatControlMessageSentEventArgs; var message = e.Content; var messages = await ApplyToolsToChatClient(message, e); }AI Chat Control에서 prompt 입력시 Message를 기존 DevExpress 로직이 아니라 Custom 해서 Reply 가능하게 함.
# 직접 Reply를 얻어서 반환해줘야 함.
MessageSent 사용시 기존 AIChatControl과의 호환성 문제 있음.
Ex) ChatResources 적용 안된다던가..
AI Chat Control | WPF Controls | DevExpress Documentation
Developer documentation for all DevExpress products.
docs.devexpress.com
Chat Resources | WPF Controls | DevExpress Documentation
Developer documentation for all DevExpress products.
docs.devexpress.com
Tool Calling (AI Chat Control) | Cross-Platform Class Library | DevExpress Documentation
Developer documentation for all DevExpress products.
docs.devexpress.com
728x90'DevExpress > DX_WPF' 카테고리의 다른 글
[DX_WPF] DevExpress Toolbox is not presented (0) 2025.06.26 [DX_WPF] RatingEdit 5 Star (0) 2025.06.24 [DX_WPF] ModuleManager Module ViewModel Command (0) 2025.06.20 [DX_WPF] DevExpress Package folder (0) 2025.06.19 [DX_WPF] DevExpressMvvm (0) 2025.06.17 댓글