Forge
csharpcf25d736
1using Microsoft.Agents.AI;
2using Microsoft.Extensions.AI;
3
4namespace CascadeIDE.Services.Fm;
5
6/// <summary>Извлечение usage из Microsoft.Extensions.AI / MAF ответов.</summary>
7public static class FmMeAiUsageExtractor
8{
9 public static FmTurnUsage? TryFromChatResponse(ChatResponse? response)
10 {
11 if (response is null)
12 return null;
13
14 var usage = response.Usage;
15 if (usage is not null)
16 return FromUsageDetails(usage);
17
18 return TryFromRawRepresentation(response.RawRepresentation);
19 }
20
21 public static FmTurnUsage? TryFromAgentResponse(AgentResponse? response)
22 {
23 if (response is null)
24 return null;
25
26 if (response.Usage is { } agentUsage)
27 return FromUsageDetails(agentUsage);
28
29 if (response.Messages is { Count: > 0 })
30 {
31 FmTurnUsage? merged = null;
32 foreach (var msg in response.Messages)
33 {
34 foreach (var content in msg.Contents)
35 {
36 if (content is UsageContent usageContent)
37 {
38 var u = FromUsageDetails(usageContent.Details);
39 if (u is not null)
40 merged = merged is null ? u : merged.Add(u);
41 }
42 }
43 }
44
45 if (merged is not null)
46 return merged;
47 }
48
49 return TryFromRawRepresentation(response.RawRepresentation);
50 }
51
52 private static FmTurnUsage? FromUsageDetails(UsageDetails? details)
53 {
54 if (details is null)
55 return null;
56
57 int? input = details.InputTokenCount is long i ? (int)Math.Min(i, int.MaxValue) : null;
58 int? output = details.OutputTokenCount is long o ? (int)Math.Min(o, int.MaxValue) : null;
59 int? total = details.TotalTokenCount is long t ? (int)Math.Min(t, int.MaxValue) : null;
60 return FmTurnUsage.TryCreate(input, output, total);
61 }
62
63 private static FmTurnUsage? TryFromRawRepresentation(object? raw)
64 {
65 if (raw is null)
66 return null;
67
68 try
69 {
70 var json = System.Text.Json.JsonSerializer.Serialize(raw);
71 return FmOpenAiUsageParser.TryParseFromCompletionChunk(json);
72 }
73 catch
74 {
75 return null;
76 }
77 }
78}
79
View only · write via MCP/CIDE