diff --git a/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al b/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
index 04b239563f..99509811bf 100644
--- a/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/AgentTask.Codeunit.al
@@ -136,6 +136,18 @@ codeunit 4303 "Agent Task"
exit(AgentTaskImpl.IsTaskStopped(AgentTask));
end;
+ ///
+ /// 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(AgentTaskID: BigInteger): Decimal
+ var
+ AgentTaskImpl: Codeunit "Agent Task Impl.";
+ begin
+ exit(AgentTaskImpl.GetCopilotCreditsConsumed(AgentTaskID));
+ end;
+
var
FeatureAccessManagement: Codeunit "Feature Access Management";
diff --git a/src/System Application/App/Agent/Interaction/AgentTaskMessageBuilder.Codeunit.al b/src/System Application/App/Agent/Interaction/AgentTaskMessageBuilder.Codeunit.al
index bfe8c8b893..39a231cbda 100644
--- a/src/System Application/App/Agent/Interaction/AgentTaskMessageBuilder.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/AgentTaskMessageBuilder.Codeunit.al
@@ -207,13 +207,18 @@ codeunit 4316 "Agent Task Message Builder"
///
/// The file to attach.
/// This instance of the Agent Task Message Builder.
- procedure AddAttachment(AgentTaskFile: Record "Agent Task File"): codeunit "Agent Task Message Builder"
+#if not CLEAN28
+#pragma warning disable AS0078
+#endif
+ procedure AddAttachment(var AgentTaskFile: Record "Agent Task File"): codeunit "Agent Task Message Builder"
begin
FeatureAccessManagement.AgentTaskManagementPreviewEnabled(true);
AgentTaskMsgBuilderImpl.AddAttachment(AgentTaskFile);
exit(this);
end;
-
+#if not CLEAN28
+#pragma warning restore AS0078
+#endif
///
/// Uploads a file to the task message.
/// The file will be attached when the message is created.
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 b8efb0818a..d3c254c99d 100644
--- a/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/Internal/AgentTaskImpl.Codeunit.al
@@ -7,6 +7,7 @@ namespace System.Agents;
using System.Agents.Troubleshooting;
using System.Environment;
+using System.Environment.Consumption;
using System.Integration;
codeunit 4300 "Agent Task Impl."
@@ -152,6 +153,18 @@ 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/AgentTaskMsgBuilderImpl.Codeunit.al b/src/System Application/App/Agent/Interaction/Internal/AgentTaskMsgBuilderImpl.Codeunit.al
index 9c32114882..ecd57c9a6a 100644
--- a/src/System Application/App/Agent/Interaction/Internal/AgentTaskMsgBuilderImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Interaction/Internal/AgentTaskMsgBuilderImpl.Codeunit.al
@@ -151,10 +151,12 @@ codeunit 4311 "Agent Task Msg. Builder Impl."
[Scope('OnPrem')]
procedure AddAttachment(var AgentTaskFile: Record "Agent Task File"): codeunit "Agent Task Msg. Builder Impl."
+ var
+ FileInStream: InStream;
begin
- TempAgentTaskFileToAttach.Copy(AgentTaskFile);
- TempAgentTaskFileToAttach.ID := TempAgentTaskFileToAttach.Count() + 1;
- TempAgentTaskFileToAttach.Insert();
+ AgentTaskFile.CalcFields(Content);
+ AgentTaskFile.Content.CreateInStream(FileInStream);
+ AddAttachment(AgentTaskFile."File Name", AgentTaskFile."File MIME Type", FileInStream);
exit(this);
end;
diff --git a/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al b/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
index 005c0c9a9e..965e1593ee 100644
--- a/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Setup/AgentImpl.Codeunit.al
@@ -398,12 +398,17 @@ codeunit 4301 "Agent Impl."
end;
procedure SelectAgent(var Agent: Record "Agent")
+ begin
+ SelectAgent(Agent, false);
+ end;
+
+ procedure SelectAgent(var Agent: Record "Agent"; AlwaysShowUI: Boolean)
begin
Agent.SetRange(State, Agent.State::Enabled);
if Agent.Count() = 0 then
Error(NoActiveAgentsErr);
- if Agent.Count() = 1 then begin
+ if (Agent.Count() = 1) and (not AlwaysShowUI) then begin
Agent.FindFirst();
exit;
end;
diff --git a/src/System Application/App/Agent/Setup/SetupPart/AgentSetup.Codeunit.al b/src/System Application/App/Agent/Setup/SetupPart/AgentSetup.Codeunit.al
index fa206bc07b..a54ce15bd3 100644
--- a/src/System Application/App/Agent/Setup/SetupPart/AgentSetup.Codeunit.al
+++ b/src/System Application/App/Agent/Setup/SetupPart/AgentSetup.Codeunit.al
@@ -107,6 +107,18 @@ codeunit 4324 "Agent Setup"
exit(AgentSetupImpl.OpenAgentLookup(AgentUserSecurityId));
end;
+ ///
+ /// Finds the agent user security ID based on the provided user name.
+ ///
+ /// The user name to search for. You can provide a partial or full user name.
+ /// The security ID of the agent user if found, otherwise a null guid.
+ /// True if an agent with the provided user name is found, false otherwise.
+ procedure FindAgentByUserName(AgentUserName: Text; var AgentUserSecurityId: Guid): Boolean
+ begin
+ FeatureAccessManagement.AgentTaskManagementPreviewEnabled(true);
+ exit(AgentSetupImpl.FindAgentByUserName(AgentUserName, AgentUserSecurityId));
+ end;
+
///
/// Allows the user to select an agent out of the list of enabled agents.
///
diff --git a/src/System Application/App/Agent/Setup/SetupPart/AgentSetupImpl.Codeunit.al b/src/System Application/App/Agent/Setup/SetupPart/AgentSetupImpl.Codeunit.al
index 05e7af166c..d3c32ed0cd 100644
--- a/src/System Application/App/Agent/Setup/SetupPart/AgentSetupImpl.Codeunit.al
+++ b/src/System Application/App/Agent/Setup/SetupPart/AgentSetupImpl.Codeunit.al
@@ -91,6 +91,27 @@ codeunit 4325 "Agent Setup Impl."
AgentImpl.OpenSetupPageId(Agent."Agent Metadata Provider", AgentUserSecurityID);
end;
+ [Scope('OnPrem')]
+ procedure FindAgentByUserName(AgentUserName: Text; var AgentUserSecurityId: Guid): Boolean
+ var
+ AgentRec: Record Agent;
+ begin
+ AgentRec.SetRange("User Name", AgentUserName);
+ if AgentRec.FindFirst() then begin
+ AgentUserSecurityId := AgentRec."User Security ID";
+ exit(true);
+ end;
+
+ AgentRec.SetFilter("User Name", '@' + AgentUserName + '*');
+ if AgentRec.FindFirst() then begin
+ AgentUserSecurityId := AgentRec."User Security ID";
+ AgentUserName := AgentRec."User Name";
+ exit(true);
+ end;
+
+ exit(false);
+ end;
+
[Scope('OnPrem')]
procedure OpenAgentLookup(var AgentUserSecurityId: Guid): Boolean
var
diff --git a/src/Tools/AI Test Toolkit/app.json b/src/Tools/AI Test Toolkit/app.json
index 34eaec17ea..40c45f7bab 100644
--- a/src/Tools/AI Test Toolkit/app.json
+++ b/src/Tools/AI Test Toolkit/app.json
@@ -26,6 +26,13 @@
"version": "29.0.0.0"
}
],
+ "internalsVisibleTo": [
+ {
+ "id": "5afe217e-507a-40b4-9aa5-f4325b6e8230",
+ "name": "Agent Test Library",
+ "publisher": "Microsoft"
+ }
+ ],
"screenshots": [],
"platform": "28.0.0.0",
"idRanges": [
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 be5445df80..22abe45fd1 100644
--- a/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al
+++ b/src/Tools/AI Test Toolkit/src/API/AITLogEntryAPI.Page.al
@@ -58,6 +58,16 @@ page 149038 "AIT Log Entry API"
{
Caption = 'Total Tokens Consumed';
}
+ field(copilotCredits; CopilotCredits)
+ {
+ Caption = 'Copilot credits';
+ Editable = false;
+ }
+ field(agentTaskIDs; AgentTaskIDs)
+ {
+ Caption = 'Agent tasks';
+ Editable = false;
+ }
field("startTime"; Rec."Start Time")
{
Caption = 'Start Time';
@@ -127,6 +137,8 @@ page 149038 "AIT Log Entry API"
}
trigger OnAfterGetRecord()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
begin
InputText := Rec.GetInputBlob();
OutputText := Rec.GetOutputBlob();
@@ -134,6 +146,8 @@ page 149038 "AIT Log Entry API"
ErrorCallStackText := Rec.GetErrorCallStack();
SuiteDescription := Rec.GetSuiteDescription();
TestMethodLineDescription := Rec.GetTestMethodLineDescription();
+ CopilotCredits := AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.");
+ AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDsForLogEntry(Rec."Entry No.");
end;
var
@@ -143,4 +157,6 @@ page 149038 "AIT Log Entry API"
ErrorCallStackText: Text;
SuiteDescription: Text[250];
TestMethodLineDescription: Text[250];
+ CopilotCredits: Decimal;
+ 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
new file mode 100644
index 0000000000..fe22dba3c8
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentLogEntries.PageExt.al
@@ -0,0 +1,54 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+pageextension 149030 "Agent Log Entries" extends "AIT Log Entries"
+{
+ layout
+ {
+ addafter("Tokens Consumed")
+ {
+ field("Copilot Credits"; CopilotCredits)
+ {
+ ApplicationArea = All;
+ AutoFormatType = 0;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for this log entry.';
+ Editable = false;
+ }
+ field("Agent Task IDs"; AgentTaskIDs)
+ {
+ ApplicationArea = All;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the comma-separated list of Agent Task IDs related to this log entry.';
+ Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(AgentTaskIDs);
+ end;
+ }
+ }
+ }
+
+ trigger OnAfterGetRecord()
+ begin
+ UpdateAgentTaskMetrics();
+ end;
+
+ local procedure UpdateAgentTaskMetrics()
+ begin
+ CopilotCredits := AgentTestContextImpl.GetCopilotCreditsForLogEntry(Rec."Entry No.");
+ AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDsForLogEntry(Rec."Entry No.");
+ end;
+
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ CopilotCredits: Decimal;
+ AgentTaskIDs: Text;
+}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al
new file mode 100644
index 0000000000..d29f3128b7
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.PageExt.al
@@ -0,0 +1,90 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+pageextension 149032 "Agent Run History" extends "AIT Run History"
+{
+ layout
+ {
+ addafter("Tokens - By Version")
+ {
+ field("Copilot Credits - By Version"; Rec."Copilot Credits")
+ {
+ ApplicationArea = All;
+ AutoFormatType = 0;
+ Visible = ViewBy = ViewBy::Version;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks in the current version.';
+ Editable = false;
+ }
+ field("Agent Task Count - By Version"; AgentTaskCountByVersion)
+ {
+ ApplicationArea = All;
+ Visible = ViewBy = ViewBy::Version;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the number of Agent Tasks related to the current version.';
+ Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(Rec."Agent Task IDs");
+ end;
+ }
+ }
+ addafter("Tokens - By Tag")
+ {
+ field("Copilot Credits - By Tag"; Rec."Copilot Credits - By Tag")
+ {
+ ApplicationArea = All;
+ AutoFormatType = 0;
+ Visible = ViewBy = ViewBy::Tag;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for the tag.';
+ Editable = false;
+ }
+ field("Agent Task Count - By Tag"; AgentTaskCountByTag)
+ {
+ ApplicationArea = All;
+ Visible = ViewBy = ViewBy::Tag;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the number of Agent Tasks related to the tag.';
+ Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(Rec."Agent Task IDs - By Tag");
+ end;
+ }
+ }
+ }
+
+ trigger OnAfterGetRecord()
+ begin
+ UpdateAgentTaskCounts();
+ end;
+
+ trigger OnAfterGetCurrRecord()
+ begin
+ UpdateAgentTaskCounts();
+ end;
+
+ local procedure UpdateAgentTaskCounts()
+ begin
+ AgentTaskCountByVersion := AgentTestContextImpl.GetAgentTaskCount(Rec."Agent Task IDs");
+ AgentTaskCountByTag := AgentTestContextImpl.GetAgentTaskCount(Rec."Agent Task IDs - By Tag");
+ end;
+
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ AgentTaskCountByVersion: Integer;
+ AgentTaskCountByTag: Integer;
+
+}
+
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.TableExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.TableExt.al
new file mode 100644
index 0000000000..7f9bfbf457
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentRunHistory.TableExt.al
@@ -0,0 +1,43 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+tableextension 149030 "Agent Run History" extends "AIT Run History"
+{
+ fields
+ {
+ field(15; "Copilot Credits"; Decimal)
+ {
+ DataClassification = SystemMetadata;
+ AutoFormatType = 0;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks in the current version.';
+ Editable = false;
+ }
+ field(16; "Agent Task IDs"; Text[2048])
+ {
+ DataClassification = SystemMetadata;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the comma-separated list of Agent Task IDs related to the current version.';
+ Editable = false;
+ }
+ field(25; "Copilot Credits - By Tag"; Decimal)
+ {
+ DataClassification = SystemMetadata;
+ AutoFormatType = 0;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for the tag.';
+ Editable = false;
+ }
+ field(26; "Agent Task IDs - By Tag"; Text[2048])
+ {
+ DataClassification = SystemMetadata;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the comma-separated list of Agent Task IDs related to the tag.';
+ Editable = false;
+ }
+ }
+}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al
new file mode 100644
index 0000000000..ee36df594c
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTaskLog.Table.al
@@ -0,0 +1,93 @@
+// ------------------------------------------------------------------------------------------------
+// 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 149050 "Agent Task Log"
+{
+ Caption = 'AI Agent Task Log';
+ DataClassification = SystemMetadata;
+ Extensible = true;
+ Access = Internal;
+ ReplicateData = false;
+ InherentEntitlements = RIMDX;
+ InherentPermissions = RIMDX;
+
+ fields
+ {
+ field(1; "Entry No."; Integer)
+ {
+ Caption = 'Entry No.';
+ AutoIncrement = true;
+ ToolTip = 'Specifies the Log Entry No..';
+ }
+ field(2; "Test Suite Code"; Code[100])
+ {
+ Caption = 'Eval Suite Code';
+ NotBlank = true;
+ TableRelation = "AIT Test Suite";
+ ToolTip = 'Specifies the Eval Suite Code.';
+ }
+ field(3; "Test Method Line No."; Integer)
+ {
+ Caption = 'Line No.';
+ ToolTip = 'Specifies the Test Method Line No.';
+ }
+ field(10; Status; Option)
+ {
+ Caption = 'Status';
+ OptionMembers = Success,Error;
+ ToolTip = 'Specifies the status of the iteration.';
+ }
+ field(11; Operation; Text[100])
+ {
+ Caption = 'Operation';
+ ToolTip = 'Specifies the operation.';
+ }
+ field(13; Version; Integer)
+ {
+ Caption = 'Version';
+ ToolTip = 'Specifies the Version No. of the eval run.';
+ }
+ field(15; Tag; Text[20])
+ {
+ DataClassification = CustomerContent;
+ Caption = 'Tag';
+ ToolTip = 'Specifies the Tag that we entered in the AI Eval Suite.';
+ }
+ field(17; "Procedure Name"; Text[128])
+ {
+ Caption = 'Procedure Name';
+ DataClassification = CustomerContent;
+ ToolTip = 'Specifies the name of the procedure being executed.';
+ }
+ field(5000; "Agent Task ID"; BigInteger)
+ {
+ Caption = 'Agent Task ID';
+ NotBlank = true;
+ ToolTip = 'Specifies the Agent Task ID.';
+ }
+ field(5001; "Test Log Entry ID"; Integer)
+ {
+ Caption = 'Test Log Entry ID';
+ ToolTip = 'Specifies the AIT Log Entry ID that this agent task is associated with.';
+ }
+ }
+
+ keys
+ {
+ key(Key1; "Entry No.")
+ {
+ Clustered = true;
+ }
+ key(Key2; "Test Suite Code", Version, "Test Method Line No.", "Agent Task ID", Operation, "Procedure Name")
+ {
+ IncludedFields = Status;
+ }
+ key(Key3; "Test Log Entry ID", "Agent Task ID")
+ {
+ }
+ }
+}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestContext.Codeunit.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContext.Codeunit.al
new file mode 100644
index 0000000000..9aed28fc36
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContext.Codeunit.al
@@ -0,0 +1,37 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+///
+/// Exposes Agent specific functionality that can be used by the AI tests.
+///
+codeunit 149048 "Agent Test Context"
+{
+ SingleInstance = true;
+ InherentEntitlements = X;
+ InherentPermissions = X;
+
+ ///
+ /// Gets the user security ID of the agent that is used by the test suite.
+ ///
+ /// The user security ID of the agent used by the test suite. If no agent is set, a null GUID is returned.
+ procedure GetAgentUserSecurityID(var AgentUserSecurityID: Guid)
+ begin
+ AgentTestContextImpl.GetAgentUserSecurityID(AgentUserSecurityID);
+ end;
+
+ ///
+ /// Adds agent task to be reported as used by the test
+ ///
+ /// The id of the agent task to be added to the log.
+ procedure AddTaskToLog(AgentTaskId: BigInteger)
+ begin
+ AgentTestContextImpl.AddTaskToLog(AgentTaskId);
+ end;
+
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+}
\ No newline at end of file
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al
new file mode 100644
index 0000000000..0b130f819b
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestContextImpl.Codeunit.al
@@ -0,0 +1,245 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+using System.Agents;
+using System.TestTools.TestRunner;
+
+codeunit 149049 "Agent Test Context Impl."
+{
+ SingleInstance = true;
+ Access = Internal;
+ InherentEntitlements = X;
+ InherentPermissions = X;
+
+ procedure GetAgentUserSecurityID(var AgentUserSecurityID: Guid)
+ begin
+ AgentUserSecurityID := GlobalAgentUserSecurityID;
+ end;
+
+ procedure AddTaskToLog(AgentTaskId: BigInteger)
+ begin
+ if not AgentTaskList.Contains(AgentTaskId) then
+ AgentTaskList.Add(AgentTaskId);
+ end;
+
+ procedure ClearTaskLog()
+ begin
+ Clear(AgentTaskList);
+ end;
+
+ procedure LogAgentTasks(var AITLogEntry: Record "AIT Log Entry")
+ var
+ AgentTaskId: BigInteger;
+ begin
+ if AgentTaskList.Count() = 0 then
+ exit;
+
+ foreach AgentTaskId in AgentTaskList do
+ LogAgentTask(AgentTaskId, AITLogEntry);
+
+ ClearTaskLog();
+ end;
+
+ local procedure LogAgentTask(AgentTaskId: BigInteger; var AITLogEntry: Record "AIT Log Entry")
+ var
+ AgentTaskLog: Record "Agent Task Log";
+ begin
+ AgentTaskLog.TransferFields(AITLogEntry, false);
+ AgentTaskLog."Agent Task ID" := AgentTaskId;
+ AgentTaskLog."Test Log Entry ID" := AITLogEntry."Entry No.";
+ AgentTaskLog.Insert();
+ end;
+
+ procedure GetAgentTaskIDsForLogEntry(LogEntryNo: Integer): Text
+ var
+ AgentTaskLog: Record "Agent Task Log";
+ begin
+ AgentTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
+ exit(GetAgentTaskIDs(AgentTaskLog));
+ end;
+
+ procedure GetAgentTaskIDs(TestSuiteCode: Code[100]; VersionNumber: Integer; Tag: Text[20]; TestMethodLineNo: Integer): Text
+ var
+ VersionFilterText: Text;
+ 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";
+ begin
+ AgentTaskLog.SetRange("Test Suite Code", TestSuiteCode);
+ if Tag <> '' then
+ AgentTaskLog.SetRange(Tag, Tag);
+ if VersionFilter <> '' then
+ AgentTaskLog.SetFilter(Version, VersionFilter);
+ if TestMethodLineNo > 0 then
+ AgentTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
+
+ exit(GetAgentTaskIDs(AgentTaskLog));
+ end;
+
+ procedure GetCopilotCreditsForLogEntry(LogEntryNo: Integer): Decimal
+ var
+ AgentTaskLog: Record "Agent Task Log";
+
+ begin
+ AgentTaskLog.SetRange("Test Log Entry ID", LogEntryNo);
+ exit(GetCopilotCredits(AgentTaskLog));
+ end;
+
+ procedure GetCopilotCredits(TestSuiteCode: Code[100]; VersionNumber: Integer; Tag: Text[20]; TestMethodLineNo: Integer): Decimal
+ var
+ VersionFilterText: Text;
+ begin
+ if VersionNumber > 0 then
+ VersionFilterText := Format(VersionNumber);
+ exit(GetCopilotCredits(TestSuiteCode, VersionFilterText, Tag, TestMethodLineNo));
+ end;
+
+ procedure GetCopilotCredits(TestSuiteCode: Code[100]; VersionFilter: Text; Tag: Text[20]; TestMethodLineNo: Integer): Decimal
+ var
+ AgentTaskLog: Record "Agent Task Log";
+ begin
+ AgentTaskLog.SetRange("Test Suite Code", TestSuiteCode);
+ if VersionFilter <> '' then
+ AgentTaskLog.SetFilter(Version, VersionFilter);
+
+ if Tag <> '' then
+ AgentTaskLog.SetRange(Tag, Tag);
+
+ if TestMethodLineNo > 0 then
+ AgentTaskLog.SetRange("Test Method Line No.", TestMethodLineNo);
+
+ exit(GetCopilotCredits(AgentTaskLog));
+ end;
+
+ local procedure GetCopilotCredits(var AgentTaskLog: Record "Agent Task Log"): Decimal
+ var
+ AgentTask: Codeunit "Agent Task";
+ TaskIDList: List of [BigInteger];
+ TotalCredits: Decimal;
+ begin
+ if AgentTaskLog.FindSet() then
+ repeat
+ if not TaskIDList.Contains(AgentTaskLog."Agent Task ID") then begin
+ TaskIDList.Add(AgentTaskLog."Agent Task ID");
+ TotalCredits += AgentTask.GetCopilotCreditsConsumed(AgentTaskLog."Agent Task ID");
+ end;
+ until AgentTaskLog.Next() = 0;
+
+ exit(TotalCredits);
+ end;
+
+ procedure GetAgentTaskCount(CommaSeparatedTaskIDs: Text): Integer
+ var
+ TaskIDList: List of [Text];
+ begin
+ if CommaSeparatedTaskIDs = '' then
+ exit(0);
+
+ TaskIDList := CommaSeparatedTaskIDs.Split(',');
+ exit(TaskIDList.Count());
+ end;
+
+ procedure OpenAgentTaskList(CommaSeparatedTaskIDs: Text)
+ var
+ AgentTask: Record "Agent Task";
+ AgentTaskListPage: Page "Agent Task List";
+ FilterText: Text;
+ begin
+ FilterText := ConvertCommaSeparatedToFilter(CommaSeparatedTaskIDs);
+ if FilterText = '' then
+ exit;
+
+ AgentTask.SetFilter(ID, FilterText);
+ AgentTaskListPage.SetTableView(AgentTask);
+ AgentTaskListPage.Run();
+ end;
+
+ local procedure GetAgentTaskIDs(var AgentTaskLog: Record "Agent Task Log"): Text
+ var
+ TaskIDList: List of [BigInteger];
+ TaskIDTextList: List of [Text];
+ begin
+ if AgentTaskLog.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"));
+ end;
+ until AgentTaskLog.Next() = 0;
+
+ exit(ConcatenateList(TaskIDTextList, ', '));
+ end;
+
+ local procedure ConvertCommaSeparatedToFilter(CommaSeparatedValues: Text): Text
+ var
+ FilterTextBuilder: TextBuilder;
+ Values: List of [Text];
+ CurrentValue: Text;
+ IsFirst: Boolean;
+ begin
+ if CommaSeparatedValues = '' then
+ exit('');
+
+ Values := CommaSeparatedValues.Split(',');
+ IsFirst := true;
+ foreach CurrentValue in Values do begin
+ CurrentValue := CurrentValue.Trim();
+ if CurrentValue <> '' then
+ if IsFirst then begin
+ FilterTextBuilder.Append(CurrentValue);
+ IsFirst := false;
+ end else
+ FilterTextBuilder.Append('|' + CurrentValue);
+ end;
+ exit(FilterTextBuilder.ToText());
+ end;
+
+ local procedure ConcatenateList(TextList: List of [Text]; Separator: Text): Text
+ var
+ Result: Text;
+ Item: Text;
+ IsFirst: Boolean;
+ begin
+ IsFirst := true;
+ foreach Item in TextList do
+ if IsFirst then begin
+ Result := Item;
+ IsFirst := false;
+ end else
+ Result += Separator + Item;
+
+ exit(Result);
+ end;
+
+ [EventSubscriber(ObjectType::Codeunit, Codeunit::"Test Runner - Mgt", OnRunTestSuite, '', false, false)]
+ local procedure OnRunTestSuite(var TestMethodLine: Record "Test Method Line")
+ var
+ AITTestSuite: Record "AIT Test Suite";
+ Agent: Codeunit Agent;
+ AITTestContext: Codeunit "AIT Test Context";
+ begin
+ AITTestContext.GetAITTestSuite(AITTestSuite);
+
+ if IsNullGuid(AITTestSuite."Agent User Security ID") then
+ exit;
+
+ GlobalAgentUserSecurityID := AITTestSuite."Agent User Security ID";
+ if not Agent.IsActive(GlobalAgentUserSecurityID) then
+ Error(AgentIsNotActiveErr, AITTestSuite.Code, AITTestSuite."Agent User Security ID");
+ end;
+
+ var
+ AgentTaskList: List of [BigInteger];
+ GlobalAgentUserSecurityID: Guid;
+ AgentIsNotActiveErr: Label 'Agent %1 set on suite %2 is not active.', Comment = '%1 = Agent ID, %2 = Suite Code';
+}
\ No newline at end of file
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al
new file mode 100644
index 0000000000..b7b88c7672
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestMethodLines.PageExt.al
@@ -0,0 +1,68 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+pageextension 149033 "Agent Test Method Lines" extends "AIT Test Method Lines"
+{
+ layout
+ {
+ addafter("Tokens Consumed")
+ {
+ field("Copilot Credits"; CopilotCredits)
+ {
+ ApplicationArea = All;
+ AutoFormatType = 0;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks for this eval line.';
+ Editable = false;
+ }
+ field("Agent Task Count"; AgentTaskCount)
+ {
+ ApplicationArea = All;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the number of Agent Tasks related to this eval line.';
+ Editable = false;
+
+ trigger OnDrillDown()
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(AgentTaskIDs);
+ end;
+ }
+ }
+ }
+
+ trigger OnAfterGetRecord()
+ begin
+ UpdateAgentTaskMetrics();
+ end;
+
+ trigger OnAfterGetCurrRecord()
+ begin
+ UpdateAgentTaskMetrics();
+ end;
+
+ local procedure UpdateAgentTaskMetrics()
+ var
+ VersionFilter: Text;
+ CurrentFilterGroup: Integer;
+ begin
+ CurrentFilterGroup := Rec.FilterGroup();
+ Rec.FilterGroup(4);
+ VersionFilter := Rec.GetFilter(Rec."Version Filter");
+ Rec.FilterGroup(CurrentFilterGroup);
+ 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;
+
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ CopilotCredits: Decimal;
+ AgentTaskIDs: Text;
+ AgentTaskCount: Integer;
+}
diff --git a/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al
new file mode 100644
index 0000000000..db589ca600
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.PageExt.al
@@ -0,0 +1,122 @@
+// ------------------------------------------------------------------------------------------------
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+// ------------------------------------------------------------------------------------------------
+
+namespace System.TestLibraries.Agents;
+
+using System.Agents;
+using System.TestTools.AITestToolkit;
+
+pageextension 149034 "Agent Test Suite" extends "AIT Test Suite"
+{
+ layout
+ {
+ addafter("Test Runner Id")
+ {
+ field(TestSuiteAgent; AgentUserName)
+ {
+ ApplicationArea = All;
+ Caption = 'Agent';
+ ToolTip = 'Specifies the agent to be used by the tests. You can use this field to test different configurations without changing the code. If you manually configure the agent and set it on the suite, this instance will be used in the eval runs. If you leave it blank, the system will automatically create an agent for each run.';
+
+ trigger OnValidate()
+ begin
+ ValidateAgentName();
+ end;
+
+ trigger OnAssistEdit()
+ begin
+ LookupAgent();
+ end;
+ }
+ }
+ addlast("Latest Run")
+ {
+ field("Copilot Credits"; CopilotCredits)
+ {
+ ApplicationArea = All;
+ AutoFormatType = 0;
+ Editable = false;
+ Caption = 'Copilot credits';
+ ToolTip = 'Specifies the total Copilot Credits consumed by the Agent Tasks in the current version.';
+ }
+ field("Agent Task Count"; AgentTaskCount)
+ {
+ ApplicationArea = All;
+ Editable = false;
+ Caption = 'Agent tasks';
+ ToolTip = 'Specifies the number of Agent Tasks related to the current version.';
+
+ trigger OnDrillDown()
+ begin
+ AgentTestContextImpl.OpenAgentTaskList(AgentTaskIDs);
+ end;
+ }
+ }
+ }
+
+ trigger OnAfterGetCurrRecord()
+ begin
+ UpdateAgentTaskMetrics();
+ UpdateAgentUserName();
+ end;
+
+ local procedure UpdateAgentTaskMetrics()
+ begin
+ CopilotCredits := AgentTestContextImpl.GetCopilotCredits(Rec.Code, Rec.Version, '', 0);
+ AgentTaskIDs := AgentTestContextImpl.GetAgentTaskIDs(Rec.Code, Rec.Version, '', 0);
+ AgentTaskCount := AgentTestContextImpl.GetAgentTaskCount(AgentTaskIDs);
+ end;
+
+ local procedure UpdateAgentUserName()
+ var
+ Agent: Codeunit Agent;
+ begin
+ AgentUserName := '';
+
+ if IsNullGuid(Rec."Agent User Security ID") then
+ exit;
+
+ AgentUserName := Agent.GetUserName(Rec."Agent User Security ID");
+ end;
+
+ local procedure LookupAgent()
+ var
+ AgentSetup: Codeunit "Agent Setup";
+ Agent: Codeunit Agent;
+ AgentUserSecurityId: Guid;
+ begin
+ if not AgentSetup.OpenAgentLookup(AgentUserSecurityId) then
+ exit;
+ Rec."Agent User Security ID" := AgentUserSecurityId;
+ AgentUserName := Agent.GetUserName(AgentUserSecurityId);
+ Rec.Modify();
+ end;
+
+ local procedure ValidateAgentName()
+ var
+ AgentSetup: Codeunit "Agent Setup";
+ Agent: Codeunit Agent;
+ begin
+ if AgentUserName = '' then begin
+ Clear(Rec."Agent User Security ID");
+ Rec.Modify();
+ exit;
+ end;
+
+ if not AgentSetup.FindAgentByUserName(AgentUserName, Rec."Agent User Security ID") then
+ Error(AgentWithNameNotFoundErr, AgentUserName);
+
+ AgentUserName := Agent.GetUserName(Rec."Agent User Security ID");
+ Rec.Modify();
+ end;
+
+ var
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
+ CopilotCredits: Decimal;
+ AgentTaskIDs: Text;
+ AgentTaskCount: Integer;
+ AgentUserName: Code[50];
+ 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/AgentTestSuite.TableExt.al b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.TableExt.al
new file mode 100644
index 0000000000..8ba265aa2a
--- /dev/null
+++ b/src/Tools/AI Test Toolkit/src/Agent/AgentTestSuite.TableExt.al
@@ -0,0 +1,19 @@
+// ------------------------------------------------------------------------------------------------
+// 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;
+
+tableextension 149050 "Agent Test Suite" extends "AIT Test Suite"
+{
+ fields
+ {
+ field(4900; "Agent User Security ID"; Guid)
+ {
+ DataClassification = SystemMetadata;
+ Caption = 'Agent User Security ID';
+ ToolTip = 'Specifies the agent to be used by the test suite.';
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al
index ead956f417..162944de18 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITLogEntry.Table.al
@@ -179,7 +179,7 @@ table 149034 "AIT Log Entry"
field(50; "Tokens Consumed"; Integer)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
}
}
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Codeunit.al b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Codeunit.al
index 436dfc6137..dfb6953b13 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Codeunit.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Codeunit.al
@@ -12,6 +12,7 @@ codeunit 149036 "AIT Run History"
procedure GetHistory(Code: Code[100]; LineNo: Integer; AITViewBy: Enum "AIT Run History - View By"; var TempAITRunHistory: Record "AIT Run History" temporary)
var
AITRunHistory: Record "AIT Run History";
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
SeenTags: List of [Text[20]];
begin
TempAITRunHistory.DeleteAll();
@@ -21,6 +22,8 @@ codeunit 149036 "AIT Run History"
if AITRunHistory.FindSet() then
repeat
TempAITRunHistory.TransferFields(AITRunHistory);
+ TempAITRunHistory."Copilot Credits" := AgentTestContextImpl.GetCopilotCredits(AITRunHistory."Test Suite Code", AITRunHistory.Version, '', LineNo);
+ TempAITRunHistory."Agent Task IDs" := CopyStr(AgentTestContextImpl.GetAgentTaskIDs(AITRunHistory."Test Suite Code", AITRunHistory.Version, '', LineNo), 1, MaxStrLen(TempAITRunHistory."Agent Task IDs"));
TempAITRunHistory.Insert();
until AITRunHistory.Next() = 0;
@@ -29,6 +32,8 @@ codeunit 149036 "AIT Run History"
repeat
if not SeenTags.Contains(AITRunHistory.Tag) then begin
TempAITRunHistory.TransferFields(AITRunHistory);
+ TempAITRunHistory."Copilot Credits - By Tag" := AgentTestContextImpl.GetCopilotCredits(AITRunHistory."Test Suite Code", '', AITRunHistory.Tag, LineNo);
+ TempAITRunHistory."Agent Task IDs - By Tag" := CopyStr(AgentTestContextImpl.GetAgentTaskIDs(AITRunHistory."Test Suite Code", '', AITRunHistory.Tag, LineNo), 1, MaxStrLen(TempAITRunHistory."Agent Task IDs - By Tag"));
TempAITRunHistory.Insert();
end;
SeenTags.Add(AITRunHistory.Tag);
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al
index db6a7b8429..1cc83a4de3 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Page.al
@@ -137,7 +137,7 @@ page 149032 "AIT Run History"
{
Visible = ViewBy = ViewBy::Version;
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
}
field("No. of Tests - By Tag"; Rec."No. of Tests Executed - By Tag")
{
@@ -183,7 +183,7 @@ page 149032 "AIT Run History"
{
Visible = ViewBy = ViewBy::Tag;
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
}
}
}
@@ -192,11 +192,13 @@ page 149032 "AIT Run History"
var
TestSuiteCode: Code[100];
- ViewBy: Enum "AIT Run History - View By";
LineNo: Integer;
ApplyLineFilter: Boolean;
LineNoFilter: Text;
+ protected var
+ ViewBy: Enum "AIT Run History - View By";
+
trigger OnOpenPage()
begin
UpdateRunHistory();
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al
index 6144bbe2a7..828bf92d63 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITRunHistory.Table.al
@@ -9,7 +9,6 @@ table 149036 "AIT Run History"
{
Caption = 'AI Eval Run History';
DataClassification = SystemMetadata;
- Extensible = false;
Access = Internal;
ReplicateData = false;
@@ -68,7 +67,7 @@ table 149036 "AIT Run History"
field(13; "Tokens Consumed"; Integer)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
Editable = false;
FieldClass = FlowField;
CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Test Suite Code"), Version = field("Version"), "Test Method Line No." = field("Line No. Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> '')));
@@ -109,7 +108,7 @@ table 149036 "AIT Run History"
field(23; "Tokens Consumed - By Tag"; Integer)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
Editable = false;
FieldClass = FlowField;
CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No. Filter"), Tag = field(Tag), Operation = const('Run Procedure'), "Procedure Name" = filter(<> '')));
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITTestMethodLinesCompare.Page.al b/src/Tools/AI Test Toolkit/src/Logs/AITTestMethodLinesCompare.Page.al
index 8e68da352b..76220b95d3 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITTestMethodLinesCompare.Page.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITTestMethodLinesCompare.Page.al
@@ -81,7 +81,7 @@ page 149035 "AIT Test Method Lines Compare"
label(TokensConsumed)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
}
}
group("Latest Version")
diff --git a/src/Tools/AI Test Toolkit/src/Logs/AITTestSuiteCompare.Page.al b/src/Tools/AI Test Toolkit/src/Logs/AITTestSuiteCompare.Page.al
index b3f46516e6..effa4c7a8c 100644
--- a/src/Tools/AI Test Toolkit/src/Logs/AITTestSuiteCompare.Page.al
+++ b/src/Tools/AI Test Toolkit/src/Logs/AITTestSuiteCompare.Page.al
@@ -82,7 +82,7 @@ page 149036 "AIT Test Suite Compare"
label(TokensConsumed)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
}
}
group("Latest Version")
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 93cae23b30..aa1e158f09 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLine.Table.al
@@ -209,21 +209,27 @@ table 149032 "AIT Test Method Line"
field(120; "Tokens Consumed"; Integer)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
Editable = false;
FieldClass = FlowField;
CalcFormula = sum("AIT Log Entry"."Tokens Consumed" 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(<> '')));
}
+#if not CLEAN26
+#pragma warning disable AS0072
field(121; "Tokens Consumed - Base"; Integer)
{
+ ObsoleteState = Pending;
+ ObsoleteReason = 'This field is deprecated as it is not used in any page or calculation. It will be removed in future versions.';
+ ObsoleteTag = '26.0';
Caption = 'Tokens Consumed - Base';
- ToolTip = 'Specifies the number of tokens consumed by the eval in the base version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the number of tokens consumed by the eval in the base version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
Editable = false;
FieldClass = FlowField;
CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Test Suite Code"), "Test Method Line No." = field("Line No."), Version = field("Base Version Filter"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> '')));
}
+#pragma warning restore AS0072
+#endif
}
-
keys
{
key(Key1; "Test Suite Code", "Line No.")
diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al
index 974260ef8b..c107aa04f2 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestMethodLines.Page.al
@@ -276,6 +276,16 @@ page 149034 "AIT Test Method Lines"
end;
trigger OnAfterGetRecord()
+ begin
+ UpdateControls();
+ end;
+
+ trigger OnAfterGetCurrRecord()
+ begin
+ UpdateControls();
+ end;
+
+ local procedure UpdateControls()
begin
EvaluationSetupTxt := AITTestSuiteMgt.GetEvaluationSetupText(CopyStr(Rec."Test Suite Code", 1, 10), Rec."Line No.");
TurnsText := AITTestSuiteMgt.GetTurnsAsText(Rec);
diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al
index e7c71dc3ba..600b7d37df 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Page.al
@@ -33,6 +33,10 @@ page 149031 "AIT Test Suite"
field(Description; Rec.Description)
{
}
+ field(TestType; Rec."Test Type")
+ {
+ Importance = Additional;
+ }
field(Dataset; Rec."Input Dataset")
{
ShowMandatory = true;
@@ -219,7 +223,7 @@ page 149031 "AIT Test Suite"
{
Editable = false;
Caption = 'Average Tokens Consumed';
- ToolTip = 'Specifies the average number of tokens consumed by the evals in the last run.';
+ ToolTip = 'Specifies the average number of tokens consumed by the evals in the last run. Tokens consumed by agent sessions are not included in this number.';
}
}
diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al
index c743b39bbc..a358a1079b 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuite.Table.al
@@ -167,7 +167,7 @@ table 149030 "AIT Test Suite"
field(24; "Tokens Consumed"; Integer)
{
Caption = 'Total Tokens Consumed';
- ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module.';
+ ToolTip = 'Specifies the aggregated number of tokens consumed by the eval in the current version. This is applicable only when using Microsoft AI Module. Tokens consumed by agent sessions are not included in this number.';
Editable = false;
FieldClass = FlowField;
CalcFormula = sum("AIT Log Entry"."Tokens Consumed" where("Test Suite Code" = field("Code"), Version = field("Version"), Operation = const('Run Procedure'), "Procedure Name" = filter(<> '')));
diff --git a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al
index bcb32cf979..9c2efd3bb1 100644
--- a/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al
+++ b/src/Tools/AI Test Toolkit/src/TestSuite/AITTestSuiteMgt.Codeunit.al
@@ -163,10 +163,12 @@ codeunit 149034 "AIT Test Suite Mgt."
var
AITRunHistory: Record "AIT Run History";
AITTestContext: Codeunit "AIT Test Context";
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
begin
AITRunHistory."Test Suite Code" := Code;
AITRunHistory.Version := Version;
AITRunHistory.Tag := Tag;
+ AITRunHistory."Copilot Credits" := AgentTestContextImpl.GetCopilotCredits(Code, Version, Tag, 0);
AITRunHistory.Insert();
AITTestContext.OnAfterRunComplete(Code, Version, Tag);
@@ -331,6 +333,7 @@ codeunit 149034 "AIT Test Suite Mgt."
TestInput: Record "Test Input";
AITTestRunIteration: Codeunit "AIT Test Run Iteration"; // single instance
TestSuiteMgt: Codeunit "Test Suite Mgt.";
+ AgentTestContextImpl: Codeunit "Agent Test Context Impl.";
ModifiedOperation: Text;
ModifiedExecutionSuccess: Boolean;
ModifiedMessage: Text;
@@ -397,6 +400,7 @@ codeunit 149034 "AIT Test Suite Mgt."
AITLogEntry."No. of Turns Passed" := AITTestRunIteration.GetNumberOfTurnsPassedForLastTestMethodLine();
AITLogEntry."Test Method Line Accuracy" := AITTestRunIteration.GetAccuracyForLastTestMethodLine();
AITLogEntry.Insert(true);
+ AgentTestContextImpl.LogAgentTasks(AITLogEntry);
Commit();
AITTestRunIteration.AddToNoOfLogEntriesInserted();