refine side car accumulate llm stats

This commit is contained in:
Jicheng Lu 2025-08-05 14:15:23 -05:00
parent 9c14caede9
commit 3dee140638
2 changed files with 56 additions and 6 deletions

View file

@ -3,8 +3,8 @@ namespace BotSharp.Abstraction.SideCar.Models;
public class SideCarOptions
{
public bool IsInheritStates { get; set; }
public IEnumerable<string>? InheritStateKeys { get; set; }
public IEnumerable<string>? ExcludedStateKeys { get; set; }
public HashSet<string>? InheritStateKeys { get; set; }
public HashSet<string>? ExcludedStateKeys { get; set; }
public static SideCarOptions Empty()
{
@ -12,8 +12,8 @@ public class SideCarOptions
}
public static SideCarOptions InheritStates(
IEnumerable<string>? includedStates = null,
IEnumerable<string>? excludedStates = null)
HashSet<string>? includedStates = null,
HashSet<string>? excludedStates = null)
{
return new()
{

View file

@ -15,6 +15,9 @@
******************************************************************************/
using BotSharp.Core.Infrastructures;
using NetTopologySuite.Index.KdTree;
using Newtonsoft.Json.Linq;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace BotSharp.Core.SideCar.Services;
@ -189,7 +192,9 @@ public class BotSharpConversationSideCar : IConversationSideCar
private void RestoreStates(ConversationState prevStates)
{
var innerStates = prevStates;
var preValues = prevStates.Values.ToList();
var copy = JsonSerializer.Deserialize<List<StateKeyValue>>(JsonSerializer.Serialize(preValues));
var innerStates = new ConversationState(copy ?? []);
var state = _services.GetRequiredService<IConversationStateService>();
if (_sideCarOptions?.IsInheritStates == true)
@ -209,7 +214,7 @@ public class BotSharpConversationSideCar : IConversationSideCar
continue;
}
if (innerStates.ContainsKey(pair.Key))
if (innerStates.ContainsKey(pair.Key) && innerStates[pair.Key].Versioning)
{
innerStates[pair.Key].Values.Add(endNode);
}
@ -226,6 +231,51 @@ public class BotSharpConversationSideCar : IConversationSideCar
}
}
AccumulateLlmStats(state, prevStates, innerStates);
state.SetCurrentState(innerStates);
}
private void AccumulateLlmStats(IConversationStateService state, ConversationState prevState, ConversationState curState)
{
var dict = new Dictionary<string, Type>
{
{ "prompt_total", typeof(int) },
{ "completion_total", typeof(int) },
{ "llm_total_cost", typeof(float) }
};
foreach (var pair in dict)
{
var preVal = prevState.GetValueOrDefault(pair.Key)?.Values?.LastOrDefault()?.Data;
var curVal = state.GetState(pair.Key);
object data = pair.Value switch
{
Type t when t == typeof(int) => ParseNumber<int>(preVal) + ParseNumber<int>(curVal),
Type t when t == typeof(float) => ParseNumber<float>(preVal) + ParseNumber<float>(curVal),
_ => default
};
var cur = curState.GetValueOrDefault(pair.Key);
if (cur?.Values?.LastOrDefault() != null)
{
cur.Values.Last().Data = $"{data}";
}
}
}
private T ParseNumber<T>(string? data) where T : struct
{
if (string.IsNullOrEmpty(data))
{
return default;
}
return typeof(T) switch
{
Type t when t == typeof(int) => (T)(object)(int.TryParse(data, out var i) ? i : 0),
Type t when t == typeof(float) => (T)(object)(float.TryParse(data, out var f) ? f : 0),
_ => default
};
}
}