Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Number Series Copilot] Bug Fixes in Intent Understanding and Field Validation #2111

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------

namespace Microsoft.Foundation.NoSeries;

permissionset 330 "No. Series Copilot - Objects"
{
Access = Internal;
Assignable = false;
Permissions =
codeunit "No. Series Copilot Impl." = X,
codeunit "No. Series Text Match Impl." = X;
}
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ codeunit 324 "No. Series Copilot Impl."
Telemetry: Codeunit Telemetry;
ToolsSelectionPrompt: Text;
begin
if not AzureKeyVault.GetAzureKeyVaultSecret('NoSeriesCopilotToolsSelectionPrompt', ToolsSelectionPrompt) then begin
if not AzureKeyVault.GetAzureKeyVaultSecret('NoSeriesCopilotToolsSelectionPromptV2', ToolsSelectionPrompt) then begin
Telemetry.LogMessage('0000NDY', TelemetryToolsSelectionPromptRetrievalErr, Verbosity::Error, DataClassification::SystemMetadata);
Error(ToolLoadingErr);
end;
Expand Down Expand Up @@ -346,52 +346,80 @@ codeunit 324 "No. Series Copilot Impl."
for i := 0 to Json.GetCollectionCount() - 1 do begin
Json.GetObjectFromCollectionByIndex(i, NoSeriesObj);
Json.InitializeObject(NoSeriesObj);
CheckTextPropertyExistAndCheckIfNotEmpty('seriesCode', Json);
CheckMaximumLengthOfPropertyValue('seriesCode', Json, 20);
CheckTextPropertyExistAndCheckIfNotEmpty('description', Json);
CheckTextPropertyExistAndCheckIfNotEmpty('startingNo', Json);
CheckMaximumLengthOfPropertyValue('startingNo', Json, 20);
CheckTextPropertyExistAndCheckIfNotEmpty('endingNo', Json);
CheckMaximumLengthOfPropertyValue('endingNo', Json, 20);
CheckTextPropertyExistAndCheckIfNotEmpty('warningNo', Json);
CheckMaximumLengthOfPropertyValue('warningNo', Json, 20);
CheckIntegerPropertyExistAndCheckIfNotEmpty('incrementByNo', Json);
CheckIntegerPropertyExistAndCheckIfNotEmpty('tableId', Json);
CheckIntegerPropertyExistAndCheckIfNotEmpty('fieldId', Json);
CheckMandatoryProperties(Json);
end;
end;

local procedure CheckMandatoryProperties(var Json: Codeunit Json)
begin
if not CheckIfNumberSeriesIsGenerated(Json) then
exit;

CheckJsonTextProperty('seriesCode', Json, true);
CheckMaximumLengthOfPropertyValue('seriesCode', Json, 20);
CheckJsonTextProperty('description', Json, true);
CheckJsonTextProperty('startingNo', Json, true);
CheckMaximumLengthOfPropertyValue('startingNo', Json, 20);
CheckJsonTextProperty('endingNo', Json, false);
CheckMaximumLengthOfPropertyValue('endingNo', Json, 20);
CheckJsonTextProperty('warningNo', Json, false);
CheckMaximumLengthOfPropertyValue('warningNo', Json, 20);
CheckJsonIntegerProperty('incrementByNo', Json, false);
CheckJsonIntegerProperty('tableId', Json, true);
CheckJsonIntegerProperty('fieldId', Json, true);
end;

local procedure CheckIfNumberSeriesIsGenerated(var Json: Codeunit Json): Boolean
var
IsExists: Boolean;
begin
Json.GetBoolPropertyValueFromJObjectByName('exists', IsExists);
exit(not IsExists);
end;

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

local procedure CheckTextPropertyExistAndCheckIfNotEmpty(propertyName: Text; var Json: Codeunit Json)
local procedure CheckJsonTextProperty(propertyName: Text; var Json: Codeunit Json; IsRequired: Boolean)
var
value: Text;
begin
Json.GetStringPropertyValueByName(propertyName, value);
if value = '' then
Error(IncorrectCompletionErr, propertyName);
if not IsRequired then
exit;

if value <> '' then
exit;

Error(IncorrectCompletionErr, propertyName);
end;

