Business Central (Part 28)
Neil Haddley • May 24, 2024
Prompt Dialog (Part 2)
I connected the Business Central PromptDialog to Azure OpenAI, so the Copilot generates real AI responses rather than static text. The RunGeneration procedure calls Azure OpenAI's chat completions API and returns the model's output to the Output field.

I updated the LLM Prompt Dialog page

Output is generated by a Large Language Model and returned to the user

I updated the RunGeneration procedure

For more detail please see this blog page.

I updated the "publisher" property

I found the Copilot & agent capabilities page in Business Central

The LLM Capability appeared in the list
Pag50100.LLM.al updated
AL
1namespace LLM.LLM; 2 3using System.AI; 4 5enumextension 50100 LLM extends "Copilot Capability" 6{ 7 value(50100; "LLM") { } 8} 9 10page 50100 LLM 11{ 12 ApplicationArea = All; 13 Caption = 'LLM'; 14 PageType = PromptDialog; 15 Extensible = false; 16 DataCaptionExpression = Prompt; 17 IsPreview = true; 18 19 layout 20 { 21 #region input section 22 area(Prompt) 23 { 24 field(PromptField; Prompt) 25 { 26 ShowCaption = false; 27 MultiLine = true; 28 InstructionalText = 'Message Large Language Model'; 29 } 30 } 31 #endregion 32 33 #region output section 34 area(Content) 35 { 36 field(OutputFiled; Output) 37 { 38 ShowCaption = false; 39 MultiLine = true; 40 } 41 } 42 #endregion 43 } 44 actions 45 { 46 #region prompt guide 47 area(PromptGuide) 48 { 49 action("Capital City") 50 { 51 ApplicationArea = All; 52 Caption = 'Capital City'; 53 ToolTip = 'What is the Capital of ...'; 54 55 trigger OnAction() 56 begin 57 Prompt := 'What is the Capital of <Country>?'; 58 end; 59 } 60 } 61 #endregion 62 63 #region system actions 64 area(SystemActions) 65 { 66 systemaction(Generate) 67 { 68 Caption = 'Generate'; 69 ToolTip = 'Generate a response.'; 70 71 trigger OnAction() 72 begin 73 RunGeneration(); 74 end; 75 } 76 systemaction(OK) 77 { 78 Caption = 'OK'; 79 ToolTip = 'Save the result.'; 80 } 81 systemaction(Cancel) 82 { 83 Caption = 'Cancel'; 84 ToolTip = 'Discard the result.'; 85 } 86 systemaction(Regenerate) 87 { 88 Caption = 'Regenerate'; 89 ToolTip = 'Regenerate a response.'; 90 91 trigger OnAction() 92 begin 93 RunGeneration(); 94 end; 95 } 96 #endregion 97 } 98 } 99 var 100 Prompt: Text; 101 Output: Text; 102 103 104 local procedure RunGeneration() 105 var 106 CopilotCapability: Codeunit "Copilot Capability"; 107 AzureOpenAI: Codeunit "Azure OpenAI"; 108 AOAIDeployments: Codeunit "AOAI Deployments"; 109 AOAIChatCompletionParams: Codeunit "AOAI Chat Completion Params"; 110 AOAIChatMessages: Codeunit "AOAI Chat Messages"; 111 AOAIOperationResponse: Codeunit "AOAI Operation Response"; 112 UserMessage: TextBuilder; 113 begin 114 115 if not CopilotCapability.IsCapabilityRegistered(Enum::"Copilot Capability"::LLM) then 116 CopilotCapability.RegisterCapability(Enum::"Copilot Capability"::LLM, 'https://about:none'); 117 118 AzureOpenAI.SetAuthorization(Enum::"AOAI Model Type"::"Chat Completions", GetEndpoint(), GetDeployment(), GetApiKey()); 119 AzureOpenAI.SetCopilotCapability(Enum::"Copilot Capability"::LLM); 120 121 AOAIChatCompletionParams.SetMaxTokens(2500); 122 AOAIChatCompletionParams.SetTemperature(0); 123 AOAIChatMessages.AddUserMessage(Prompt); 124 125 AzureOpenAI.GenerateChatCompletion(AOAIChatMessages, AOAIChatCompletionParams, AOAIOperationResponse); 126 if (AOAIOperationResponse.IsSuccess()) then 127 Output := AOAIChatMessages.GetLastMessage() 128 else 129 Output := ('Error: ' + AOAIOperationResponse.GetError()); 130 131 end; 132 133 134 local procedure GetEndpoint(): Text 135 var 136 begin 137 exit('https://haddley-ai.openai.azure.com'); 138 end; 139 140 local procedure GetDeployment(): Text 141 var 142 begin 143 exit('gpt-4o'); 144 end; 145 146 [NonDebuggable] 147 local procedure GetApiKey(): Text //SecretText 148 var 149 begin 150 exit('12345678901234567890123456789012'); 151 end; 152 153 154 155}