1919
2020_agent_instances : dict [str , Any ] = {}
2121
22+ _agent_llm_stats_lock = threading .Lock ()
23+
24+
25+ def _empty_llm_stats_totals () -> dict [str , int | float ]:
26+ return {
27+ "input_tokens" : 0 ,
28+ "output_tokens" : 0 ,
29+ "cached_tokens" : 0 ,
30+ "cost" : 0.0 ,
31+ "requests" : 0 ,
32+ }
33+
34+
35+ _completed_agent_llm_totals : dict [str , int | float ] = _empty_llm_stats_totals ()
36+
2237_agent_states : dict [str , Any ] = {}
2338
2439
40+ def _snapshot_agent_llm_stats (agent : Any ) -> dict [str , int | float ] | None :
41+ if not hasattr (agent , "llm" ) or not hasattr (agent .llm , "_total_stats" ):
42+ return None
43+
44+ stats = agent .llm ._total_stats
45+ return {
46+ "input_tokens" : stats .input_tokens ,
47+ "output_tokens" : stats .output_tokens ,
48+ "cached_tokens" : stats .cached_tokens ,
49+ "cost" : stats .cost ,
50+ "requests" : stats .requests ,
51+ }
52+
53+
54+ def _finalize_agent_llm_stats (agent_id : str , agent : Any ) -> None :
55+ stats = _snapshot_agent_llm_stats (agent )
56+ with _agent_llm_stats_lock :
57+ if stats is not None :
58+ _completed_agent_llm_totals ["input_tokens" ] += int (stats ["input_tokens" ])
59+ _completed_agent_llm_totals ["output_tokens" ] += int (stats ["output_tokens" ])
60+ _completed_agent_llm_totals ["cached_tokens" ] += int (stats ["cached_tokens" ])
61+ _completed_agent_llm_totals ["cost" ] += float (stats ["cost" ])
62+ _completed_agent_llm_totals ["requests" ] += int (stats ["requests" ])
63+
64+ node = _agent_graph ["nodes" ].get (agent_id )
65+ if node is not None :
66+ node ["llm_stats" ] = stats
67+
68+ _agent_instances .pop (agent_id , None )
69+
70+
2571def _is_whitebox_agent (agent_id : str ) -> bool :
2672 agent = _agent_instances .get (agent_id )
2773 return bool (getattr (getattr (agent , "llm_config" , None ), "is_whitebox" , False ))
@@ -237,7 +283,7 @@ def _run_agent_in_thread(
237283 _agent_graph ["nodes" ][state .agent_id ]["finished_at" ] = datetime .now (UTC ).isoformat ()
238284 _agent_graph ["nodes" ][state .agent_id ]["result" ] = {"error" : str (e )}
239285 _running_agents .pop (state .agent_id , None )
240- _agent_instances . pop (state .agent_id , None )
286+ _finalize_agent_llm_stats (state .agent_id , agent )
241287 raise
242288 else :
243289 if state .stop_requested :
@@ -247,7 +293,7 @@ def _run_agent_in_thread(
247293 _agent_graph ["nodes" ][state .agent_id ]["finished_at" ] = datetime .now (UTC ).isoformat ()
248294 _agent_graph ["nodes" ][state .agent_id ]["result" ] = result
249295 _running_agents .pop (state .agent_id , None )
250- _agent_instances . pop (state .agent_id , None )
296+ _finalize_agent_llm_stats (state .agent_id , agent )
251297
252298 return {"result" : result }
253299
@@ -418,7 +464,8 @@ def create_agent(
418464 if inherit_context :
419465 inherited_messages = agent_state .get_conversation_history ()
420466
421- _agent_instances [state .agent_id ] = agent
467+ with _agent_llm_stats_lock :
468+ _agent_instances [state .agent_id ] = agent
422469
423470 thread = threading .Thread (
424471 target = _run_agent_in_thread ,
0 commit comments