Forge
csharpcf25d736
1using System.Text.Json;
2
3namespace CascadeIDE.Services.Fm;
4
5/// <summary>Парсинг <c>usage</c> из OpenAI-compatible chat completion (stream/non-stream).</summary>
6public static class FmOpenAiUsageParser
7{
8 public static FmTurnUsage? TryParseFromCompletionChunk(string json)
9 {
10 if (string.IsNullOrWhiteSpace(json))
11 return null;
12
13 try
14 {
15 using var doc = JsonDocument.Parse(json);
16 return TryParseFromRoot(doc.RootElement);
17 }
18 catch (JsonException)
19 {
20 return null;
21 }
22 }
23
24 public static FmTurnUsage? TryParseFromRoot(JsonElement root)
25 {
26 if (!root.TryGetProperty("usage", out var usage) || usage.ValueKind != JsonValueKind.Object)
27 return null;
28
29 int? prompt = TryReadInt(usage, "prompt_tokens");
30 int? completion = TryReadInt(usage, "completion_tokens");
31 int? total = TryReadInt(usage, "total_tokens");
32 return FmTurnUsage.TryCreate(prompt, completion, total);
33 }
34
35 private static int? TryReadInt(JsonElement obj, string name)
36 {
37 if (!obj.TryGetProperty(name, out var el))
38 return null;
39 return el.ValueKind switch
40 {
41 JsonValueKind.Number when el.TryGetInt32(out var n) => n,
42 JsonValueKind.Number => (int)el.GetDouble(),
43 _ => null,
44 };
45 }
46}
47
View only · write via MCP/CIDE