Skip to content

Commit

Permalink
Merge branch 'main' into private/mattinielsen/fix-metadata-generation…
Browse files Browse the repository at this point in the history
…-bug-2
  • Loading branch information
DenLilleMand committed Sep 18, 2024
2 parents 962dca4 + 995ab07 commit f36255b
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/AL-Go-Settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"runs-on": "windows-latest",
"cacheImageName": "",
"UsePsSession": false,
"artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/26.0.24149.0/base",
"artifact": "https://bcinsider-fvh2ekdjecfjd6gk.b02.azurefd.net/sandbox/26.0.24318.0/base",
"country": "base",
"useProjectDependencies": true,
"repoVersion": "26.0",
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/MSDO.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ jobs:
tools: credscan

- name: Upload results to Security tab
uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6
uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
with:
sarif_file: ${{ steps.credscan.outputs.sarifFile }}
2 changes: 1 addition & 1 deletion .github/workflows/powershell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ jobs:

# Upload the SARIF file generated in the previous step
- name: Upload SARIF results file
uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v3.26.6
uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v3.26.7
with:
sarif_file: results.sarif
2 changes: 1 addition & 1 deletion .github/workflows/scorecard-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ jobs:
results_format: sarif

- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # v2.16.4
uses: github/codeql-action/upload-sarif@8214744c546c1e5c8f03dde8fab3a7353211988d # v2.16.4
with:
sarif_file: results.sarif
4 changes: 2 additions & 2 deletions build/Packages.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"Microsoft.Dynamics.BusinessCentral.Translations": {
"Version": "26.0.20240902.5",
"Version": "26.0.20240916.5",
"Source": "NuGet.org"
},
"AppBaselines-BCArtifacts": {
"Version": "25.1.24147.0",
"Version": "25.1.24274.0",
"Source": "BCArtifacts",
"_comment": "Used to fetch app baselines from BC artifacts"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ codeunit 324 "No. Series Copilot Impl."

var
IncorrectCompletionErr: Label 'Incorrect completion. The property %1 is empty', Comment = '%1 = property name';
EmptyCompletionErr: Label 'Incorrect completion. The completion is empty.';
IncorrectCompletionNumberOfGeneratedNoSeriesErr: Label 'Incorrect completion. The number of generated number series is incorrect. Expected %1, but got %2', Comment = '%1 = Expected Number, %2 = Actual Number';
TextLengthIsOverMaxLimitErr: Label 'The property %1 exceeds the maximum length of %2', Comment = '%1 = property name, %2 = maximum length';
DateSpecificPlaceholderLbl: Label '{current_date}', Locked = true;
Expand Down Expand Up @@ -68,6 +69,7 @@ codeunit 324 "No. Series Copilot Impl."

procedure ApplyGeneratedNoSeries(var GeneratedNoSeries: Record "No. Series Generation Detail")
begin
GeneratedNoSeries.SetRange(Exists, false);
if GeneratedNoSeries.FindSet() then
repeat
InsertNoSeriesWithLines(GeneratedNoSeries);
Expand Down Expand Up @@ -189,13 +191,13 @@ codeunit 324 "No. Series Copilot Impl."
CompletionAnswerTxt := AOAIChatMessages.GetLastMessage(); // the model can answer to rephrase the question, if the user input is not clear

if AOAIOperationResponse.IsFunctionCall() then
CompletionAnswerTxt := GenerateNoSeriesUsingToolResult(AzureOpenAI, InputText, AOAIOperationResponse);
CompletionAnswerTxt := GenerateNoSeriesUsingToolResult(AzureOpenAI, InputText, AOAIOperationResponse, AddNoSeriesIntent.GetExistingNoSeries());

exit(CompletionAnswerTxt);
end;

[NonDebuggable]
local procedure GenerateNoSeriesUsingToolResult(var AzureOpenAI: Codeunit "Azure OpenAI"; InputText: Text; var AOAIOperationResponse: Codeunit "AOAI Operation Response"): Text
local procedure GenerateNoSeriesUsingToolResult(var AzureOpenAI: Codeunit "Azure OpenAI"; InputText: Text; var AOAIOperationResponse: Codeunit "AOAI Operation Response"; ExistingNoSeriesArray: Text): Text
var
AOAIChatCompletionParams: Codeunit "AOAI Chat Completion Params";
AOAIChatMessages: Codeunit "AOAI Chat Messages";
Expand All @@ -209,6 +211,9 @@ codeunit 324 "No. Series Copilot Impl."
FunctionResponses: List of [Codeunit "AOAI Function Response"];
Progress: Dialog;
begin
if ExistingNoSeriesArray <> '' then
FinalResults.Add(ExistingNoSeriesArray);

FunctionResponses := AOAIOperationResponse.GetFunctionResponses();

foreach AOAIFunctionResponse in FunctionResponses do begin
Expand Down Expand Up @@ -237,7 +242,6 @@ codeunit 324 "No. Series Copilot Impl."
Progress.Close();
end;
end;

exit(ConcatenateToolResponse(FinalResults));
end;

Expand Down Expand Up @@ -337,6 +341,7 @@ codeunit 324 "No. Series Copilot Impl."
begin
ReadGeneratedNumberSeriesJArray(GeneratedNoSeriesArrayText).WriteTo(NoSeriesArrText);
Json.InitializeCollection(NoSeriesArrText);
CheckIfArrayIsNotEmpty(Json.GetCollectionCount());

for i := 0 to Json.GetCollectionCount() - 1 do begin
Json.GetObjectFromCollectionByIndex(i, NoSeriesObj);
Expand All @@ -356,6 +361,12 @@ codeunit 324 "No. Series Copilot Impl."
end;
end;

local procedure CheckIfArrayIsNotEmpty(NumberOfGeneratedNoSeries: Integer)
begin
if NumberOfGeneratedNoSeries = 0 then
Error(EmptyCompletionErr);
end;

local procedure CheckTextPropertyExistAndCheckIfNotEmpty(propertyName: Text; var Json: Codeunit Json)
var
value: Text;
Expand Down Expand Up @@ -420,47 +431,32 @@ codeunit 324 "No. Series Copilot Impl."
var
Json: Codeunit Json;
i: Integer;
NoSeriesObj: Text;
NoSeriesCodes: List of [Text];
NoSeriesCode: Text;
begin
Json.InitializeCollection(NoSeriesArrText);

for i := 0 to Json.GetCollectionCount() - 1 do begin
Json.GetObjectFromCollectionByIndex(i, NoSeriesObj);
Json.InitializeObject(NoSeriesObj);
Json.GetStringPropertyValueByName('seriesCode', NoSeriesCode);
if NoSeriesCodes.Contains(NoSeriesCode) then begin
Json.ReplaceOrAddJPropertyInJObject('seriesCode', GenerateNewSeriesCodeValue(NoSeriesCodes, NoSeriesCode));
NoSeriesObj := Json.GetObjectAsText();
Json.ReplaceJObjectInCollection(i, NoSeriesObj);
end;
NoSeriesCodes.Add(NoSeriesCode);
end;
for i := 0 to Json.GetCollectionCount() - 1 do
ProcessNoSeries(i, NoSeriesCodes, Json);

NoSeriesArrText := Json.GetCollectionAsText()
end;

local procedure GenerateNewSeriesCodeValue(var NoSeriesCodes: List of [Text]; var NoSeriesCode: Text): Text
local procedure ProcessNoSeries(i: Integer; var NoSeriesCodes: List of [Text]; var Json: Codeunit Json)
var
NewNoSeriesCode: Text;
begin
repeat
NewNoSeriesCode := CopyStr(NoSeriesCode, 1, 18) + '-' + RandomCharacter();
until not NoSeriesCodes.Contains(NewNoSeriesCode);

NoSeriesCode := NewNoSeriesCode;
exit(NewNoSeriesCode);
end;

local procedure RandomCharacter(): Char
NoSeriesCode: Text;
NoSeriesObj: Text;
IsExists: Boolean;
begin
exit(RandIntInRange(33, 126)); // ASCII: ! (33) to ~ (126)
end;
Json.GetObjectFromCollectionByIndex(i, NoSeriesObj);
Json.InitializeObject(NoSeriesObj);
Json.GetBoolPropertyValueFromJObjectByName('exists', IsExists);
Json.GetStringPropertyValueByName('seriesCode', NoSeriesCode);

local procedure RandIntInRange(MinInt: Integer; MaxInt: Integer): Integer
begin
exit(MinInt - 1 + Random(MaxInt - MinInt + 1));
if NoSeriesCodes.Contains(NoSeriesCode) and (not IsExists) then begin
Json.RemoveJObjectFromCollection(i);
exit;
end;
NoSeriesCodes.Add(NoSeriesCode);
end;

local procedure InsertGeneratedNoSeries(var GeneratedNoSeries: Record "No. Series Generation Detail"; NoSeriesObj: Text; GenerationNo: Integer)
Expand All @@ -482,7 +478,9 @@ codeunit 324 "No. Series Copilot Impl."
Json.GetValueAndSetToRecFieldNo(RecRef, 'tableId', GeneratedNoSeries.FieldNo("Setup Table No."));
Json.GetValueAndSetToRecFieldNo(RecRef, 'fieldId', GeneratedNoSeries.FieldNo("Setup Field No."));
Json.GetValueAndSetToRecFieldNo(RecRef, 'nextYear', GeneratedNoSeries.FieldNo("Is Next Year"));
RecRef.Insert(true);
Json.GetValueAndSetToRecFieldNo(RecRef, 'exists', GeneratedNoSeries.FieldNo(Exists));
Json.GetValueAndSetToRecFieldNo(RecRef, 'message', GeneratedNoSeries.FieldNo(Message));
if RecRef.Insert(true) then;

ValidateGeneratedNoSeries(RecRef);
end;
Expand Down Expand Up @@ -528,7 +526,7 @@ codeunit 324 "No. Series Copilot Impl."

local procedure MaxModelTokens(): Integer
begin
exit(16385); //gpt-4o-mini-latest
exit(16385); //gpt-4o-latest
end;

procedure IsCopilotVisible(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace Microsoft.Foundation.NoSeries;

using System.Reflection;

table 392 "No. Series Generation Detail"
{
TableType = Temporary;
Expand Down Expand Up @@ -76,6 +78,28 @@ table 392 "No. Series Generation Detail"
{
Caption = 'Starting Date';
}
field(13; "Exists"; Boolean)
{
Caption = 'Exists';
}
field(14; Message; Text[1024])
{
Caption = 'Message';
}
field(20; "Setup Table Name"; Text[80])
{
Caption = 'Setup Table';
FieldClass = FlowField;
CalcFormula = lookup("Table Metadata".Caption where(ID = field("Setup Table No.")));
Editable = false;
}
field(21; "Setup Field Name"; Text[250])
{
Caption = 'Setup Field';
FieldClass = FlowField;
CalcFormula = lookup(Field."Field Caption" where(TableNo = field("Setup Table No."), "No." = field("Setup Field No.")));
Editable = false;
}
}

keys
Expand Down Expand Up @@ -129,4 +153,4 @@ table 392 "No. Series Generation Detail"

Rec."Starting Date" := CalcDate('<-CY+1Y>', Today);
end;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,41 +28,76 @@ page 333 "No. Series Generation Sub"
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Series Code field.';
Enabled = IsEnabled;
}
field(Description; Rec.Description)
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Description field.';
Enabled = IsEnabled;
}
field("Starting No."; Rec."Starting No.")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Starting No. field.';
Enabled = IsEnabled;
}
field("Increment-by No."; Rec."Increment-by No.")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Increment-by No. field.';
Enabled = IsEnabled;
}
field("Ending No."; Rec."Ending No.")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Ending No. field.';
Enabled = IsEnabled;
}
field("Warning No."; Rec."Warning No.")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Warning No. field.';
Enabled = IsEnabled;
}
field("Starting Date"; Rec."Starting Date")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Starting Date field.';
Enabled = IsEnabled;
}
field(Message; Rec.Message)
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Message field.';
Style = Attention;
Editable = false;
}
field("Setup Table Name"; Rec."Setup Table Name")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Setup Table Name field.';
Enabled = IsEnabled;
}
field("Setup Field Name"; Rec."Setup Field Name")
{
ApplicationArea = All;
ToolTip = 'Specifies the value of the Setup Field Name field.';
Enabled = IsEnabled;
}

}
}
}