local procedure CheckIntegerPropertyExistAndCheckIfNotEmpty(propertyName: Text; var Json: Codeunit Json)
local procedure CheckJsonIntegerProperty(propertyName: Text; var Json: Codeunit Json; IsRequired: Boolean)
var
PropertyValue: Integer;
begin
Json.GetIntegerPropertyValueFromJObjectByName(propertyName, PropertyValue);
if PropertyValue = 0 then
Error(IncorrectCompletionErr, propertyName);
if not IsRequired then
exit;

if PropertyValue <> 0 then
exit;

Error(IncorrectCompletionErr, propertyName);
end;

local procedure CheckMaximumLengthOfPropertyValue(propertyName: Text; var Json: Codeunit Json; maxLength: Integer)
var
value: Text;
begin
Json.GetStringPropertyValueByName(propertyName, value);
if StrLen(value) > maxLength then
Error(TextLengthIsOverMaxLimitErr, propertyName, maxLength);
if StrLen(value) <= maxLength then
exit;

Error(TextLengthIsOverMaxLimitErr, propertyName, maxLength);
end;

local procedure ReadGeneratedNumberSeriesJArray(Completion: Text) NoSeriesJArray: JsonArray
Expand Down Expand Up @@ -445,14 +473,12 @@ codeunit 324 "No. Series Copilot Impl."
var
NoSeriesCode: Text;
NoSeriesObj: Text;
IsExists: Boolean;
begin
Json.GetObjectFromCollectionByIndex(i, NoSeriesObj);
Json.InitializeObject(NoSeriesObj);
Json.GetBoolPropertyValueFromJObjectByName('exists', IsExists);
Json.GetStringPropertyValueByName('seriesCode', NoSeriesCode);

