44
55from langchain_core .callbacks import BaseCallbackHandler
66from langchain_core .outputs import ChatGeneration , LLMResult
7- from ldai .agent_graph import AgentGraphDefinition
8- from ldai .providers .types import JudgeResult , LDAIMetrics
7+ from ldai .providers .types import LDAIMetrics
98from ldai .tracker import TokenUsage
109
1110from ldai_langchain .langchain_helper import get_ai_usage_from_response
@@ -20,8 +19,9 @@ class LDMetricsCallbackHandler(BaseCallbackHandler):
2019
2120 LangChain callback handler that collects per-node metrics during a LangGraph run.
2221
23- Records token usage, tool calls, and duration for each agent node in the graph,
24- then flushes them to LaunchDarkly trackers after the run completes via ``flush()``.
22+ Records token usage, tool calls, and duration for each agent node in the graph.
23+ Call ``collect_node_metrics()`` after the run completes to retrieve the accumulated
24+ per-node metrics for use by the managed layer.
2525 """
2626
2727 def __init__ (self , node_keys : Set [str ], fn_name_to_config_key : Dict [str , str ]):
@@ -185,67 +185,6 @@ def on_tool_end(
185185 self ._node_tool_calls [node_key ] = []
186186 self ._node_tool_calls [node_key ].append (config_key )
187187
188- # ------------------------------------------------------------------
189- # Flush
190- # ------------------------------------------------------------------
191-
192- async def flush (
193- self , graph : AgentGraphDefinition , eval_tasks = None
194- ) -> List [JudgeResult ]:
195- """
196- Emit collected per-node metrics to LaunchDarkly trackers.
197-
198- .. deprecated::
199- Per-node tracking is now driven by the managed layer
200- (:class:`ManagedAgentGraph`) from
201- :attr:`AgentGraphRunnerResult.metrics.node_metrics`. This method
202- is retained for tests and any external callers that still rely on
203- the original handler-driven tracking path; production code should
204- not call it.
205-
206- :param graph: The AgentGraphDefinition whose nodes hold the LD config trackers.
207- :param eval_tasks: Optional dict mapping node key to a list of awaitables that
208- return judge evaluation results.
209- :return: All judge results collected across all nodes.
210- """
211- node_trackers : Dict [str , Any ] = {}
212- all_eval_results : List [JudgeResult ] = []
213- for node_key in self ._path :
214- if node_key in node_trackers :
215- continue
216- node = graph .get_node (node_key )
217- if not node :
218- continue
219- config_tracker = node .get_config ().create_tracker ()
220- if not config_tracker :
221- continue
222- node_trackers [node_key ] = config_tracker
223-
224- usage = self ._node_tokens .get (node_key )
225- if usage :
226- config_tracker .track_tokens (usage )
227-
228- duration = self ._node_duration_ms .get (node_key )
229- if duration is not None :
230- config_tracker .track_duration (duration )
231-
232- config_tracker .track_success ()
233-
234- for tool_key in self ._node_tool_calls .get (node_key , []):
235- config_tracker .track_tool_call (tool_key )
236-
237- if not eval_tasks :
238- continue
239-
240- for eval_task in eval_tasks .get (node_key , []):
241- results = await eval_task
242- all_eval_results .extend (results )
243- for r in results :
244- if r .success :
245- config_tracker .track_judge_result (r )
246-
247- return all_eval_results
248-
249188 def collect_node_metrics (self ) -> Dict [str , LDAIMetrics ]:
250189 """
251190 Build a per-node ``LDAIMetrics`` map from data collected during the run.
0 commit comments