var
IsEnabled: Boolean;

trigger OnAfterGetRecord()
begin
IsEnabled := not Rec.Exists;
end;

internal procedure Load(var GeneratedNoSeries: Record "No. Series Generation Detail")
begin
GeneratedNoSeries.Reset();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
AzureKeyVault: Codeunit "Azure Key Vault";
Telemetry: Codeunit Telemetry;
ToolsImpl: Codeunit "No. Series Cop. Tools Impl.";
ExistingNoSeriesJArr: JsonArray;
FunctionNameLbl: Label 'CreateNewNumberSeries', Locked = true;
DateSpecificPlaceholderLbl: Label '{current_date}', Locked = true;
CustomPatternsPlaceholderLbl: Label '{custom_patterns}', Locked = true;
Expand All @@ -28,6 +29,7 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
TelemetryTool1PromptRetrievalErr: Label 'Unable to retrieve the prompt for No. Series Copilot Tool 1 from Azure Key Vault.', Locked = true;
TelemetryTool1DefinitionRetrievalErr: Label 'Unable to retrieve the definition for No. Series Copilot Tool 1 from Azure Key Vault.', Locked = true;
ToolLoadingErr: Label 'Unable to load the No. Series Copilot Tool 1. Please try again later.';
ExistingNoSeriesMessageLbl: Label 'Number series already configured. If you wish to modify the existing series, please use the `Modify number series` prompt.';

