Custom AI-powered Extensions
- 3 minutes to read
The following example creates a custom AI-powered extension (“AuthoredStyleExtension”) and integrates it into the DevExpress Rich Text Editor.
Register AI Client
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 "gpt-4o-mini"; } }
}
Create an Extension
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; }
}
Integrate an AI-powered Extension into a Rich Text Editor
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);
}
};
}
}
See Also