if NoSeriesCodes.Contains(NoSeriesCode) and (not IsExists) then begin
if NoSeriesCodes.Contains(NoSeriesCode) and (CheckIfNumberSeriesIsGenerated(Json)) then begin
Json.RemoveJObjectFromCollection(i);
exit;
end;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,23 +114,23 @@ page 332 "No. Series Generation"
{
Caption = 'Prepare for next year';

action(SetupForNextYear)
action(PrepareForNextYear)
{
Caption = 'Set up number series for the next year';
Caption = 'Prepare number series for the next year';
ToolTip = 'Sample prompt for setting up number series for the next year.';
trigger OnAction()
begin
InputText := SetupForNextYearLbl;
InputText := PrepareForNextYearLbl;
CurrPage.Update();
end;
}
action(SetupModuleForNextYear)
action(PrepareModuleForNextYear)
{
Caption = 'Set up number series for the [sales] module for the next year';
Caption = 'Prepare number series for the [sales] module for the next year';
ToolTip = 'Sample prompt for setting up number series for a specific module for the next year. Replace [sales] with the module you want to set up number series for.';
trigger OnAction()
begin
InputText := SetupModuleForNextYearLbl;
InputText := PrepareModuleForNextYearLbl;
CurrPage.Update();
end;
}
Expand Down Expand Up @@ -178,8 +178,8 @@ page 332 "No. Series Generation"
CreateNoSeriesForModuleWithPatternLbl: Label 'Create number series for [specify here] module in the format ';
CreateNoSeriesForCompanyLbl: Label 'Create numbers series for the new company';
ChangeNumberLbl: Label 'Change the [specify here] number to ';
SetupForNextYearLbl: Label 'Set up number series for the next year';
SetupModuleForNextYearLbl: Label 'Set up number series for the [specify here] module for the next year';
PrepareForNextYearLbl: Label 'Prepare number series for the next year';
PrepareModuleForNextYearLbl: Label 'Prepare number series for the [specify here] module for the next year';

trigger OnAfterGetCurrRecord()
begin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,24 @@

namespace Microsoft.Foundation.NoSeries;

codeunit 337 "Record Match Impl."
codeunit 337 "No. Series Text Match Impl."
{
Access = Internal;
InherentPermissions = X;
InherentEntitlements = X;

procedure IsRelevant(FirstString: Text; SecondString: Text): Boolean
var
Score: Decimal;
begin
FirstString := RemoveShortWords(FirstString);
SecondString := RemoveShortWords(SecondString);

Score := CalculateStringNearness(FirstString, SecondString, GetMatchLengthTreshold(), 100) / 100;

exit(Score >= RequiredNearness());
end;

/// <summary>
/// Computes a nearness score between strings. Nearness is based on repeatedly finding longest common substrings.
/// Substring matches below Threshold are not considered.
Expand All @@ -21,7 +33,7 @@ codeunit 337 "Record Match Impl."
/// <param name="Threshold">Substring matches below Threshold are not considered</param>
/// <param name="NormalizingFactor">Max value returned by this procedure</param>
/// <returns>A number between 0 and NormalizingFactor, representing how much of the strings was matched</returns>
procedure CalculateStringNearness(FirstString: Text; SecondString: Text; Threshold: Integer; NormalizingFactor: Integer): Integer
local procedure CalculateStringNearness(FirstString: Text; SecondString: Text; Threshold: Integer; NormalizingFactor: Integer): Integer
var
Result: Text;
TotalMatchedChars: Integer;
Expand Down Expand Up @@ -98,11 +110,11 @@ codeunit 337 "Record Match Impl."
exit(MinThreshold <= Length);
end;

procedure RemoveShortWords(OriginalText: Text[250]): Text[250];
local procedure RemoveShortWords(OriginalText: Text): Text;
var
Words: List of [Text];
Word: Text[250];
Result: Text[250];
Word: Text;
Result: Text;
begin
Words := OriginalText.Split(' '); // split the text by spaces into a list of words
foreach Word in Words do // loop through each word in the list
Expand All @@ -112,4 +124,14 @@ codeunit 337 "Record Match Impl."
OriginalText := Result; // assign the result back to the text parameter
exit(OriginalText);
end;

local procedure GetMatchLengthTreshold(): Decimal
begin
exit(2);
end;

local procedure RequiredNearness(): Decimal
begin
exit(0.9)
end;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
NumberOfAddedTablesPlaceholderLbl: Label '{number_of_tables}', Locked = true;
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;
ToolProgressDialogTextLbl: Label 'Searching for tables with number series related to your query';
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.';

Expand Down Expand Up @@ -62,7 +63,9 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
NewNoSeriesPrompt, CustomPatternsPromptList, TablesYamlList, EmptyList : List of [Text];
NumberOfToolResponses, i, ActualTablesChunkSize : Integer;
NumberOfAddedTables: Integer;
Progress: Dialog;
begin
Progress.Open(ToolProgressDialogTextLbl);
GetTablesRequireNoSeries(Arguments, TempSetupTable, TempNoSeriesField);
ToolsImpl.GetUserSpecifiedOrExistingNumberPatternsGuidelines(Arguments, CustomPatternsPromptList, EmptyList, false);

Expand All @@ -80,7 +83,8 @@ codeunit 331 "No. Series Cop. Add Intent" implements "AOAI Function"
.Replace(NumberOfAddedTablesPlaceholderLbl, Format(ActualTablesChunkSize)));

ToolResults.Add(ToolsImpl.ConvertListToText(NewNoSeriesPrompt), ActualTablesChunkSize);
end
end;
Progress.Close();
end;

local procedure GetTablesRequireNoSeries(var Arguments: JsonObject; var TempSetupTable: Record "Table Metadata" temporary; var TempNoSeriesField: Record "Field" temporary)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ codeunit 334 "No. Series Cop. Change Intent" implements "AOAI Function"
NumberOfAddedTablesPlaceholderLbl: Label '{number_of_tables}', Locked = true;
TelemetryTool2PromptRetrievalErr: Label 'Unable to retrieve the prompt for No. Series Copilot Tool 2 from Azure Key Vault.', Locked = true;
TelemetryTool2DefinitionRetrievalErr: Label 'Unable to retrieve the definition for No. Series Copilot Tool 2 from Azure Key Vault.', Locked = true;
ToolProgressDialogTextLbl: Label 'Searching for tables with number series related to your query';
ToolLoadingErr: Label 'Unable to load the No. Series Copilot Tool 2. Please try again later.';

procedure GetName(): Text
Expand Down Expand Up @@ -71,12 +72,14 @@ codeunit 334 "No. Series Cop. Change Intent" implements "AOAI Function"
ChangeNoSeriesPrompt, CustomPatternsPromptList, TablesYamlList, ExistingNoSeriesToChangeList : List of [Text];
NumberOfToolResponses, i, ActualTablesChunkSize : Integer;
NumberOfChangedTables: Integer;
Progress: Dialog;
begin
if not CheckIfUserSpecifiedNoSeriesToChange(Arguments) then begin
NoSeriesCopilotImpl.SendNotification(GetLastErrorText());
exit;
end;

Progress.Open(ToolProgressDialogTextLbl);
GetTablesWithNoSeries(Arguments, TempSetupTable, TempNoSeriesField, ExistingNoSeriesToChangeList);
ToolsImpl.GetUserSpecifiedOrExistingNumberPatternsGuidelines(Arguments, CustomPatternsPromptList, ExistingNoSeriesToChangeList, UpdateForNextYear);

Expand All @@ -97,7 +100,8 @@ codeunit 334 "No. Series Cop. Change Intent" implements "AOAI Function"
.Replace(NumberOfAddedTablesPlaceholderLbl, Format(ActualTablesChunkSize)));