procedure GetName(): Text
begin
Expand Down Expand Up @@ -148,8 +150,10 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
exit;

FieldRef := RecRef.Field(Field."No.");
if Format(FieldRef.Value) <> '' then
if Format(FieldRef.Value) <> '' then begin
SaveExistingNoSeries(TempTableMetadata, FieldRef);
exit; // No need to generate number series if it already created and configured
end;

TempSetupTable := TempTableMetadata;
if TempSetupTable.Insert() then;
Expand All @@ -158,6 +162,42 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
TempNoSeriesField.Insert();
end;

local procedure SaveExistingNoSeries(TempTableMetadata: Record "Table Metadata" temporary; FieldRef: FieldRef)
var
NoSeries: Record "No. Series";
NoSeriesLine: Record "No. Series Line";
NoSeriesManagement: Codeunit "No. Series";
ExistingNoSeriesJObj: JsonObject;
begin
if not NoSeries.Get(Format(FieldRef.Value)) then
exit;

NoSeriesManagement.GetNoSeriesLine(NoSeriesLine, NoSeries.Code, Today(), false);

Clear(ExistingNoSeriesJObj);
ExistingNoSeriesJObj.Add('seriesCode', NoSeries.Code);
ExistingNoSeriesJObj.Add('description', NoSeries.Description);
ExistingNoSeriesJObj.Add('startingNo', NoSeriesLine."Starting No.");
ExistingNoSeriesJObj.Add('endingNo', NoSeriesLine."Ending No.");
ExistingNoSeriesJObj.Add('warningNo', NoSeriesLine."Warning No.");
ExistingNoSeriesJObj.Add('incrementByNo', NoSeriesLine."Increment-by No.");
ExistingNoSeriesJObj.Add('tableId', TempTableMetadata.ID);
ExistingNoSeriesJObj.Add('fieldId', FieldRef.Number);
ExistingNoSeriesJObj.Add('nextYear', false);
ExistingNoSeriesJObj.Add('exists', true);
ExistingNoSeriesJObj.Add('message', ExistingNoSeriesMessageLbl);

ExistingNoSeriesJArr.Add(ExistingNoSeriesJObj);
end;

procedure GetExistingNoSeries() ExistingNoSeries: Text
begin
if ExistingNoSeriesJArr.Count() = 0 then
exit('');

ExistingNoSeriesJArr.WriteTo(ExistingNoSeries);
end;

[NonDebuggable]
local procedure GetToolPrompt() Prompt: Text
begin
Expand Down
Loading

0 comments on commit f36255b

Please sign in to comment.