generated from microsoft/AL-Go-PTE-Preview
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
46 changed files
with
3,101 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
namespace DefaultPublisher.DraftProject; | ||
using System.AI; | ||
|
||
page 50100 "Draft Project" | ||
{ | ||
PageType = PromptDialog; | ||
ApplicationArea = All; | ||
Caption = 'Draft with Copilot'; | ||
PromptMode = Prompt; | ||
Extensible = false; | ||
|
||
layout | ||
{ | ||
area(Prompt) | ||
{ | ||
field(ProjectDescriptionField; InputProjectDescription) | ||
{ | ||
ShowCaption = false; | ||
MultiLine = true; | ||
InstructionalText = 'Please describe the project or work to be done that needs to be converted into tasks'; | ||
} | ||
} | ||
|
||
area(PromptOptions) | ||
{ | ||
// In PromptDialog pages, you can define a PromptOptions area. Here you can add different settings to tweak the output that Copilot will generate. | ||
// These settings must be defined as page fields, and must be of type Option or Enum. You cannot define groups in this area. | ||
} | ||
|
||
area(Content) | ||
{ | ||
field("Project Tasks"; OutputProjectTasks) | ||
{ | ||
MultiLine = true; | ||
ExtendedDatatype = RichContent; | ||
Editable = false; | ||
} | ||
} | ||
} | ||
|
||
actions | ||
{ | ||
area(SystemActions) | ||
{ | ||
systemaction(Generate) | ||
{ | ||
trigger OnAction() | ||
var | ||
SystemPrompt: Text; | ||
begin | ||
SystemPrompt := 'The user will describe a project. Your task is to prepare the project plan for this project to be used in Microsoft Dynamics 365 Business Central.' | ||
+ 'The output should be html formatted bulleted list. ' | ||
+ 'Generate at least 6 tasks.' | ||
+ 'Order the tasks in order of execution.' | ||
+ 'If a task needs an item format the item name with bold.' | ||
+ 'Add relevant emoji to each task.' | ||
+ 'If a tasks needs a person format task with underline.'; | ||
|
||
OutputProjectTasks := CreateSuggestion(SystemPrompt, InputProjectDescription); | ||
end; | ||
} | ||
} | ||
area(PromptGuide) | ||
{ | ||
action("AOrganizeEvent") | ||
{ | ||
Caption = 'Organize an event'; | ||
trigger OnAction() | ||
begin | ||
InputProjectDescription += 'Plan for organizing a <project name> for the attendees of <event name>'; | ||
end; | ||
} | ||
} | ||
} | ||
|
||
var | ||
InputProjectDescription: Text; | ||
OutputProjectTasks: Text; | ||
|
||
local procedure CreateSuggestion(SystemPrompt: Text; ProjectDescription: Text): Text | ||
var | ||
CopilotCapability: Codeunit "Copilot Capability"; | ||
AzureOpenAI: Codeunit "Azure OpenAI"; | ||
AOAIDeployments: Codeunit "AOAI Deployments"; | ||
AOAIChatCompletionParams: Codeunit "AOAI Chat Completion Params"; | ||
AOAIChatMessages: Codeunit "AOAI Chat Messages"; | ||
AOAIOperationResponse: Codeunit "AOAI Operation Response"; | ||
begin | ||
if not CopilotCapability.IsCapabilityRegistered(Enum::"Copilot Capability"::"Project Task Creation") then | ||
CopilotCapability.RegisterCapability(Enum::"Copilot Capability"::"Project Task Creation", 'https://about:none'); | ||
|
||
// If you are using managed resources, call this function: | ||
// NOTE: endpoint, deployment, and key are only used to verify that you have a valid Azure OpenAI subscription; we don't use them to generate the result | ||
AzureOpenAI.SetManagedResourceAuthorization(Enum::"AOAI Model Type"::"Chat Completions", | ||
GetEndpoint(), GetDeployment(), GetApiKey(), AOAIDeployments.GetGPT4oLatest()); | ||
// If you are using your own Azure OpenAI subscription, call this function instead: | ||
// AzureOpenAI.SetAuthorization(Enum::"AOAI Model Type"::"Chat Completions", GetEndpoint(), GetDeployment(), GetApiKey()); | ||
AzureOpenAI.SetCopilotCapability(Enum::"Copilot Capability"::"Project Task Creation"); | ||
|
||
AOAIChatCompletionParams.SetMaxTokens(2500); | ||
AOAIChatCompletionParams.SetTemperature(0); | ||
|
||
AOAIChatMessages.AddSystemMessage(SystemPrompt); | ||
AOAIChatMessages.AddUserMessage(ProjectDescription); | ||
|
||
AzureOpenAI.GenerateChatCompletion(AOAIChatMessages, AOAIChatCompletionParams, AOAIOperationResponse); | ||
if (AOAIOperationResponse.IsSuccess()) then | ||
exit(AOAIChatMessages.GetLastMessage()); | ||
|
||
exit('Error: ' + AOAIOperationResponse.GetError()); | ||
end; | ||
|
||
local procedure GetApiKey(): SecretText | ||
begin | ||
// Use your Azure Open AI secret key. | ||
// NOTE: Do not add the key in plain text. Instead, use Isolated Storage or other more secure ways. | ||
exit(Format(CreateGuid())); | ||
end; | ||
|
||
local procedure GetDeployment(): Text | ||
begin | ||
// Use your deployment name from Azure Open AI here | ||
exit('gpt-' + CreateGuid()); | ||
end; | ||
|
||
local procedure GetEndpoint(): Text | ||
begin | ||
// Use your endpoint name from Azure Open AI here | ||
exit('https://my-deployment.azure.com/'); | ||
end; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace DefaultPublisher.DraftProject; | ||
using System.AI; | ||
|
||
enumextension 50110 "MyCapability" extends "Copilot Capability" | ||
{ | ||
value(50110; "Project Task Creation") { } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
namespace DefaultPublisher.DraftProject; | ||
using Microsoft.Projects.Project.Job; | ||
|
||
pageextension 50100 ProjectListExtension extends "Job List" | ||
{ | ||
actions | ||
{ | ||
addfirst(Prompting) | ||
{ | ||
action("DraftWithCopilot") | ||
{ | ||
ApplicationArea = All; | ||
Caption = 'Draft with Copilot'; | ||
|
||
RunObject = Page "Draft Project"; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"id": "0a1bc520-b532-4486-9db2-337d046b5e64", | ||
"name": "1-GetStarted Demo", | ||
"publisher": "Copilot Toolkit Demo", | ||
"version": "0.1.0.0", | ||
"brief": "", | ||
"description": "", | ||
"privacyStatement": "", | ||
"EULA": "", | ||
"help": "", | ||
"url": "", | ||
"logo": "", | ||
"dependencies": [], | ||
"screenshots": [], | ||
"platform": "24.0.0.0", | ||
"application": "24.0.0.0", | ||
"idRanges": [ | ||
{ | ||
"from": 50100, | ||
"to": 50149 | ||
} | ||
], | ||
"resourceExposurePolicy": { | ||
"allowDebugging": true, | ||
"allowDownloadingSource": true, | ||
"includeSourceInSymbolFile": true | ||
}, | ||
"runtime": "14.0", | ||
"features": [ | ||
"NoImplicitWith" | ||
] | ||
} |
146 changes: 146 additions & 0 deletions
146
2-ItemSubstitution/CopilotCodeunits/GenerateItemSubProposal.Codeunit.al
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
namespace CopilotToolkitDemo.ItemSubstitution; | ||
|
||
using System.IO; | ||
using Microsoft.Inventory.Item; | ||
using System.Environment; | ||
using System.AI; | ||
using System.Utilities; | ||
|
||
codeunit 54323 "Generate Item Sub Proposal" | ||
{ | ||
trigger OnRun() | ||
begin | ||
GenerateItemProposal(); | ||
end; | ||
|
||
procedure SetUserPrompt(InputUserPrompt: Text) | ||
begin | ||
UserPrompt := InputUserPrompt; | ||
end; | ||
|
||
procedure GetResult(var TmpItemSubstAIProposal2: Record "Copilot Item Sub Proposal" temporary) | ||
begin | ||
TmpItemSubstAIProposal2.Copy(TmpItemSubstAIProposal, true); | ||
end; | ||
|
||
local procedure GenerateItemProposal() | ||
var | ||
TmpXmlBuffer: Record "XML Buffer" temporary; | ||
TempBlob: Codeunit "Temp Blob"; | ||
InStr: InStream; | ||
OutStr: OutStream; | ||
CurrInd, LineNo : Integer; | ||
DateVar: Date; | ||
TmpText: Text; | ||
begin | ||
TempBlob.CreateOutStream(OutStr); | ||
TmpText := Chat(GetSystemPrompt(), GetFinalUserPrompt(UserPrompt)); | ||
OutStr.WriteText(TmpText); | ||
TempBlob.CreateInStream(InStr); | ||
|
||
TmpXmlBuffer.DeleteAll(); | ||
TmpXmlBuffer.LoadFromStream(InStr); | ||
|
||
Clear(OutStr); | ||
LineNo := 10000; | ||
if TmpXmlBuffer.FindSet() then | ||
repeat | ||
case TmpXmlBuffer.Path of | ||
'/items/item': | ||
TmpItemSubstAIProposal.Init(); | ||
'/items/item/number': | ||
begin | ||
TmpItemSubstAIProposal."No." := UpperCase(CopyStr(TmpXmlBuffer.GetValue(), 1, MaxStrLen(TmpItemSubstAIProposal."No."))); | ||
TmpItemSubstAIProposal.Insert(); | ||
end; | ||
'/items/item/description': | ||
begin | ||
TmpItemSubstAIProposal.Description := CopyStr(TmpXmlBuffer.GetValue(), 1, MaxStrLen(TmpItemSubstAIProposal.Description)); | ||
TmpItemSubstAIProposal.Modify(); | ||
end; | ||
'/items/item/explanation': | ||
begin | ||
TmpItemSubstAIProposal.Explanation := CopyStr(TmpXmlBuffer.GetValue(), 1, MaxStrLen(TmpItemSubstAIProposal.Explanation)); | ||
TmpItemSubstAIProposal."Full Explanation".CreateOutStream(OutStr); | ||
OutStr.WriteText(TmpXmlBuffer.GetValue()); | ||
TmpItemSubstAIProposal.Modify(); | ||
end; | ||
end; | ||
until TmpXmlBuffer.Next() = 0; | ||
end; | ||
|
||
procedure Chat(ChatSystemPrompt: Text; ChatUserPrompt: Text): Text | ||
var | ||
AzureOpenAI: Codeunit "Azure OpenAI"; | ||
EnvironmentInformation: Codeunit "Environment Information"; | ||
AOAIOperationResponse: Codeunit "AOAI Operation Response"; | ||
AOAIChatCompletionParams: Codeunit "AOAI Chat Completion Params"; | ||
AOAIChatMessages: Codeunit "AOAI Chat Messages"; | ||
AOAIDeployments: Codeunit "AOAI Deployments"; | ||
IsolatedStorageWrapper: Codeunit "Isolated Storage Wrapper"; | ||
Result: Text; | ||
EntityTextModuleInfo: ModuleInfo; | ||
begin | ||
// If you are using managed resources, call this function: | ||
// NOTE: endpoint, deployment, and key are only used to verify that you have a valid Azure OpenAI subscription; we don't use them to generate the result | ||
AzureOpenAI.SetManagedResourceAuthorization(Enum::"AOAI Model Type"::"Chat Completions", | ||
IsolatedStorageWrapper.GetEndpoint(), IsolatedStorageWrapper.GetDeployment(), IsolatedStorageWrapper.GetSecretKey(), AOAIDeployments.GetGPT4oLatest()); | ||
// If you are using your own Azure OpenAI subscription, call this function instead: | ||
// AzureOpenAI.SetAuthorization(Enum::"AOAI Model Type"::"Chat Completions", IsolatedStorageWrapper.GetEndpoint(), IsolatedStorageWrapper.GetDeployment(), IsolatedStorageWrapper.GetSecretKey()); | ||
|
||
AzureOpenAI.SetCopilotCapability(Enum::"Copilot Capability"::"Find Item Substitutions"); | ||
|
||
AOAIChatCompletionParams.SetMaxTokens(2500); | ||
AOAIChatCompletionParams.SetTemperature(0); | ||
|
||
AOAIChatMessages.AddSystemMessage(ChatSystemPrompt); | ||
AOAIChatMessages.AddUserMessage(ChatUserPrompt); | ||
|
||
AzureOpenAI.GenerateChatCompletion(AOAIChatMessages, AOAIChatCompletionParams, AOAIOperationResponse); | ||
|
||
if AOAIOperationResponse.IsSuccess() then | ||
Result := AOAIChatMessages.GetLastMessage() | ||
else | ||
Error(AOAIOperationResponse.GetError()); | ||
|
||
Result := Result.Replace('&', '&'); | ||
Result := Result.Replace('"', ''); | ||
Result := Result.Replace('''', ''); | ||
|
||
exit(Result); | ||
end; | ||
|
||
local procedure GetFinalUserPrompt(InputUserPrompt: Text) FinalUserPrompt: Text | ||
var | ||
Item: Record Item; | ||
Newline: Char; | ||
begin | ||
Newline := 10; | ||
FinalUserPrompt := 'These are the available items:' + Newline; | ||
if Item.FindSet() then | ||
repeat | ||
FinalUserPrompt += | ||
'Number: ' + Item."No." + ', ' + | ||
'Description:' + Item.Description + '.' + Newline; | ||
until Item.Next() = 0; | ||
|
||
FinalUserPrompt += Newline; | ||
FinalUserPrompt += StrSubstNo('The description of the item that needs to be substituted is: %1.', InputUserPrompt); | ||
end; | ||
|
||
local procedure GetSystemPrompt() SystemPrompt: Text | ||
var | ||
Item: Record Item; | ||
begin | ||
SystemPrompt += 'The user will provide an item description, and a list of other items. Your task is to find items that can substitute that item.'; | ||
SystemPrompt += 'Try to suggest several relevant items if possible.'; | ||
SystemPrompt += 'The output should be in xml, containing item number (use number tag), item description (use description tag), and explanation why this item was suggested (use explanation tag).'; | ||
SystemPrompt += 'Use items as a root level tag, use item as item tag.'; | ||
SystemPrompt += 'Do not use line breaks or other special characters in explanation.'; | ||
SystemPrompt += 'Skip empty nodes.'; | ||
end; | ||
|
||
var | ||
TmpItemSubstAIProposal: Record "Copilot Item Sub Proposal" temporary; | ||
UserPrompt: Text; | ||
} |
32 changes: 32 additions & 0 deletions
32
2-ItemSubstitution/CopilotCodeunits/SecretsAndCapabilitiesSetup.Codeunit.al
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
namespace CopilotToolkitDemo.ItemSubstitution; | ||
|
||
using System.AI; | ||
|
||
codeunit 54310 "Secrets And Capabilities Setup" | ||
{ | ||
Subtype = Install; | ||
InherentEntitlements = X; | ||
InherentPermissions = X; | ||
Access = Internal; | ||
|
||
trigger OnInstallAppPerDatabase() | ||
begin | ||
RegisterCapability(); | ||
end; | ||
|
||
local procedure RegisterCapability() | ||
var | ||
CopilotCapability: Codeunit "Copilot Capability"; | ||
IsolatedStorageWrapper: Codeunit "Isolated Storage Wrapper"; | ||
LearnMoreUrlTxt: Label 'https://example.com/CopilotToolkit', Locked = true; | ||
begin | ||
if not CopilotCapability.IsCapabilityRegistered(Enum::"Copilot Capability"::"Find Item Substitutions") then | ||
CopilotCapability.RegisterCapability(Enum::"Copilot Capability"::"Find Item Substitutions", Enum::"Copilot Availability"::Preview, LearnMoreUrlTxt); | ||
|
||
// You will need to use your own key for Azure OpenAI for all your Copilot features (for both development and production). | ||
Error('Set up your secrets here before publishing the app.'); | ||
// IsolatedStorageWrapper.SetSecretKey(''); | ||
// IsolatedStorageWrapper.SetDeployment(''); | ||
// IsolatedStorageWrapper.SetEndpoint(''); | ||
end; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace CopilotToolkitDemo.ItemSubstitution; | ||
|
||
permissionset 54300 CopilotSample | ||
{ | ||
Assignable = true; | ||
Permissions = tabledata "Copilot Item Sub Proposal" = RIMD, | ||
table "Copilot Item Sub Proposal" = X, | ||
codeunit "Generate Item Sub Proposal" = X, | ||
codeunit "Isolated Storage Wrapper" = X, | ||
codeunit "Secrets And Capabilities Setup" = X, | ||
page "Copilot Item Sub Proposal" = X, | ||
page "Copilot Item Subs Proposal Sub" = X; | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.