ToolResults.Add(ToolsImpl.ConvertListToText(ChangeNoSeriesPrompt), ActualTablesChunkSize);
end
end;
Progress.Close();
end;

[TryFunction]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ codeunit 349 "No. Series Cop. Nxt Yr. Intent" implements "AOAI Function"

var
Telemetry: Codeunit Telemetry;
FunctionNameLbl: Label 'GenerateNextYearNumberSeries', Locked = true;
FunctionNameLbl: Label 'PrepareNextYearNumberSeries', Locked = true;
TelemetryTool3DefinitionRetrievalErr: Label 'Unable to retrieve the definition for No. Series Copilot Tool 3 from Azure Key Vault.', Locked = true;
ToolLoadingErr: Label 'Unable to load the No. Series Copilot Tool 3. Please try again later.';

Expand Down Expand Up @@ -45,7 +45,7 @@ codeunit 349 "No. Series Cop. Nxt Yr. Intent" implements "AOAI Function"
var
AzureKeyVault: Codeunit "Azure Key Vault";
begin
if not AzureKeyVault.GetAzureKeyVaultSecret('NoSeriesCopilotTool3Definition', Definition) then begin
if not AzureKeyVault.GetAzureKeyVaultSecret('NoSeriesCopilotTool3DefinitionV2', Definition) then begin
Telemetry.LogMessage('0000ND9', TelemetryTool3DefinitionRetrievalErr, Verbosity::Error, DataClassification::SystemMetadata);
Error(ToolLoadingErr);
end;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,32 +225,21 @@ codeunit 336 "No. Series Cop. Tools Impl."

procedure IsRelevant(TableMetadata: Record "Table Metadata"; Field: Record "Field"; Entities: List of [Text]): Boolean
var
RecordMatchMgtCopy: Codeunit "Record Match Impl.";
TextMatchImpl: Codeunit "No. Series Text Match Impl.";
Entity: Text[250];
String1: Text[250];
String2: Text[250];
Score: Decimal;
begin
foreach Entity in Entities do begin
String1 := RecordMatchMgtCopy.RemoveShortWords(RemoveTextPart(TableMetadata.Caption, ' Setup') + ' ' + RemoveTextParts(Field.FieldName, GetNoSeriesAbbreviations()));
String2 := RecordMatchMgtCopy.RemoveShortWords(Entity);
Score := RecordMatchMgtCopy.CalculateStringNearness(String1, String2, GetMatchLengthThreshold(), 100) / 100;
if Score >= RequiredNearness() then
String1 := RemoveTextPart(TableMetadata.Name, '& ') + ' ' + Field.FieldName;
String2 := Entity;

if TextMatchImpl.IsRelevant(String1, String2) then
exit(true);
end;
exit(false);
end;

local procedure GetMatchLengthThreshold(): Decimal
begin
exit(2);
end;

local procedure RequiredNearness(): Decimal
begin
exit(0.9)
end;

procedure GenerateChunkedTablesListInYamlFormat(var TablesYamlList: List of [Text]; var TempSetupTable: Record "Table Metadata" temporary; var TempNoSeriesField: Record "Field" temporary; var NumberOfAddedTables: Integer)
begin
Clear(TablesYamlList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ codeunit 327 "No. Series Copilot Register"
end;

var
LearnMoreUrlTxt: Label 'https://go.microsoft.com/fwlink/?linkid=[id]', Locked = true; //TODO: replace 'id' when docs page is ready
LearnMoreUrlTxt: Label 'https://go.microsoft.com/fwlink/?linkid=2294514', Locked = true;

}
Loading