windowsforms-405336-ai-powered-extensions-custom-ai-powered-extensions.md
The following example creates a custom AI-powered extension (“AuthoredStyleExtension”) and integrates it into the DevExpress Rich Text Editor.
See the following help topic for information on required NuGet packages and system requirements: Register an AI Client.
The following code snippet registers the Azure OpenAI client:
using Microsoft.Extensions.AI;
using DevExpress.AIIntegration;
internal static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
IChatClient azureChatClient = new Azure.AI.OpenAI.AzureOpenAIClient(new Uri(AzureOpenAIEndpoint),
new System.ClientModel.ApiKeyCredential(AzureOpenAIKey))
.GetChatClient(ModelId).AsIChatClient();
AIExtensionsContainerDesktop.Default.RegisterChatClient(azureChatClient);
// Uncomment the following line if your project targets the .NET Framework and
// you create AI-powered behaviors in code.
// DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize();
Application.Run(new Form1());
}
static string AzureOpenAIEndpoint { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT"); } }
static string AzureOpenAIKey { get { return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY"); } }
static string ModelId { get { return "MODEL_NAME"; } }
}
Imports Microsoft.Extensions.AI
Imports DevExpress.AIIntegration
Friend Module Program
<STAThread>
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
' Register Azure.OpenAI
Dim azureChatClient As IChatClient = New Azure.AI.OpenAI.AzureOpenAIClient(New Uri(AzureOpenAIEndpoint),
New System.ClientModel.ApiKeyCredential(AzureOpenAIKey)).
GetChatClient(ModelId).AsIChatClient()
AIExtensionsContainerDesktop.Default.RegisterChatClient(azureChatClient)
' Uncomment the following line if your project targets the .NET Framework and
' you create AI-powered behaviors in code.
' DevExpress.AIIntegration.WinForms.BehaviorInitializer.Initialize()
Application.Run(New Form1())
End Sub
Private ReadOnly Property AzureOpenAIEndpoint() As String
Get
Return Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
End Get
End Property
Private ReadOnly Property AzureOpenAIKey() As String
Get
Return Environment.GetEnvironmentVariable("AZURE_OPENAI_APIKEY")
End Get
End Property
Private ReadOnly Property ModelId As String
Get
Return "MODEL_NAME"
End Get
End Property
End Module
The AuthoredStyleExtension is based on the DevExpress ChangeStyleExtension. The example overrides the GetSystemPrompt method to customize the prompt:
using DevExpress.AIIntegration.Extensions;
public class AuthoredStyleExtension : ChangeTextExtension<AuthoredStyleRequest> {
public AuthoredStyleExtension(IServiceProvider serviceProvider) : base(serviceProvider) { }
protected override string GetSystemPrompt(AuthoredStyleRequest request) {
return String.Format("Rewrite this text in the {0} style", request.Author);
}
}
public class AuthoredStyleRequest : TextRequest {
public AuthoredStyleRequest(string Author, string Text) : base(Text) {
this.Author = Author;
}
public string Author { get; set; }
}
Register the AuthoredStyleExtension and handle the RichEditControl.PopupMenuShowing event to display a submenu (“Authored Style”) in the popup menu:
using DevExpress.AIIntegration;
using DevExpress.AIIntegration.WinForms;
using DevExpress.Utils.Menu;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraRichEdit.API.Native;
public partial class Form1 : RibbonForm {
public Form1() {
InitializeComponent();
var defaultContainer = AIExtensionsContainerDesktop.Default;
defaultContainer.Register<AuthoredStyleRequest, AuthoredStyleExtension>();
string menuCaption = "Authored Style";
richEditControl.PopupMenuShowing += (s, e) => {
var menuItem = e.Menu.Items.FirstOrDefault(x => x.Caption == menuCaption) as DXSubMenuItem;
if (menuItem == null) {
menuItem = new DXSubMenuItem(menuCaption);
string[] authors = ["Mark Twain", "Ernest Hemingway", "Maya Angelou"];
foreach (string author in authors) {
menuItem.Items.Add(new DXMenuItem(author, async (ss, ee) => {
var extension = (AuthoredStyleExtension)defaultContainer.GetExtension(typeof(AuthoredStyleRequest));
DocumentRange selection = richEditControl.Document.Selection;
var request = new AuthoredStyleRequest(author, richEditControl.Document.GetText(selection));
string result = await AIOverlayForm.Execute(richEditControl, extension, request);
richEditControl.Document.Replace(selection, result);
}));
}
e.Menu.Items.Add(menuItem);
}
};
}
}
Run Demo: Create Custom Extension in MemoEdit
See Also