@@ -77,6 +77,7 @@ def __init__(
7777 model_name : str ,
7878 provider_name : str ,
7979 context : Context ,
80+ graph_key : Optional [str ] = None ,
8081 ):
8182 """
8283 Initialize an AI Config tracker.
@@ -88,6 +89,8 @@ def __init__(
8889 :param model_name: Name of the model used.
8990 :param provider_name: Name of the provider used.
9091 :param context: Context for evaluation.
92+ :param graph_key: When set, include ``graphKey`` in all event payloads
93+ (e.g. config-level metrics inside a graph).
9194 """
9295 self ._ld_client = ld_client
9396 self ._variation_key = variation_key
@@ -96,13 +99,13 @@ def __init__(
9699 self ._model_name = model_name
97100 self ._provider_name = provider_name
98101 self ._context = context
102+ self ._graph_key = graph_key
99103 self ._summary = LDAIMetricSummary ()
100104
101- def __get_track_data (self , graph_key : Optional [ str ] = None ) -> dict :
105+ def __get_track_data (self ) -> dict :
102106 """
103107 Get tracking data for events.
104108
105- :param graph_key: When set, include ``graphKey`` in the payload.
106109 :return: Dictionary containing variation and config keys.
107110 """
108111 data = {
@@ -112,82 +115,72 @@ def __get_track_data(self, graph_key: Optional[str] = None) -> dict:
112115 "modelName" : self ._model_name ,
113116 "providerName" : self ._provider_name ,
114117 }
115- if graph_key is not None :
116- data ['graphKey' ] = graph_key
118+ if self . _graph_key is not None :
119+ data ['graphKey' ] = self . _graph_key
117120 return data
118121
119- def track_duration (self , duration : int , * , graph_key : Optional [ str ] = None ) -> None :
122+ def track_duration (self , duration : int ) -> None :
120123 """
121124 Manually track the duration of an AI operation.
122125
123126 :param duration: Duration in milliseconds.
124- :param graph_key: When set, include ``graphKey`` in the event payload
125- (e.g. config-level metrics inside a graph).
126127 """
127128 self ._summary ._duration = duration
128129 self ._ld_client .track (
129- "$ld:ai:duration:total" , self ._context , self .__get_track_data (graph_key ), duration
130+ "$ld:ai:duration:total" , self ._context , self .__get_track_data (), duration
130131 )
131132
132- def track_time_to_first_token (
133- self , time_to_first_token : int , * , graph_key : Optional [str ] = None
134- ) -> None :
133+ def track_time_to_first_token (self , time_to_first_token : int ) -> None :
135134 """
136135 Manually track the time to first token of an AI operation.
137136
138137 :param time_to_first_token: Time to first token in milliseconds.
139- :param graph_key: When set, include ``graphKey`` in the event payload.
140138 """
141139 self ._summary ._time_to_first_token = time_to_first_token
142140 self ._ld_client .track (
143141 "$ld:ai:tokens:ttf" ,
144142 self ._context ,
145- self .__get_track_data (graph_key ),
143+ self .__get_track_data (),
146144 time_to_first_token ,
147145 )
148146
149- def track_duration_of (self , func , * , graph_key : Optional [ str ] = None ):
147+ def track_duration_of (self , func ):
150148 """
151149 Automatically track the duration of an AI operation.
152150
153151 An exception occurring during the execution of the function will still
154152 track the duration. The exception will be re-thrown.
155153
156154 :param func: Function to track (synchronous only).
157- :param graph_key: When set, passed through to :meth:`track_duration`.
158155 :return: Result of the tracked function.
159156 """
160157 start_ns = time .perf_counter_ns ()
161158 try :
162159 result = func ()
163160 finally :
164161 duration = (time .perf_counter_ns () - start_ns ) // 1_000_000 # duration in milliseconds
165- self .track_duration (duration , graph_key = graph_key )
162+ self .track_duration (duration )
166163
167164 return result
168165
169166 def _track_from_metrics_extractor (
170167 self ,
171168 result : Any ,
172169 metrics_extractor : Callable [[Any ], Any ],
173- * ,
174- graph_key : Optional [str ] = None ,
175170 ) -> Any :
176171 metrics = metrics_extractor (result )
177172 if metrics .success :
178- self .track_success (graph_key = graph_key )
173+ self .track_success ()
179174 else :
180- self .track_error (graph_key = graph_key )
175+ self .track_error ()
181176 if metrics .usage :
182- self .track_tokens (metrics .usage , graph_key = graph_key )
177+ self .track_tokens (metrics .usage )
183178 return result
184179
185180 def track_metrics_of (
186181 self ,
187182 func : Callable [[], Any ],
188183 metrics_extractor : Callable [[Any ], Any ],
189- * ,
190- graph_key : Optional [str ] = None ,
191184 ) -> Any :
192185 """
193186 Track metrics for a synchronous AI operation.
@@ -203,33 +196,29 @@ def track_metrics_of(
203196
204197 :param func: Synchronous callable that runs the operation
205198 :param metrics_extractor: Function that extracts LDAIMetrics from the operation result
206- :param graph_key: When set, include ``graphKey`` on emitted config-level events.
207199 :return: The result of the operation
208200 """
209201 start_ns = time .perf_counter_ns ()
210202 try :
211203 result = func ()
212204 except Exception as err :
213205 duration = (time .perf_counter_ns () - start_ns ) // 1_000_000
214- self .track_duration (duration , graph_key = graph_key )
215- self .track_error (graph_key = graph_key )
206+ self .track_duration (duration )
207+ self .track_error ()
216208 raise err
217209
218210 duration = (time .perf_counter_ns () - start_ns ) // 1_000_000
219- self .track_duration (duration , graph_key = graph_key )
220- return self ._track_from_metrics_extractor (result , metrics_extractor , graph_key = graph_key )
211+ self .track_duration (duration )
212+ return self ._track_from_metrics_extractor (result , metrics_extractor )
221213
222- async def track_metrics_of_async (
223- self , func , metrics_extractor , * , graph_key : Optional [str ] = None
224- ):
214+ async def track_metrics_of_async (self , func , metrics_extractor ):
225215 """
226216 Track metrics for an async AI operation (``func`` is awaited).
227217
228218 Same event semantics as :meth:`track_metrics_of`.
229219
230220 :param func: Async callable or zero-arg callable that returns an awaitable when called
231221 :param metrics_extractor: Function that extracts LDAIMetrics from the operation result
232- :param graph_key: When set, include ``graphKey`` on emitted config-level events.
233222 :return: The result of the operation
234223 """
235224 start_ns = time .perf_counter_ns ()
@@ -238,23 +227,22 @@ async def track_metrics_of_async(
238227 result = await func ()
239228 except Exception as err :
240229 duration = (time .perf_counter_ns () - start_ns ) // 1_000_000
241- self .track_duration (duration , graph_key = graph_key )
242- self .track_error (graph_key = graph_key )
230+ self .track_duration (duration )
231+ self .track_error ()
243232 raise err
244233
245234 duration = (time .perf_counter_ns () - start_ns ) // 1_000_000
246- self .track_duration (duration , graph_key = graph_key )
247- return self ._track_from_metrics_extractor (result , metrics_extractor , graph_key = graph_key )
235+ self .track_duration (duration )
236+ return self ._track_from_metrics_extractor (result , metrics_extractor )
248237
249- def track_judge_result (self , judge_result : Any , * , graph_key : Optional [ str ] = None ) -> None :
238+ def track_judge_result (self , judge_result : Any ) -> None :
250239 """
251240 Track a judge result, including the evaluation score with judge config key.
252241
253242 :param judge_result: JudgeResult object containing score, metric key, and success status
254- :param graph_key: When set, include ``graphKey`` in the event payload.
255243 """
256244 if judge_result .success and judge_result .metric_key :
257- track_data = self .__get_track_data (graph_key = graph_key )
245+ track_data = self .__get_track_data ()
258246 if judge_result .judge_config_key :
259247 track_data = {** track_data , 'judgeConfigKey' : judge_result .judge_config_key }
260248 self ._ld_client .track (
@@ -264,49 +252,44 @@ def track_judge_result(self, judge_result: Any, *, graph_key: Optional[str] = No
264252 judge_result .score ,
265253 )
266254
267- def track_feedback (self , feedback : Dict [str , FeedbackKind ], * , graph_key : Optional [ str ] = None ) -> None :
255+ def track_feedback (self , feedback : Dict [str , FeedbackKind ]) -> None :
268256 """
269257 Track user feedback for an AI operation.
270258
271259 :param feedback: Dictionary containing feedback kind.
272- :param graph_key: When set, include ``graphKey`` in the event payload.
273260 """
274261 self ._summary ._feedback = feedback
275262 if feedback ["kind" ] == FeedbackKind .Positive :
276263 self ._ld_client .track (
277264 "$ld:ai:feedback:user:positive" ,
278265 self ._context ,
279- self .__get_track_data (graph_key = graph_key ),
266+ self .__get_track_data (),
280267 1 ,
281268 )
282269 elif feedback ["kind" ] == FeedbackKind .Negative :
283270 self ._ld_client .track (
284271 "$ld:ai:feedback:user:negative" ,
285272 self ._context ,
286- self .__get_track_data (graph_key = graph_key ),
273+ self .__get_track_data (),
287274 1 ,
288275 )
289276
290- def track_success (self , * , graph_key : Optional [ str ] = None ) -> None :
277+ def track_success (self ) -> None :
291278 """
292279 Track a successful AI generation.
293-
294- :param graph_key: When set, include ``graphKey`` in the event payload.
295280 """
296281 self ._summary ._success = True
297282 self ._ld_client .track (
298- "$ld:ai:generation:success" , self ._context , self .__get_track_data (graph_key = graph_key ), 1
283+ "$ld:ai:generation:success" , self ._context , self .__get_track_data (), 1
299284 )
300285
301- def track_error (self , * , graph_key : Optional [ str ] = None ) -> None :
286+ def track_error (self ) -> None :
302287 """
303288 Track an unsuccessful AI generation attempt.
304-
305- :param graph_key: When set, include ``graphKey`` in the event payload.
306289 """
307290 self ._summary ._success = False
308291 self ._ld_client .track (
309- "$ld:ai:generation:error" , self ._context , self .__get_track_data (graph_key = graph_key ), 1
292+ "$ld:ai:generation:error" , self ._context , self .__get_track_data (), 1
310293 )
311294
312295 def track_openai_metrics (self , func ):
@@ -364,15 +347,14 @@ def track_bedrock_converse_metrics(self, res: dict) -> dict:
364347 self .track_tokens (_bedrock_to_token_usage (res ["usage" ]))
365348 return res
366349
367- def track_tokens (self , tokens : TokenUsage , * , graph_key : Optional [ str ] = None ) -> None :
350+ def track_tokens (self , tokens : TokenUsage ) -> None :
368351 """
369352 Track token usage metrics.
370353
371354 :param tokens: Token usage data from either custom, OpenAI, or Bedrock sources.
372- :param graph_key: When set, include ``graphKey`` in the event payload.
373355 """
374356 self ._summary ._usage = tokens
375- td = self .__get_track_data (graph_key = graph_key )
357+ td = self .__get_track_data ()
376358 if tokens .total > 0 :
377359 self ._ld_client .track (
378360 "$ld:ai:tokens:total" ,
@@ -395,32 +377,28 @@ def track_tokens(self, tokens: TokenUsage, *, graph_key: Optional[str] = None) -
395377 tokens .output ,
396378 )
397379
398- def track_tool_call (self , tool_key : str , * , graph_key : Optional [ str ] = None ) -> None :
380+ def track_tool_call (self , tool_key : str ) -> None :
399381 """
400382 Track a tool invocation for this configuration (standalone or within a graph).
401383
402384 :param tool_key: Identifier of the tool that was invoked.
403- :param graph_key: When set, include ``graphKey`` in the event payload.
404385 """
405- track_data = {** self .__get_track_data (graph_key = graph_key ), "toolKey" : tool_key }
386+ track_data = {** self .__get_track_data (), "toolKey" : tool_key }
406387 self ._ld_client .track (
407388 "$ld:ai:tool_call" ,
408389 self ._context ,
409390 track_data ,
410391 1 ,
411392 )
412393
413- def track_tool_calls (
414- self , tool_keys : Iterable [str ], * , graph_key : Optional [str ] = None
415- ) -> None :
394+ def track_tool_calls (self , tool_keys : Iterable [str ]) -> None :
416395 """
417396 Track multiple tool invocations for this configuration.
418397
419398 :param tool_keys: Tool identifiers (e.g. from a model response).
420- :param graph_key: When set, include ``graphKey`` on each event.
421399 """
422400 for tool_key in tool_keys :
423- self .track_tool_call (tool_key , graph_key = graph_key )
401+ self .track_tool_call (tool_key )
424402
425403 def get_summary (self ) -> LDAIMetricSummary :
426404 """
0 commit comments