Skip to content

Commit e6dc2b3

Browse files
authored
Agent Cost Calculation Fix (#64)
2 parents d6ff4e4 + f58ccf0 commit e6dc2b3

File tree

15 files changed

+642
-32
lines changed

15 files changed

+642
-32
lines changed

src/AnalyticsEngine/Common/DataUtils/Sql/Inserts/InsertBatchTypeFieldCache.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class InsertBatchTypeFieldCache<T>
1515
static List<Type> _validTempColumnTypes = new List<Type>()
1616
{
1717
typeof(string), typeof(DateTime), typeof(DateTime?), typeof(int), typeof(float), typeof(double), typeof(bool), typeof(Guid), typeof(int?),
18-
typeof(int?), typeof(double?)
18+
typeof(int?), typeof(double?), typeof(bool?)
1919
};
2020

2121
public List<InsertBatchPropertyMapping> PropertyMappingInfo
@@ -95,6 +95,10 @@ public List<InsertBatchPropertyMapping> PropertyMappingInfo
9595
{
9696
return ("bit", false);
9797
}
98+
else if (propertyType == typeof(bool?))
99+
{
100+
return ("bit", true);
101+
}
98102
else if (propertyType == typeof(Guid))
99103
{
100104
return ("uniqueidentifier", false);

src/AnalyticsEngine/Common/Entities/Entities.csproj

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,10 @@
263263
<Compile Include="Migrations\202511211834002_CopilotExtendedData.Designer.cs">
264264
<DependentUpon>202511211834002_CopilotExtendedData.cs</DependentUpon>
265265
</Compile>
266+
<Compile Include="Migrations\202512011404129_CopilotExtendedDataAgentType.cs" />
267+
<Compile Include="Migrations\202512011404129_CopilotExtendedDataAgentType.Designer.cs">
268+
<DependentUpon>202512011404129_CopilotExtendedDataAgentType.cs</DependentUpon>
269+
</Compile>
266270
<Compile Include="Migrations\v1-0-5.cs" />
267271
<Compile Include="Migrations\v1-0-5.Designer.cs">
268272
<DependentUpon>v1-0-5.cs</DependentUpon>
@@ -380,6 +384,9 @@
380384
<EmbeddedResource Include="Migrations\202511211834002_CopilotExtendedData.resx">
381385
<DependentUpon>202511211834002_CopilotExtendedData.cs</DependentUpon>
382386
</EmbeddedResource>
387+
<EmbeddedResource Include="Migrations\202512011404129_CopilotExtendedDataAgentType.resx">
388+
<DependentUpon>202512011404129_CopilotExtendedDataAgentType.cs</DependentUpon>
389+
</EmbeddedResource>
383390
<EmbeddedResource Include="Migrations\v1-0-5.resx">
384391
<DependentUpon>v1-0-5.cs</DependentUpon>
385392
</EmbeddedResource>

src/AnalyticsEngine/Common/Entities/Entities/AuditLog/CopilotEvents.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ public class CopilotAgent : AbstractEFEntityWithName
102102
{
103103
[Column("agent_id")]
104104
public string AgentID { get; set; } = null;
105+
106+
/// <summary>
107+
/// Indicates whether this is a custom agent (extracted from AppIdentity) or a standard Copilot agent.
108+
/// Nullable to support backward compatibility with existing data.
109+
/// </summary>
110+
[Column("is_custom_agent")]
111+
public bool? IsCustomAgent { get; set; }
105112
}
106113

107114
/// <summary>

src/AnalyticsEngine/Common/Entities/Migrations/202511211834002_CopilotExtendedData.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public override void Up()
119119
AddColumn("dbo.copilot_chats", "copilot_credit_estimate_total", c => c.Int());
120120
AddColumn("dbo.copilot_chats", "copilot_credit_estimate_json", c => c.String());
121121

122-
Console.WriteLine("DB SCHEMA: Rolled back all Copilot extended data tables.");
122+
Console.WriteLine("DB SCHEMA: Applied 'Copilot extended data tables' succesfully.");
123123
}
124124

125125
public override void Down()

src/AnalyticsEngine/Common/Entities/Migrations/202512011404129_CopilotExtendedDataAgentType.Designer.cs

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Common.Entities.Migrations
2+
{
3+
using System;
4+
using System.Data.Entity.Migrations;
5+
6+
public partial class CopilotExtendedDataAgentType : DbMigration
7+
{
8+
public override void Up()
9+
{
10+
AddColumn("dbo.copilot_agents", "is_custom_agent", c => c.Boolean());
11+
12+
Console.WriteLine("DB SCHEMA: Applied 'Copilot agent type' succesfully.");
13+
}
14+
15+
public override void Down()
16+
{
17+
DropColumn("dbo.copilot_agents", "is_custom_agent");
18+
}
19+
}
20+
}

src/AnalyticsEngine/Common/Entities/Migrations/202512011404129_CopilotExtendedDataAgentType.resx

Lines changed: 126 additions & 0 deletions
Large diffs are not rendered by default.

src/AnalyticsEngine/Tests.UnitTests/CopilotExtendedDataTests.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public void Copilot_CostEstimation_GenerativeAnswersOnly_CalculatesCorrectly()
5050
}";
5151

5252
// Act
53-
var cost = CopilotCreditEstimation.Analyze(json);
53+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
5454

