diff --git a/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al b/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
index 99509811bf..782be7d4d6 100644
--- a/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
@@ -137,15 +137,15 @@ codeunit 4303 "Agent Task"
end;
///
- /// Gets the total Copilot credits consumed by the agent task.
+ /// Gets the details for the specified agent task log entry.
///
- /// The ID of the agent task to get consumed credits for.
- /// The total Copilot credits consumed by the agent task.
- procedure GetCopilotCreditsConsumed(AgentTaskID: BigInteger): Decimal
+ /// The agent task log entry to get details for.
+ /// The details of the agent task log entry.
+ procedure GetDetailsForAgentTaskLogEntry(var AgentTaskLogEntry: Record "Agent Task Log Entry"): Text
var
AgentTaskImpl: Codeunit "Agent Task Impl.";
begin
- exit(AgentTaskImpl.GetCopilotCreditsConsumed(AgentTaskID));
+ exit(AgentTaskImpl.GetDetailsForAgentTaskLogEntry(AgentTaskLogEntry));
end;
var
diff --git a/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al b/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al
index 47ff6de66d..ef89659c4c 100644
--- a/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al
@@ -7,7 +7,6 @@ namespace System.Agents;
using System.Agents.Troubleshooting;
using System.Environment;
-using System.Environment.Consumption;
using System.Integration;
codeunit 4300 "Agent Task Impl."
@@ -15,7 +14,6 @@ codeunit 4300 "Agent Task Impl."
Access = Internal;
InherentEntitlements = X;
InherentPermissions = X;
- Permissions = tabledata "User AI Consumption Data" = r;
procedure SetMessageText(var AgentTaskMessage: Record "Agent Task Message"; MessageText: Text)
var
@@ -154,18 +152,6 @@ codeunit 4300 "Agent Task Impl."
exit((AgentTask.Status = AgentTask.Status::"Stopped by User") or (AgentTask.Status = AgentTask.Status::"Stopped by System"));
end;
- procedure GetCopilotCreditsConsumed(AgentTaskID: BigInteger): Decimal
- var
- AgentTask: Record "Agent Task";
- UserAIConsumptionData: Record "User AI Consumption Data";
- begin
- if not AgentTask.Get(AgentTaskID) then
- exit(0);
- UserAIConsumptionData.SetRange("Agent Task Id", AgentTask.ID);
- UserAIConsumptionData.CalcSums("Copilot Credits");
- exit(UserAIConsumptionData."Copilot Credits");
- end;
-
internal procedure TryGetAgentRecordFromTaskId(TaskId: Integer; var Agent: Record Agent): Boolean
var
AgentTask: Record "Agent Task";
diff --git a/src/System Application/App/Agent/Interaction/Internal/AgentTaskList.Page.al b/src/System Application/App/Agent/Interaction/Internal/AgentTaskList.Page.al
index a1fdf1bca2..ac60fabba2 100644
--- a/src/System Application/App/Agent/Interaction/Internal/AgentTaskList.Page.al
+++ b/src/System Application/App/Agent/Interaction/Internal/AgentTaskList.Page.al
@@ -108,7 +108,6 @@ page 4300 "Agent Task List"
}
field(Credits; ConsumedCredits)
{
- Visible = ConsumedCreditsVisible;
Caption = 'Copilot credits';
ToolTip = 'Specifies the number of Copilot credits consumed by the agent task.';
AutoFormatType = 0;
@@ -116,10 +115,9 @@ page 4300 "Agent Task List"
trigger OnDrillDown()
var
- UserAIConsumptionData: Record "User AI Consumption Data";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
begin
- UserAIConsumptionData.SetRange("Agent Task Id", Rec.ID);
- Page.Run(Page::"Agent Consumption Overview", UserAIConsumptionData);
+ AgentConsumptionOverview.OpenAgentTaskConsumptionOverview(Rec.ID);
end;
}
}
@@ -205,13 +203,6 @@ page 4300 "Agent Task List"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- end;
-
trigger OnAfterGetRecord()
begin
UpdateControls();
@@ -226,16 +217,9 @@ page 4300 "Agent Task List"
local procedure CalculateTaskConsumedCredits()
var
- UserAIConsumptionData: Record "User AI Consumption Data";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
begin
- if not ConsumedCreditsVisible then begin
- Clear(ConsumedCredits);
- exit;
- end;
-
- UserAIConsumptionData.SetRange("Agent Task Id", Rec.ID);
- UserAIConsumptionData.CalcSums("Copilot Credits");
- ConsumedCredits := UserAIConsumptionData."Copilot Credits";
+ ConsumedCredits := AgentConsumptionOverview.GetCopilotCreditsConsumed(Rec.ID);
end;
local procedure UpdateControls()
@@ -258,5 +242,4 @@ page 4300 "Agent Task List"
NumberOfStepsDone: Integer;
TaskSelected: Boolean;
ConsumedCredits: Decimal;
- ConsumedCreditsVisible: Boolean;
}
\ No newline at end of file
diff --git a/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Codeunit.al b/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Codeunit.al
new file mode 100644
index 0000000000..5d950456cb
--- /dev/null
+++ b/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Codeunit.al
@@ -0,0 +1,67 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.Agents;
+using System.Environment.Consumption;
+
+codeunit 4333 "Agent Consumption Overview"
+{
+ InherentEntitlements = X;
+ InherentPermissions = X;
+ Permissions = tabledata "Agent Task" = r,
+ tabledata "User AI Consumption Data" = r;
+
+ ///
+ /// Gets the total Copilot credits consumed by the agent task.
+ ///
+ /// The ID of the agent task to get consumed credits for.
+ /// The total Copilot credits consumed by the agent task.
+ procedure GetCopilotCreditsConsumed(TaskId: BigInteger): Decimal
+ var
+ UserAIConsumptionData: Record "User AI Consumption Data";
+ begin
+ UserAIConsumptionData.SetRange("Agent Task Id", TaskId);
+ UserAIConsumptionData.CalcSums("Copilot Credits");
+ exit(UserAIConsumptionData."Copilot Credits");
+ end;
+
+ ///
+ /// Opens the agent consumption overview page for the specified agent.
+ ///
+ /// The agent user security ID.
+ procedure OpenAgentConsumptionOverview(AgentUserSecurityId: Guid)
+ var
+ AgentTaskConsumption: Record "Agent Task Consumption";
+ begin
+ AgentTaskConsumption.SetRange("Agent User Security ID", AgentUserSecurityId);
+ Page.Run(Page::"Agent Consumption Overview", AgentTaskConsumption);
+ end;
+
+ ///
+ /// Opens the agent consumption overview page for the specified agent task.
+ ///
+ /// The ID of the agent task.
+ procedure OpenAgentTaskConsumptionOverview(TaskId: BigInteger)
+ var
+ AgentTaskConsumption: Record "Agent Task Consumption";
+ begin
+ AgentTaskConsumption.SetRange("Task ID", TaskId);
+ Page.Run(Page::"Agent Consumption Overview", AgentTaskConsumption);
+ end;
+
+ ///
+ /// Opens the agent consumption overview page for the agent tasks matching the specified filter.
+ ///
+ /// The filter for the agent task IDs.
+ procedure OpenAgentTaskConsumptionOverview(TaskIDFilter: Text)
+ var
+ AgentTaskConsumption: Record "Agent Task Consumption";
+ AgentConsumptionOverview: Page "Agent Consumption Overview";
+ begin
+ AgentTaskConsumption.SetFilter("Task ID", TaskIDFilter);
+ AgentConsumptionOverview.SetTableView(AgentTaskConsumption);
+ AgentConsumptionOverview.Run();
+ end;
+}
\ No newline at end of file
diff --git a/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Page.al b/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Page.al
index e5e84b83f6..85f674a48c 100644
--- a/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Page.al
+++ b/src/System Application/App/Agent/Monetization/AgentConsumptionOverview.Page.al
@@ -6,8 +6,6 @@
namespace System.Agents;
using System.Agents.Troubleshooting;
-using System.Environment.Consumption;
-using System.Security.AccessControl;
///
/// This page is showing Copilot credit consumption per agent or per agent task
@@ -16,12 +14,11 @@ page 4333 "Agent Consumption Overview"
{
PageType = Worksheet;
ApplicationArea = All;
- SourceTable = "User AI Consumption Data";
+ SourceTable = "Agent Task Consumption";
Caption = 'Agent consumption overview';
InherentEntitlements = X;
InherentPermissions = X;
- SourceTableView = sorting("Consumption DateTime") order(descending);
- Permissions = tabledata User = r;
+ SourceTableView = sorting("Consumption Timestamp") order(descending);
InsertAllowed = false;
ModifyAllowed = false;
DeleteAllowed = false;
@@ -62,7 +59,7 @@ page 4333 "Agent Consumption Overview"
repeater(GroupName)
{
Editable = false;
- field(ConsumptionDateTime; Rec."Consumption DateTime")
+ field(ConsumptionDateTime; Rec."Consumption Timestamp")
{
Caption = 'Created at';
ToolTip = 'Specifies the date and time when the consumption was created.';
@@ -83,7 +80,7 @@ page 4333 "Agent Consumption Overview"
Caption = 'Resource name';
ToolTip = 'Specifies the name of the resource that consumed the credits. This is typically the type of the agent that performed the operation.';
}
- field(UserName; UserName)
+ field(UserName; Rec."Agent User Display Name")
{
Caption = 'User name';
ToolTip = 'Specifies the name of the user who performed the operation.';
@@ -101,7 +98,7 @@ page 4333 "Agent Consumption Overview"
{
Caption = 'Copilot Studio feature';
}
- field("Agent Task ID"; Rec."Agent Task ID")
+ field("Agent Task ID"; Rec."Task ID")
{
Caption = 'Agent task ID';
Enabled = not FilteredToTask;
@@ -298,12 +295,8 @@ page 4333 "Agent Consumption Overview"
}
trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
begin
- if not AgentSystemPermissions.CurrentUserCanSeeConsumptionData() then
- Error(YourNotAuthorizedToViewMonetizationDataErr);
-
+ ValidateAgentAccessControl();
SetDateRangeFilters();
OnGetTotalsVisible(TotalsVisible, FilteredToTask);
end;
@@ -322,58 +315,34 @@ page 4333 "Agent Consumption Overview"
local procedure UpdateRowValues()
var
- User: Record User;
DescriptionInStream: InStream;
begin
- Rec.CalcFields(Description);
+ Rec.CalcFields(Description, "Agent User Display Name", "Task Title");
Rec.Description.CreateInStream(DescriptionInStream, TextEncoding::UTF8);
DescriptionInStream.ReadText(DescriptionTxt);
- if not UserNameDictionary.ContainsKey(Rec."User Id") then begin
- if User.Get(Rec."User Id") then begin
- UserName := User."User Name";
- UserNameDictionary.Add(Rec."User Id", UserName);
- end else
- UserName := '';
-
- exit;
- end;
-
- UserName := UserNameDictionary.Get(Rec."User Id");
end;
local procedure UpdateAgentTaskName()
- var
- AgentTask: Record "Agent Task";
begin
- if not AgentTaskDictionary.ContainsKey(Rec."Agent Task ID") then begin
- if AgentTask.Get(Rec."Agent Task ID") then begin
- TaskNameTxt := StrSubstNo(AgentTaskNameTxt, AgentTask.ID, AgentTask.Title);
- AgentTaskDictionary.Add(Rec."Agent Task ID", TaskNameTxt);
- end else
- TaskNameTxt := '';
-
- exit;
- end;
-
- TaskNameTxt := AgentTaskDictionary.Get(Rec."Agent Task ID");
+ TaskNameTxt := StrSubstNo(AgentTaskNameTxt, Rec."Task Id", Rec."Task Title");
end;
local procedure UpdateTotals()
var
- UserAIConsumptionData: Record "User AI Consumption Data";
+ AgentTaskConsumption: Record "Agent Task Consumption";
begin
if not TotalsVisible then
exit;
TotalEntriesCount := Rec.Count();
- UserAIConsumptionData.Copy(Rec);
- UserAIConsumptionData.CalcSums("Copilot Credits");
- TotalEntriesCopilotCredits := UserAIConsumptionData."Copilot Credits";
-
- UserAIConsumptionData.Copy(Rec);
- UserAIConsumptionData.SetRange("Agent Task Id", Rec."Agent Task ID");
- UserAIConsumptionData.CalcSums("Copilot Credits");
- TotalTaskConsumedCredits := UserAIConsumptionData."Copilot Credits";
+ AgentTaskConsumption.Copy(Rec);
+ AgentTaskConsumption.CalcSums("Copilot Credits");
+ TotalEntriesCopilotCredits := AgentTaskConsumption."Copilot Credits";
+
+ AgentTaskConsumption.Copy(Rec);
+ AgentTaskConsumption.SetRange("Task Id", Rec."Task ID");
+ AgentTaskConsumption.CalcSums("Copilot Credits");
+ TotalTaskConsumedCredits := AgentTaskConsumption."Copilot Credits";
end;
local procedure UpdateTheDescriptionAndTotalsVisibility()
@@ -382,7 +351,7 @@ page 4333 "Agent Consumption Overview"
FilteredToTask := false;
ShowFilters := true;
- if (Rec.GetFilter("User Id") = '') and (Rec.GetFilter("Agent Task Id") = '') then begin
+ if (Rec.GetFilter("Agent User Security Id") = '') and (Rec.GetFilter("Task Id") = '') then begin
ChangedDateRangeFilters := false;
ConsumptionCaption := EverythingTok;
TotalsVisible := false;
@@ -390,7 +359,7 @@ page 4333 "Agent Consumption Overview"
exit;
end;
- if Rec.GetFilter("Agent Task Id") <> '' then begin
+ if Rec.GetFilter("Task Id") <> '' then begin
ConsumptionCaption := TaskNameTxt;
FilteredToTask := true;
ShowFilters := false;
@@ -398,8 +367,8 @@ page 4333 "Agent Consumption Overview"
exit;
end;
- if Rec.GetFilter("User Id") <> '' then begin
- ConsumptionCaption := StrSubstNo(UserName);
+ if Rec.GetFilter("Agent User Security Id") <> '' then begin
+ ConsumptionCaption := Rec."Agent User Display Name";
FilteredToTask := false;
exit;
end;
@@ -410,7 +379,7 @@ page 4333 "Agent Consumption Overview"
if ChangedDateRangeFilters then
exit;
- if Rec.GetFilter("Agent Task Id") = '' then begin
+ if Rec.GetFilter("Task Id") = '' then begin
EndDate := Today();
StartDate := CalcDate(StartDateTok, Today());
UpdateDateRange(StartDate, EndDate);
@@ -420,7 +389,7 @@ page 4333 "Agent Consumption Overview"
local procedure ClearDateRangeFilters()
begin
- Rec.SetRange("Consumption DateTime");
+ Rec.SetRange("Consumption Timestamp");
Clear(StartDate);
Clear(EndDate);
end;
@@ -430,23 +399,82 @@ page 4333 "Agent Consumption Overview"
StartDate := NewStartDate;
EndDate := NewEndDate;
- Rec.SetRange("Consumption DateTime", CreateDateTime(StartDate, 0T), CreateDateTime(EndDate, 235959.999T));
+ Rec.SetRange("Consumption Timestamp", CreateDateTime(StartDate, 0T), CreateDateTime(EndDate, 235959.999T));
end;
local procedure DrillDownToAgentTask()
var
AgentTaskLogEntry: Record "Agent Task Log Entry";
begin
- AgentTaskLogEntry.SetRange("Task ID", Rec."Agent Task Id");
+ AgentTaskLogEntry.SetRange("Task ID", Rec."Task ID");
Page.Run(Page::"Agent Task Log Entry List", AgentTaskLogEntry)
end;
local procedure DrillDownToAgentTaskConsumption()
var
- UserAIConsumptionData: Record "User AI Consumption Data";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
+ begin
+ AgentConsumptionOverview.OpenAgentTaskConsumptionOverview(Rec."Task ID");
+ end;
+
+ local procedure ValidateAgentAccessControl()
+ var
+ AgentTask: Record "Agent Task";
+ AgentSystemPermissions: Codeunit "Agent System Permissions";
+ AgentUserSecurityId: Guid;
+ TaskId: BigInteger;
+ begin
+ RecallNonAdminDisclaimerNotification();
+
+ if AgentSystemPermissions.CurrentUserHasCanManageAllAgentsPermission() then
+ exit;
+
+ // There is a filter on the agent user security, check that the user has access to the agent.
+ if Rec.GetFilter("Agent User Security Id") <> '' then begin
+ Evaluate(AgentUserSecurityId, Rec.GetFilter("Agent User Security Id"));
+ if not AgentSystemPermissions.CurrentUserCanUseAgent(AgentUserSecurityId) then
+ Error(YouDoNotHaveAccessToTheAgentErr);
+ exit;
+ end;
+
+ // There is a filter on the task ID, check that the user has access to the agent.
+ if Rec.GetFilter("Task Id") <> '' then begin
+ Evaluate(TaskId, Rec.GetFilter("Task Id"));
+ if not AgentTask.Get(TaskId) then
+ Error(YouDoNotHaveAccessToTheAgentErr)
+ else
+ if not AgentSystemPermissions.CurrentUserCanUseAgent(AgentTask."Agent User Security ID") then
+ Error(YouDoNotHaveAccessToTheAgentErr);
+ exit;
+ end;
+
+ SendNonAdminDisclaimerNotification();
+ end;
+
+ local procedure RecallNonAdminDisclaimerNotification()
+ var
+ NonAdminNotification: Notification;
+ begin
+ NonAdminNotification.Id := GetNonAdminDisclaimerNotificationId();
+ NonAdminNotification.Recall();
+ end;
+
+ local procedure SendNonAdminDisclaimerNotification()
+ var
+ AgentSystemPermissions: Codeunit "Agent System Permissions";
+ NonAdminNotification: Notification;
+ begin
+ if AgentSystemPermissions.CurrentUserHasCanManageAllAgentsPermission() then
+ exit;
+
+ NonAdminNotification.Message := NonAdminDisclaimerMsg;
+ NonAdminNotification.Scope := NotificationScope::LocalScope;
+ NonAdminNotification.Send();
+ end;
+
+ local procedure GetNonAdminDisclaimerNotificationId(): Text
begin
- UserAIConsumptionData.SetRange("Agent Task Id", Rec."Agent Task ID");
- Page.Run(Page::"Agent Consumption Overview", UserAIConsumptionData);
+ exit('b9234f5f-3e6b-437a-9f34-acdb9bf9fb8f');
end;
[IntegrationEvent(false, false)]
@@ -455,13 +483,10 @@ page 4333 "Agent Consumption Overview"
end;
var
- AgentTaskDictionary: Dictionary of [BigInteger, Text];
- UserNameDictionary: Dictionary of [Guid, Text[80]];
ChangedDateRangeFilters: Boolean;
StartDate: Date;
EndDate: Date;
DescriptionTxt: Text;
- UserName: Text[80];
TotalEntriesCount: Integer;
TaskNameTxt: Text;
FilteredToTask: Boolean;
@@ -473,7 +498,8 @@ page 4333 "Agent Consumption Overview"
TotalsVisible: Boolean;
EverythingTok: Label 'Everything';
AgentTaskNameTxt: Label 'Task #%1 - %2', Comment = '%1 - ID of the agent task, %2 - Title of the agent task';
- YourNotAuthorizedToViewMonetizationDataErr: Label 'You are missing the required permissions to view monetization data.';
TheEndDateIsTodayMsg: Label 'The end date is already set to today. You cannot move the date range filter further.';
+ NonAdminDisclaimerMsg: Label 'You''re seeing consumption for agents you have access to. For complete data, ask an Agent-Admin.';
+ YouDoNotHaveAccessToTheAgentErr: Label 'You do not have permission to view consumption data for this agent.';
StartDateTok: Label '<-CM>', Locked = true;
}
\ No newline at end of file
diff --git a/src/System Application/App/Agent/Permissions/AgentSystemPermissions.Codeunit.al b/src/System Application/App/Agent/Permissions/AgentSystemPermissions.Codeunit.al
index 6a763626b2..2bd22c3ab4 100644
--- a/src/System Application/App/Agent/Permissions/AgentSystemPermissions.Codeunit.al
+++ b/src/System Application/App/Agent/Permissions/AgentSystemPermissions.Codeunit.al
@@ -11,9 +11,9 @@ codeunit 4317 "Agent System Permissions"
InherentPermissions = X;
///
- /// Gets whether the current user has permissions to see consumption data.
+ /// Gets whether the current user has permissions to see all consumption data.
///
- /// True if the user has permissions to see consumption data, false otherwise.
+ /// True if the user has permissions to see all consumption data, false otherwise.
procedure CurrentUserCanSeeConsumptionData(): Boolean
begin
exit(AgentSystemPermissionsImpl.CurrentUserCanSeeConsumptionData());
@@ -23,7 +23,6 @@ codeunit 4317 "Agent System Permissions"
/// Gets whether the current user has permissions to manage all agents.
///
/// True if the user has permissions to manage all agents, false otherwise.
- [Scope('OnPrem')]
procedure CurrentUserHasCanManageAllAgentsPermission(): Boolean
begin
exit(AgentSystemPermissionsImpl.CurrentUserHasCanManageAllAgentsPermission());
@@ -49,6 +48,17 @@ codeunit 4317 "Agent System Permissions"
exit(AgentSystemPermissionsImpl.CurrentUserHasCanCreateCustomAgent());
end;
+ ///
+ /// Gets whether the current user has permissions to use a specific agent.
+ ///
+ /// The user security id associated with the agent.
+ /// True if the user has use permissions for the specified agent, false otherwise.
+ [Scope('OnPrem')]
+ procedure CurrentUserCanUseAgent(AgentUserSecurityId: Guid): Boolean
+ begin
+ exit(AgentSystemPermissionsImpl.CurrentUserCanUseAgent(AgentUserSecurityId));
+ end;
+
var
AgentSystemPermissionsImpl: Codeunit "Agent System Permissions Impl.";
}
\ No newline at end of file
diff --git a/src/System Application/App/Agent/Permissions/Internal/AgentSystemPermissionsImpl.Codeunit.al b/src/System Application/App/Agent/Permissions/Internal/AgentSystemPermissionsImpl.Codeunit.al
index fbe0fbd88d..91436fee0b 100644
--- a/src/System Application/App/Agent/Permissions/Internal/AgentSystemPermissionsImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Permissions/Internal/AgentSystemPermissionsImpl.Codeunit.al
@@ -38,6 +38,19 @@ codeunit 4318 "Agent System Permissions Impl."
exit(false);
end;
+ procedure CurrentUserCanUseAgent(AgentUserSecurityId: Guid): Boolean
+ var
+ Agent: Record Agent;
+ begin
+ if (CurrentUserHasCanManageAllAgentsPermission()) then
+ exit(true);
+
+ if Agent.Get(AgentUserSecurityId) then
+ exit(Agent."Can Current User Use Agent");
+
+ exit(false);
+ end;
+
local procedure CurrentUserHasExecuteSystemPermission(PermissionId: Integer): Boolean
var
TempPermission: Record "Expanded Permission" temporary;
diff --git a/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al b/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
index 5e5ffb6472..991b63d885 100644
--- a/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
@@ -268,13 +268,6 @@ codeunit 4301 "Agent Impl."
exit(false);
end;
- procedure CanShowMonetizationData(): Boolean
- var
- DummyUserAIConsumptionData: Record "User AI Consumption Data";
- begin
- exit(DummyUserAIConsumptionData.ReadPermission());
- end;
-
local procedure UpdateUserSettingsWithProfile(var TempAllProfile: Record "All Profile" temporary; var UserSettingsRec: Record "User Settings")
begin
UserSettingsRec."Profile ID" := TempAllProfile."Profile ID";
diff --git a/src/System Application/App/Agent/Setup/AgentList.Page.al b/src/System Application/App/Agent/Setup/AgentList.Page.al
index dc17a35fbc..a6edd4916d 100644
--- a/src/System Application/App/Agent/Setup/AgentList.Page.al
+++ b/src/System Application/App/Agent/Setup/AgentList.Page.al
@@ -101,12 +101,12 @@ page 4316 "Agent List"
trigger OnAction()
var
- UserAIConsumptionData: Record "User AI Consumption Data";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
begin
if Rec.IsEmpty() then
Error(NoAgentSetupErr);
- UserAIConsumptionData.SetRange("User ID", Rec."User Security ID");
- Page.Run(Page::"Agent Consumption Overview", UserAIConsumptionData);
+
+ AgentConsumptionOverview.OpenAgentConsumptionOverview(Rec."User Security ID");
end;
}
}
diff --git a/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al b/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al
index 6a76958903..f6b3576753 100644
--- a/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al
+++ b/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al
@@ -139,13 +139,6 @@ page 149038 "AIT Log Entry API"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- end;
-
trigger OnAfterGetRecord()
var
AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
@@ -156,7 +149,7 @@ page 149038 "AIT Log Entry API"
ErrorCallStackText := Rec.GetErrorCallStack();
SuiteDescription := Rec.GetSuiteDescription();
TestMethodLineDescription := Rec.GetTestMethodLineDescription();
- CopilotCredits := ConsumedCreditsVisible ? AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.") : -1;
+ CopilotCredits := AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.");
AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDsForLogEntry(Rec."Entry No.");
end;
@@ -168,6 +161,5 @@ page 149038 "AIT Log Entry API"
SuiteDescription: Text[250];
TestMethodLineDescription: Text[250];
CopilotCredits: Decimal;
- ConsumedCreditsVisible: Boolean;
AgentTaskIDs: Text;
}
\ No newline at end of file
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentLogEntries.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentLogEntries.PageExt.al
index 6461003efe..fc12a1edf4 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentLogEntries.PageExt.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentLogEntries.PageExt.al
@@ -20,7 +20,11 @@ pageextension 149030 "Agent Log Entries" extends "AIT Log Entries"
Caption = 'Copilot Credits Consumed';
ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for this log entry.';
Editable = false;
- Visible = ConsumedCreditsVisible;
+
+ trigger OnDrillDown()
+ begin
+ AgentTestContextImpl.OpenAgentConsumptionOverview(AgentTaskIDs);
+ end;
}
field("Agent Task IDs"; AgentTaskIDs)
{
@@ -39,13 +43,6 @@ pageextension 149030 "Agent Log Entries" extends "AIT Log Entries"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- end;
-
trigger OnAfterGetRecord()
begin
UpdateAgentTaskMetrics();
@@ -53,7 +50,7 @@ pageextension 149030 "Agent Log Entries" extends "AIT Log Entries"
local procedure UpdateAgentTaskMetrics()
begin
- CopilotCredits := ConsumedCreditsVisible ? AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.") : -1;
+ CopilotCredits := AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.");
AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDsForLogEntry(Rec."Entry No.");
end;
@@ -61,5 +58,4 @@ pageextension 149030 "Agent Log Entries" extends "AIT Log Entries"
AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
CopilotCredits: Decimal;
AgentTaskIDs: Text;
- ConsumedCreditsVisible: Boolean;
}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al
index 62d5ddcb7e..c0e8818d55 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al
@@ -17,10 +17,17 @@ pageextension 149032 "Agent Run History" extends "AIT Run History"
{
ApplicationArea = All;
AutoFormatType = 0;
- Visible = (ViewBy = ViewBy::Version) and ConsumedCreditsVisible;
+ Visible = ViewBy = ViewBy::Version;
Caption = 'Copilot Credits Consumed';
ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks in the current version.';
Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentConsumptionOverview(Rec."Agent Task IDs");
+ end;
}
field("Agent Task Count - By Version"; AgentTaskCountByVersion)
{
@@ -44,10 +51,17 @@ pageextension 149032 "Agent Run History" extends "AIT Run History"
{
ApplicationArea = All;
AutoFormatType = 0;
- Visible = (ViewBy = ViewBy::Tag) and ConsumedCreditsVisible;
+ Visible = ViewBy = ViewBy::Tag;
Caption = 'Copilot Credits Consumed';
ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for the tag.';
Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(Rec."Agent Task IDs - By Tag");
+ end;
}
field("Agent Task Count - By Tag"; AgentTaskCountByTag)
{
@@ -67,13 +81,6 @@ pageextension 149032 "Agent Run History" extends "AIT Run History"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- end;
-
trigger OnAfterGetRecord()
begin
UpdateAgentTaskCounts();
@@ -94,7 +101,6 @@ pageextension 149032 "Agent Run History" extends "AIT Run History"
AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
AgentTaskCountByVersion: Integer;
AgentTaskCountByTag: Integer;
- ConsumedCreditsVisible: Boolean;
}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestConsumptionLog.Table.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestConsumptionLog.Table.al
new file mode 100644
index 0000000000..5fe54bfb2d
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestConsumptionLog.Table.al
@@ -0,0 +1,50 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestTools.AITestToolkit;
+
+table 149049 "Agent Test Consumption Log"
+{
+ Caption = 'Agent Eval Task Consumption Log';
+ DataClassification = SystemMetadata;
+ Access = Internal;
+ ReplicateData = false;
+ DataPerCompany = false;
+ InherentEntitlements = RIMDX;
+ InherentPermissions = RIMDX;
+
+ fields
+ {
+ field(1; "Entry No."; Integer)
+ {
+ Caption = 'Entry No.';
+ AutoIncrement = true;
+ ToolTip = 'Specifies the Log Entry No..';
+ }
+ field(2; "Agent Task ID"; BigInteger)
+ {
+ Caption = 'Agent Task ID';
+ NotBlank = true;
+ ToolTip = 'Specifies the Agent Task ID.';
+ }
+ field(3; "Copilot Credits"; Decimal)
+ {
+ Caption = 'Copilot Credits';
+ ToolTip = 'Specifies the Copilot Credits consumed.';
+ NotBlank = true;
+ }
+ }
+
+ keys
+ {
+ key(Key1; "Entry No.")
+ {
+ Clustered = true;
+ }
+ key(Key2; "Agent Task ID")
+ {
+ }
+ }
+}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al
index 9ec4d53bac..820451f4cf 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al
@@ -6,6 +6,7 @@
namespace System.TestTools.AITestToolkit;
using System.Agents;
+using System.Environment;
using System.TestTools.TestRunner;
codeunit 149049 "Agent Test Context Impl."
@@ -46,20 +47,27 @@ codeunit 149049 "Agent Test Context Impl."
local procedure LogAgentTask(AgentTaskId: BigInteger; var AITLogEntry: Record "AIT Log Entry")
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
+ AgentTestConsumptionLog: Record "Agent Test Consumption Log";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
begin
- AgentTaskLog.TransferFields(AITLogEntry, false);
- AgentTaskLog."Agent Task ID" := AgentTaskId;
- AgentTaskLog."Test Log Entry ID" := AITLogEntry."Entry No.";
- AgentTaskLog.Insert();
+ AgentTestTaskLog.TransferFields(AITLogEntry, false);
+ AgentTestTaskLog."Agent Task ID" := AgentTaskId;
+ AgentTestTaskLog."Test Log Entry ID" := AITLogEntry."Entry No.";
+ AgentTestTaskLog.Insert();
+
+ // Insert database level consumption tracking.
+ AgentTestConsumptionLog."Agent Task ID" := AgentTaskId;
+ AgentTestConsumptionLog."Copilot Credits" := AgentConsumptionOverview.GetCopilotCreditsConsumed(AgentTaskId);
+ AgentTestConsumptionLog.Insert();
end;
procedure GetAgentTaskIDsForLogEntry(LogEntryNo: Integer): Text
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
begin
- AgentTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
- exit(GetAgentTaskIDs(AgentTaskLog));
+ AgentTestTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
+ exit(GetCommaSeparatedAgentTaskIDs(AgentTestTaskLog));
end;
procedure GetAgentTaskIDs(TestSuiteCode: Code[100]; VersionNumber: Integer; Tag: Text[20]; TestMethodLineNo: Integer): Text
@@ -68,30 +76,31 @@ codeunit 149049 "Agent Test Context Impl."
begin
if VersionNumber > 0 then
VersionFilterText := Format(VersionNumber);
+
exit(GetAgentTaskIDs(TestSuiteCode, VersionFilterText, Tag, TestMethodLineNo));
end;
procedure GetAgentTaskIDs(TestSuiteCode: Code[100]; VersionFilter: Text; Tag: Text[20]; TestMethodLineNo: Integer): Text
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
begin
- AgentTaskLog.SetRange("Test Suite Code", TestSuiteCode);
+ AgentTestTaskLog.SetRange("Test Suite Code", TestSuiteCode);
if Tag <> '' then
- AgentTaskLog.SetRange(Tag, Tag);
+ AgentTestTaskLog.SetRange(Tag, Tag);
if VersionFilter <> '' then
- AgentTaskLog.SetFilter(Version, VersionFilter);
+ AgentTestTaskLog.SetFilter(Version, VersionFilter);
if TestMethodLineNo > 0 then
- AgentTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
+ AgentTestTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
- exit(GetAgentTaskIDs(AgentTaskLog));
+ exit(GetCommaSeparatedAgentTaskIDs(AgentTestTaskLog));
end;
procedure GetCopilotCreditsForLogEntry(LogEntryNo: Integer): Decimal
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
begin
- AgentTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
- exit(GetCopilotCredits(AgentTaskLog));
+ AgentTestTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
+ exit(GetCopilotCredits(AgentTestTaskLog));
end;
procedure GetCopilotCredits(TestSuiteCode: Code[100]; VersionNumber: Integer; Tag: Text[20]; TestMethodLineNo: Integer): Decimal
@@ -105,34 +114,31 @@ codeunit 149049 "Agent Test Context Impl."
procedure GetCopilotCredits(TestSuiteCode: Code[100]; VersionFilter: Text; Tag: Text[20]; TestMethodLineNo: Integer): Decimal
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
begin
- AgentTaskLog.SetRange("Test Suite Code", TestSuiteCode);
+ AgentTestTaskLog.SetRange("Test Suite Code", TestSuiteCode);
if VersionFilter <> '' then
- AgentTaskLog.SetFilter(Version, VersionFilter);
-
+ AgentTestTaskLog.SetFilter(Version, VersionFilter);
if Tag <> '' then
- AgentTaskLog.SetRange(Tag, Tag);
-
+ AgentTestTaskLog.SetRange(Tag, Tag);
if TestMethodLineNo > 0 then
- AgentTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
-
- exit(GetCopilotCredits(AgentTaskLog));
+ AgentTestTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
+ exit(GetCopilotCredits(AgentTestTaskLog));
end;
- local procedure GetCopilotCredits(var AgentTaskLog: Record "Agent Task Log"): Decimal
+ local procedure GetCopilotCredits(var AgentTestTaskLog: Record "Agent Test Task Log"): Decimal
var
- AgentTask: Codeunit "Agent Task";
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
TaskIDsList: List of [BigInteger];
TotalCredits: Decimal;
begin
- if AgentTaskLog.FindSet() then
+ if AgentTestTaskLog.FindSet() then
repeat
- if not TaskIDsList.Contains(AgentTaskLog."Agent Task ID") then begin
- TaskIDsList.Add(AgentTaskLog."Agent Task ID");
- TotalCredits += AgentTask.GetCopilotCreditsConsumed(AgentTaskLog."Agent Task ID");
+ if not TaskIDsList.Contains(AgentTestTaskLog."Agent Task ID") then begin
+ TaskIDsList.Add(AgentTestTaskLog."Agent Task ID");
+ TotalCredits += AgentConsumptionOverview.GetCopilotCreditsConsumed(AgentTestTaskLog."Agent Task ID");
end;
- until AgentTaskLog.Next() = 0;
+ until AgentTestTaskLog.Next() = 0;
exit(TotalCredits);
end;
@@ -163,18 +169,30 @@ codeunit 149049 "Agent Test Context Impl."
AgentTaskListPage.Run();
end;
- local procedure GetAgentTaskIDs(var AgentTaskLog: Record "Agent Task Log"): Text
+ procedure OpenAgentConsumptionOverview(CommaSeparatedTaskIDs: Text)
+ var
+ AgentConsumptionOverview: Codeunit "Agent Consumption Overview";
+ FilterText: Text;
+ begin
+ FilterText := ConvertCommaSeparatedToFilter(CommaSeparatedTaskIDs);
+ if FilterText = '' then
+ exit;
+
+ AgentConsumptionOverview.OpenAgentTaskConsumptionOverview(FilterText);
+ end;
+
+ local procedure GetCommaSeparatedAgentTaskIDs(var AgentTestTaskLog: Record "Agent Test Task Log"): Text
var
TaskIDList: List of [BigInteger];
TaskIDTextList: List of [Text];
begin
- if AgentTaskLog.FindSet() then
+ if AgentTestTaskLog.FindSet() then
repeat
- if not TaskIDList.Contains(AgentTaskLog."Agent Task ID") then begin
- TaskIDList.Add(AgentTaskLog."Agent Task ID");
- TaskIDTextList.Add(Format(AgentTaskLog."Agent Task ID"));
+ if not TaskIDList.Contains(AgentTestTaskLog."Agent Task ID") then begin
+ TaskIDList.Add(AgentTestTaskLog."Agent Task ID");
+ TaskIDTextList.Add(Format(AgentTestTaskLog."Agent Task ID"));
end;
- until AgentTaskLog.Next() = 0;
+ until AgentTestTaskLog.Next() = 0;
exit(ConcatenateList(TaskIDTextList, ', '));
end;
@@ -227,24 +245,25 @@ codeunit 149049 "Agent Test Context Impl."
procedure GetCopilotCreditsForPeriod(TestSuiteCode: Code[100]; PeriodStartDate: Date; PeriodEndDate: Date): Decimal
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestTaskLog: Record "Agent Test Task Log";
begin
- AgentTaskLog.SetRange("Test Suite Code", TestSuiteCode);
- AgentTaskLog.SetFilter(SystemCreatedAt, '>=%1&<=%2', CreateDateTime(PeriodStartDate, 0T), CreateDateTime(PeriodEndDate, 235959.999T));
- exit(GetCopilotCredits(AgentTaskLog));
+ AgentTestTaskLog.SetRange("Test Suite Code", TestSuiteCode);
+ AgentTestTaskLog.SetFilter(SystemCreatedAt, '>=%1&<=%2', CreateDateTime(PeriodStartDate, 0T), CreateDateTime(PeriodEndDate, 235959.999T));
+ exit(GetCopilotCredits(AgentTestTaskLog));
end;
- procedure GetCopilotCreditsForPeriod(PeriodStartDate: Date): Decimal
+ procedure GetCopilotCreditsAcrossCompaniesForPeriod(PeriodStartDate: Date): Decimal
begin
- exit(GetCopilotCreditsForPeriod(PeriodStartDate, DT2Date(CurrentDateTime())));
+ exit(GetCopilotCreditsAcrossCompaniesForPeriod(PeriodStartDate, DT2Date(CurrentDateTime())));
end;
- procedure GetCopilotCreditsForPeriod(PeriodStartDate: Date; PeriodEndDate: Date): Decimal
+ procedure GetCopilotCreditsAcrossCompaniesForPeriod(PeriodStartDate: Date; PeriodEndDate: Date): Decimal
var
- AgentTaskLog: Record "Agent Task Log";
+ AgentTestConsumptionLog: Record "Agent Test Consumption Log";
begin
- AgentTaskLog.SetFilter(SystemCreatedAt, '>=%1&<=%2', CreateDateTime(PeriodStartDate, 0T), CreateDateTime(PeriodEndDate, 235959.999T));
- exit(GetCopilotCredits(AgentTaskLog));
+ AgentTestConsumptionLog.SetFilter(SystemCreatedAt, '>=%1&<=%2', CreateDateTime(PeriodStartDate, 0T), CreateDateTime(PeriodEndDate, 235959.999T));
+ AgentTestConsumptionLog.CalcSums("Copilot Credits");
+ exit(AgentTestConsumptionLog."Copilot Credits");
end;
[EventSubscriber(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", OnRunTestSuite, '', false, false)]
@@ -264,6 +283,16 @@ codeunit 149049 "Agent Test Context Impl."
Error(AgentIsNotActiveErr, AITTestSuite.Code, AITTestSuite."Agent User Security ID");
end;
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"System Action Triggers", GetAgentTaskEvalExecutionContext, '', true, true)]
+ local procedure GetAgentTaskEvalExecutionContextEvent(AgentUserSecurityId: Guid; TaskId: BigInteger; var Context: JsonObject)
+ var
+ AIMonthlyEvalCopilotCredits: Codeunit "AIT Eval Monthly Copilot Cred.";
+ LimitReachedTok: Label 'limitReached', Locked = true;
+ begin
+ // Agent task log entries are currently logged after the eval execution, so we need to answer independently of the task ID.
+ Context.Add(LimitReachedTok, AIMonthlyEvalCopilotCredits.IsLimitReached());
+ end;
+
var
AgentTaskList: List of [BigInteger];
GlobalAgentUserSecurityID: Guid;
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al
index 3189285855..905de123bf 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al
@@ -20,7 +20,11 @@ pageextension 149033 "Agent Test Method Lines" extends "AIT Test Method Lines"
Caption = 'Copilot Credits Consumed';
ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for this eval line.';
Editable = false;
- Visible = ConsumedCreditsVisible;
+
+ trigger OnDrillDown()
+ begin
+ AgentTestContextImpl.OpenAgentConsumptionOverview(AgentTaskIDs);
+ end;
}
field("Agent Task Count"; AgentTaskCount)
{
@@ -39,13 +43,6 @@ pageextension 149033 "Agent Test Method Lines" extends "AIT Test Method Lines"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- end;
-
trigger OnAfterGetRecord()
begin
UpdateAgentTaskMetrics();
@@ -65,7 +62,7 @@ pageextension 149033 "Agent Test Method Lines" extends "AIT Test Method Lines"
Rec.FilterGroup(4);
VersionFilter := Rec.GetFilter(Rec."Version Filter");
Rec.FilterGroup(CurrentFilterGroup);
- CopilotCredits := ConsumedCreditsVisible ? AgentTestContextImpl.GetCopilotCredits(Rec."Test Suite Code", VersionFilter, '', Rec."Line No.") : -1;
+ CopilotCredits := AgentTestContextImpl.GetCopilotCredits(Rec."Test Suite Code", VersionFilter, '', Rec."Line No.");
AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDs(Rec."Test Suite Code", VersionFilter, '', Rec."Line No.");
AgentTaskCount := AgentTestContextImpl.GetAgentTaskCount(AgentTaskIDs);
end;
@@ -75,5 +72,4 @@ pageextension 149033 "Agent Test Method Lines" extends "AIT Test Method Lines"
CopilotCredits: Decimal;
AgentTaskIDs: Text;
AgentTaskCount: Integer;
- ConsumedCreditsVisible: Boolean;
}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al
index 170192f164..05f1fc7d0e 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al
@@ -58,7 +58,11 @@ pageextension 149034 "Agent Test Suite" extends "AIT Test Suite"
Editable = false;
Caption = 'Copilot Credits Consumed';
ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks in the current version.';
- Visible = ConsumedCreditsVisible;
+
+ trigger OnDrillDown()
+ begin
+ AgentTestContextImpl.OpenAgentConsumptionOverview(AgentTaskIDs);
+ end;
}
field("Agent Task Count"; AgentTaskCount)
{
@@ -105,16 +109,9 @@ pageextension 149034 "Agent Test Suite" extends "AIT Test Suite"
}
}
- trigger OnOpenPage()
- var
- AgentSystemPermissions: Codeunit "Agent System Permissions";
- begin
- ConsumedCreditsVisible := AgentSystemPermissions.CurrentUserCanSeeConsumptionData();
- UpdateIsAgentTestType();
- end;
-
trigger OnAfterGetCurrRecord()
begin
+ UpdateIsAgentTestType();
UpdateAgentTaskMetrics();
UpdateAgentUserName();
ShowNotifications();
@@ -127,7 +124,7 @@ pageextension 149034 "Agent Test Suite" extends "AIT Test Suite"
local procedure UpdateAgentTaskMetrics()
begin
- CopilotCredits := ConsumedCreditsVisible ? AgentTestContextImpl.GetCopilotCredits(Rec.Code, Rec.Version, '', 0) : -1;
+ CopilotCredits := AgentTestContextImpl.GetCopilotCredits(Rec.Code, Rec.Version, '', 0);
AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDs(Rec.Code, Rec.Version, '', 0);
AgentTaskCount := AgentTestContextImpl.GetAgentTaskCount(AgentTaskIDs);
end;
@@ -189,7 +186,6 @@ pageextension 149034 "Agent Test Suite" extends "AIT Test Suite"
AgentTaskIDs: Text;
AgentTaskCount: Integer;
AgentUserName: Code[50];
- ConsumedCreditsVisible: Boolean;
IsAgentTestType: Boolean;
AgentWithNameNotFoundErr: Label 'An agent with the name %1 was not found.', Comment = '%1 - The name of the agent';
}
\ No newline at end of file
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestTaskLog.Table.al
similarity index 93%
rename from src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al
rename to src/Tools/AI Test Toolkit/src/Agent/AgentTestTaskLog.Table.al
index ee36df594c..f5e495ba66 100644
--- a/src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestTaskLog.Table.al
@@ -4,10 +4,11 @@
// ------------------------------------------------------------------------------------------------
namespace System.TestTools.AITestToolkit;
+using System.Environment;
-table 149050 "Agent Task Log"
+table 149050 "Agent Test Task Log"
{
- Caption = 'AI Agent Task Log';
+ Caption = 'Agent Eval Task Log';
DataClassification = SystemMetadata;
Extensible = true;
Access = Internal;
@@ -27,7 +28,7 @@ table 149050 "Agent Task Log"
{
Caption = 'Eval Suite Code';
NotBlank = true;
- TableRelation = "AIT Test Suite";
+ TableRelation = "AIT Test Suite".Code;
ToolTip = 'Specifies the Eval Suite Code.';
}
field(3; "Test Method Line No."; Integer)
@@ -89,5 +90,8 @@ table 149050 "Agent Task Log"
key(Key3; "Test Log Entry ID", "Agent Task ID")
{
}
+ key(Key4; "Agent Task ID")
+ {
+ }
}
}
diff --git a/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Codeunit.al b/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Codeunit.al
index 3a9ac1e904..2fbbe0933d 100644
--- a/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Codeunit.al
+++ b/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Codeunit.al
@@ -51,7 +51,7 @@ codeunit 149039 "AIT Eval Monthly Copilot Cred." implements "AIT Eval Limit Prov
if AITEvalMonthlyCopilotCreditsLimit."Monthly Credit Limit" <= 0 then
exit(false);
- CopilotCreditConsumed := AgentTestContextImpl.GetCopilotCreditsForPeriod(AITEvalMonthlyCopilotCreditsLimit.GetPeriodStartDate());
+ CopilotCreditConsumed := AgentTestContextImpl.GetCopilotCreditsAcrossCompaniesForPeriod(AITEvalMonthlyCopilotCreditsLimit.GetPeriodStartDate());
exit(CopilotCreditConsumed >= AITEvalMonthlyCopilotCreditsLimit."Monthly Credit Limit");
end;
diff --git a/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Page.al b/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Page.al
index 82a9faa937..1778dfeff4 100644
--- a/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Page.al
+++ b/src/Tools/AI Test Toolkit/src/Limits/CopilotCredits/AITEvalMonthlyCopilotCred.Page.al
@@ -5,6 +5,8 @@
namespace System.TestTools.AITestToolkit;
+using System.Agents;
+
page 149048 "AIT Eval Monthly Copilot Cred."
{
Caption = 'AI Eval Monthly Copilot Credit Limits';
@@ -31,10 +33,12 @@ page 149048 "AIT Eval Monthly Copilot Cred."
group(CreditLimitSetup)
{
ShowCaption = false;
+ Enabled = CurrentUserIsAgentAdmin;
field(EnforcementEnabled; EnforcementEnabled)
{
Caption = 'Limits Enabled';
ToolTip = 'Specifies whether the credit limit enforcement is enabled. When disabled, suites can consume unlimited credits.';
+ Enabled = CurrentUserIsAgentAdmin;
trigger OnValidate()
begin
@@ -46,9 +50,9 @@ page 149048 "AIT Eval Monthly Copilot Cred."
{
AutoFormatType = 0;
Caption = 'Monthly Copilot Credit Limit';
- ToolTip = 'Specifies the maximum number of Copilot credits that can be consumed by all agent test suites during the current month.';
+ ToolTip = 'Specifies the maximum number of Copilot credits that can be consumed by all agent test suites in this environment during the current month.';
DecimalPlaces = 2 : 5;
- Editable = EnforcementEnabled;
+ Editable = EnforcementEnabled and CurrentUserIsAgentAdmin;
trigger OnValidate()
begin
@@ -59,7 +63,7 @@ page 149048 "AIT Eval Monthly Copilot Cred."
}
repeater(AgentSuites)
{
- Caption = 'Agent Test Suites';
+ Caption = 'Agent test suites in this company';
field("Code"; Rec."Suite Code")
{
@@ -81,7 +85,7 @@ page 149048 "AIT Eval Monthly Copilot Cred."
{
AutoFormatType = 0;
Caption = 'Copilot Credits Consumed (Month)';
- ToolTip = 'Specifies the number of Copilot credits consumed by this test suite during the current month.';
+ ToolTip = 'Specifies the number of Copilot credits consumed by this test suite in this environment during the current month.';
Editable = false;
DecimalPlaces = 2 : 5;
}
@@ -99,7 +103,7 @@ page 149048 "AIT Eval Monthly Copilot Cred."
{
AutoFormatType = 0;
Caption = 'Copilot Credits Consumed';
- ToolTip = 'Specifies the total number of Copilot credits consumed by all agent test suites during the current month, including credits from deleted suites.';
+ ToolTip = 'Specifies the total number of Copilot credits consumed by all agent test suites in this environment during the current month, including credits from deleted suites.';
Editable = false;
DecimalPlaces = 2 : 5;
}
@@ -165,6 +169,7 @@ page 149048 "AIT Eval Monthly Copilot Cred."
DeletedSuiteCreditsConsumed: Decimal;
LoadedDataCopilotCreditsConsumed: Decimal;
EnforcementEnabled: Boolean;
+ CurrentUserIsAgentAdmin: Boolean;
CreditsUsagePercentage: Text;
CurrentPeriod: Text;
CreditsAvailableStyle: Text;
@@ -176,12 +181,20 @@ page 149048 "AIT Eval Monthly Copilot Cred."
local procedure RefreshPage()
begin
+ LoadCurrentUserIsAgentAdmin();
LoadCreditLimitSetup();
LoadBufferData();
UpdateComputedFields();
CurrPage.Update(false);
end;
+ local procedure LoadCurrentUserIsAgentAdmin()
+ var
+ AgentSystemPermissions: Codeunit "Agent System Permissions";
+ begin
+ CurrentUserIsAgentAdmin := AgentSystemPermissions.CurrentUserHasCanManageAllAgentsPermission();
+ end;
+
local procedure LoadCreditLimitSetup()
begin
AITEvalMonthlyCopilotCreditLimitRecord.GetOrCreate();
@@ -201,7 +214,7 @@ page 149048 "AIT Eval Monthly Copilot Cred."
local procedure LoadBufferData()
var
AITTestSuite: Record "AIT Test Suite";
- AIEvalSuiteUsageBufferTemp: Record "AIT Eval Suite Usage Buffer";
+ TempAIEvalSuiteUsageBuffer: Record "AIT Eval Suite Usage Buffer";
AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
SortOrder: Integer;
begin
@@ -214,25 +227,25 @@ page 149048 "AIT Eval Monthly Copilot Cred."
if AITTestSuite.FindSet() then
repeat
SortOrder += 1;
- AIEvalSuiteUsageBufferTemp.Index := SortOrder;
- AIEvalSuiteUsageBufferTemp."Suite Code" := AITTestSuite.Code;
- AIEvalSuiteUsageBufferTemp."Suite Description" := AITTestSuite.Description;
- AIEvalSuiteUsageBufferTemp.Consumed := AgentTestContextImpl.GetCopilotCreditsForPeriod(AITTestSuite.Code, AITEvalMonthlyCopilotCreditLimitRecord.GetPeriodStartDate());
- AIEvalSuiteUsageBufferTemp.Insert();
- LoadedDataCopilotCreditsConsumed += AIEvalSuiteUsageBufferTemp.Consumed;
+ TempAIEvalSuiteUsageBuffer.Index := SortOrder;
+ TempAIEvalSuiteUsageBuffer."Suite Code" := AITTestSuite.Code;
+ TempAIEvalSuiteUsageBuffer."Suite Description" := AITTestSuite.Description;
+ TempAIEvalSuiteUsageBuffer.Consumed := AgentTestContextImpl.GetCopilotCreditsForPeriod(AITTestSuite.Code, AITEvalMonthlyCopilotCreditLimitRecord.GetPeriodStartDate());
+ TempAIEvalSuiteUsageBuffer.Insert();
+ LoadedDataCopilotCreditsConsumed += TempAIEvalSuiteUsageBuffer.Consumed;
until AITTestSuite.Next() = 0;
// Sort the buffer by consumed credits in descending order.
SortOrder := 0;
- AIEvalSuiteUsageBufferTemp.SetCurrentKey(Consumed);
+ TempAIEvalSuiteUsageBuffer.SetCurrentKey(Consumed);
#pragma warning disable AA0233, AA0181
- if AIEvalSuiteUsageBufferTemp.FindLast() then
+ if TempAIEvalSuiteUsageBuffer.FindLast() then
repeat
SortOrder += 1;
- Rec := AIEvalSuiteUsageBufferTemp;
+ Rec := TempAIEvalSuiteUsageBuffer;
Rec.Index := SortOrder;
Rec.Insert();
- until AIEvalSuiteUsageBufferTemp.Next(-1) = 0;
+ until TempAIEvalSuiteUsageBuffer.Next(-1) = 0;
#pragma warning restore AA0233, AA0181
if Rec.FindFirst() then;
diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al
index b3494c474f..a390f7440c 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al
@@ -206,7 +206,7 @@ table 149032 "AIT Test Method Line"
ToolTip = 'Specifies the average accuracy of the eval line. The accuracy is calculated as the percentage of turns that passed or can be set manually by the eval.';
Editable = false;
FieldClass = FlowField;
- CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> '')));
+ CalcFormula = average("AIT Log Entry"."Test Method Line Accuracy" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> ''), Status = filter(<> 2)));
AutoFormatType = 0;
}
field(101; "AL Test Suite"; Code[10])