|
|
@@ -791,6 +791,28 @@ class FileSystemTraceStore:
|
|
|
|
|
|
# ===== 模型使用追踪 =====
|
|
|
|
|
|
+ async def get_model_usage(self, trace_id: str) -> Dict[str, Any]:
|
|
|
+ """Read one Trace's provider usage without exposing storage paths."""
|
|
|
+
|
|
|
+ _validate_path_segment(trace_id, "trace_id")
|
|
|
+ usage_file = self._get_model_usage_file(trace_id)
|
|
|
+ if not usage_file.exists():
|
|
|
+ return {
|
|
|
+ "summary": {
|
|
|
+ "total_models": 0,
|
|
|
+ "total_tokens": 0,
|
|
|
+ "total_cache_read_tokens": 0,
|
|
|
+ "agent_tokens": 0,
|
|
|
+ "tool_tokens": 0,
|
|
|
+ },
|
|
|
+ "models": [],
|
|
|
+ "timeline": [],
|
|
|
+ }
|
|
|
+ value = json.loads(usage_file.read_text(encoding="utf-8"))
|
|
|
+ if not isinstance(value, dict):
|
|
|
+ raise ValueError("model usage root must be an object")
|
|
|
+ return value
|
|
|
+
|
|
|
async def record_model_usage(
|
|
|
self,
|
|
|
trace_id: str,
|