5555
// Assert
5656
// 3 messages × 2 credits = 6 credits
@@ -79,7 +79,7 @@ public void Copilot_CostEstimation_TenantGraphGrounding_CalculatesCorrectly()
7979
}";
8080

8181
// Act
82-
var cost = CopilotCreditEstimation.Analyze(json);
82+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
8383

8484
// Assert
8585
// 3 messages × (2 credits generative + 10 credits tenant graph) = 36 credits
@@ -129,7 +129,7 @@ public void Copilot_CostEstimation_DeepReasoningWithTenantGraph_CalculatesCorrec
129129
}";
130130

131131
// Act
132-
var cost = CopilotCreditEstimation.Analyze(json);
132+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
133133

134134
// Assert
135135
// 3 messages × 2 credits (generative) = 6 credits
@@ -163,7 +163,7 @@ public void Copilot_CostEstimation_DeepReasoningWithoutTenantGraph_CalculatesCor
163163
}";
164164

165165
// Act
166-
var cost = CopilotCreditEstimation.Analyze(json);
166+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
167167

168168
// Assert
169169
// 2 messages × 2 credits (generative) = 4 credits
@@ -191,7 +191,7 @@ public void Copilot_CostEstimation_OneDriveResources_DetectedAsTenantGraph()
191191
}";
192192

193193
// Act
194-
var cost = CopilotCreditEstimation.Analyze(json);
194+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
195195

196196
// Assert
197197
// 1 message × (2 + 10) = 12 credits
@@ -213,7 +213,7 @@ public void Copilot_CostEstimation_TeamsAsyncGatewayResources_DetectedAsTenantGr
213213
}";
214214

215215
// Act
216-
var cost = CopilotCreditEstimation.Analyze(json);
216+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
217217

218218
// Assert
219219
Assert.AreEqual(12, cost.TotalCredits);
@@ -237,7 +237,7 @@ public void Copilot_CostEstimation_MultipleResourceTypes_CountedOnce()
237237
}";
238238

239239
// Act
240-
var cost = CopilotCreditEstimation.Analyze(json);
240+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
241241

242242
// Assert
243243
// Still just 1 message × (2 + 10) = 12 credits (not multiplied by resource count)
@@ -249,9 +249,9 @@ public void Copilot_CostEstimation_MultipleResourceTypes_CountedOnce()
249249
public void Copilot_CostEstimation_NullOrEmptyInput_ReturnsZero()
250250
{
251251
// Arrange & Act
252-
var costNull = CopilotCreditEstimation.Analyze((string)null);
253-
var costEmpty = CopilotCreditEstimation.Analyze("");
254-
var costWhitespace = CopilotCreditEstimation.Analyze(" ");
252+
var costNull = CopilotCreditEstimation.Analyze((string)null, isCustomAgent: true);
253+
var costEmpty = CopilotCreditEstimation.Analyze("", isCustomAgent: true);
254+
var costWhitespace = CopilotCreditEstimation.Analyze(" ", isCustomAgent: true);
255255

256256
// Assert
257257
Assert.AreEqual(0, costNull.TotalCredits);
@@ -271,7 +271,7 @@ public void Copilot_CostEstimation_NoMessages_ReturnsZero()
271271
}";
272272

273273
// Act
274-
var cost = CopilotCreditEstimation.Analyze(json);
274+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
275275

276276
// Assert
277277
Assert.AreEqual(0, cost.TotalCredits);
@@ -290,7 +290,7 @@ public void Copilot_CostEstimation_OnlyPromptMessages_ReturnsZero()
290290
}";
291291

292292
// Act
293-
var cost = CopilotCreditEstimation.Analyze(json);
293+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
294294

295295
// Assert
296296
Assert.AreEqual(0, cost.TotalCredits);
@@ -315,7 +315,7 @@ public void Copilot_CostEstimation_ResourceTypeBreakdown_PopulatedCorrectly()
315315
}";
316316

317317
// Act
318-
var cost = CopilotCreditEstimation.Analyze(json);
318+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
319319

320320
// Assert
321321
Assert.AreEqual(2, cost.ResourceTypeBreakdown["docx"]);
@@ -338,7 +338,7 @@ public void Copilot_CostEstimation_CaseInsensitiveModelDetection_WorksCorrectly(
338338
}";
339339

340340
// Act
341-
var cost = CopilotCreditEstimation.Analyze(json);
341+
var cost = CopilotCreditEstimation.Analyze(json, isCustomAgent: true);
342342

343343
// Assert
344344
Assert.AreEqual(7, cost.TotalCredits); // 2 + 5
@@ -1075,7 +1075,7 @@ public async Task Copilot_SaveCopilotEvent_WithDeepReasoningModel_CalculatesCost
10751075
Assert.AreEqual("DEEP_LEO", aiModels[0].AIModel.Name);
10761076

10771077
// Assert - Verify cost calculation
1078-
var cost = CopilotCreditEstimation.Analyze(auditLogContent.ParsedAuditEvent);
1078+
var cost = CopilotCreditEstimation.Analyze(auditLogContent.ParsedAuditEvent, isCustomAgent: true);
10791079
// 2 messages × (2 generative + 10 tenant graph) + 5 deep reasoning = 29 credits
10801080
Assert.AreEqual(29, cost.TotalCredits);
10811081
Assert.AreEqual(1, cost.DeepReasoningActions);

0 commit comments

Comments
 (0)