@@ -85,29 +85,17 @@ def convert_trace_to_evaluation_row(
8585 execution_metadata = ExecutionMetadata ()
8686 row_id = None
8787
88- if trace .observations :
89- for obs in trace .observations :
90- if obs .metadata and "requester_metadata" in obs .metadata :
91- req_meta = obs .metadata ["requester_metadata" ]
92- if isinstance (req_meta , dict ):
93- execution_metadata .invocation_id = req_meta .get ("invocation_id" )
94- execution_metadata .experiment_id = req_meta .get ("experiment_id" )
95- execution_metadata .rollout_id = req_meta .get ("rollout_id" )
96- execution_metadata .run_id = req_meta .get ("run_id" )
97- row_id = req_meta .get ("row_id" )
98- break # Only need to get first observation
99-
10088 if trace .tags :
10189 for tag in trace .tags :
102- if tag .startswith ("invocation_id:" ) and not execution_metadata . invocation_id :
90+ if tag .startswith ("invocation_id:" ):
10391 execution_metadata .invocation_id = tag .split (":" , 1 )[1 ]
104- elif tag .startswith ("experiment_id:" ) and not execution_metadata . experiment_id :
92+ elif tag .startswith ("experiment_id:" ):
10593 execution_metadata .experiment_id = tag .split (":" , 1 )[1 ]
106- elif tag .startswith ("rollout_id:" ) and not execution_metadata . rollout_id :
94+ elif tag .startswith ("rollout_id:" ):
10795 execution_metadata .rollout_id = tag .split (":" , 1 )[1 ]
108- elif tag .startswith ("run_id:" ) and not execution_metadata . run_id :
96+ elif tag .startswith ("run_id:" ):
10997 execution_metadata .run_id = tag .split (":" , 1 )[1 ]
110- elif tag .startswith ("row_id:" ) and not row_id :
98+ elif tag .startswith ("row_id:" ):
11199 row_id = tag .split (":" , 1 )[1 ]
112100
113101 if (
@@ -298,9 +286,6 @@ def get_evaluation_rows(
298286 max_retries : int = 3 ,
299287 span_name : Optional [str ] = None ,
300288 converter : Optional [TraceConverter ] = None ,
301- metadata : Optional [Dict [str , Any ]] = None ,
302- requester_metadata : Optional [Dict [str , Any ]] = None ,
303- requester_metadata_contains : Optional [str ] = None ,
304289 ) -> List [EvaluationRow ]:
305290 """Pull traces from Langfuse and convert to EvaluationRow format.
306291
@@ -335,10 +320,6 @@ def get_evaluation_rows(
335320 to_timestamp = datetime .now ()
336321 from_timestamp = to_timestamp - timedelta (hours = hours_back )
337322
338- # If filtering by metadata/requester_metadata, prefer fetching metadata fields
339- if (metadata is not None or requester_metadata is not None or requester_metadata_contains ) and not fields :
340- fields = "core,metadata,observations"
341-
342323 # Collect trace summaries via pagination (up to limit)
343324 all_traces = []
344325 page = 1
@@ -420,74 +401,6 @@ def get_evaluation_rows(
420401 selected_traces = all_traces
421402 logger .debug ("Processing all %d collected traces (no sampling)" , len (all_traces ))
422403
423- # Helper to check if a trace matches provided metadata filters. We look in multiple places
424- # to account for Langfuse moving fields (e.g., metadata vs requester_metadata) and SDK shape.
425- def _trace_matches_metadata_filters (trace_obj : Any ) -> bool :
426- if metadata is None and requester_metadata is None :
427- return True
428-
429- def _as_dict (val : Any ) -> Dict [str , Any ]:
430- if val is None :
431- return {}
432- if isinstance (val , dict ):
433- return val
434- # Some SDK objects expose .model_dump() or behave like pydantic models
435- dump = getattr (val , "model_dump" , None )
436- if callable (dump ):
437- try :
438- return dump () # type: ignore[no-any-return]
439- except Exception :
440- return {}
441- return {}
442-
443- # Try common locations for metadata on full trace
444- trace_meta = _as_dict (getattr (trace_obj , "metadata" , None ))
445- trace_req_meta = _as_dict (getattr (trace_obj , "requester_metadata" , None ))
446- # Some Langfuse deployments nest requester_metadata inside metadata
447- nested_req_meta = {}
448- try :
449- if isinstance (trace_meta , dict ) and isinstance (trace_meta .get ("requester_metadata" ), dict ):
450- nested_req_meta = _as_dict (trace_meta .get ("requester_metadata" ))
451- except Exception :
452- nested_req_meta = {}
453-
454- # Fallbacks: sometimes metadata is embedded in input
455- input_meta = {}
456- try :
457- inp = getattr (trace_obj , "input" , None )
458- if isinstance (inp , dict ):
459- input_meta = _as_dict (inp .get ("metadata" ))
460- except Exception :
461- input_meta = {}
462-
463- # Combine for matching convenience (later keys override earlier for equality check only)
464- combined_meta = {** trace_meta , ** input_meta }
465- combined_req_meta = {** trace_req_meta }
466-
467- # Also merge nested requester metadata when present
468- if nested_req_meta :
469- combined_req_meta = {** combined_req_meta , ** nested_req_meta }
470-
471- def _is_subset (needle : Dict [str , Any ], haystack : Dict [str , Any ]) -> bool :
472- for k , v in needle .items ():
473- if haystack .get (k ) != v :
474- return False
475- return True
476-
477- ok_meta = True
478- ok_req_meta = True
479-
480- if metadata is not None :
481- # Accept match if found either in metadata or requester_metadata buckets
482- ok_meta = _is_subset (metadata , combined_meta ) or _is_subset (metadata , combined_req_meta )
483-
484- if requester_metadata is not None :
485- ok_req_meta = _is_subset (requester_metadata , combined_req_meta ) or _is_subset (
486- requester_metadata , combined_meta
487- )
488-
489- return ok_meta and ok_req_meta
490-
491404 # Process each selected trace with sleep and retry logic
492405 for trace_info in selected_traces :
493406 # Sleep between gets to avoid rate limits
@@ -524,39 +437,6 @@ def _is_subset(needle: Dict[str, Any], haystack: Dict[str, Any]) -> bool:
524437 break # Skip this trace
525438
526439 if trace_full :
527- # If metadata filters are provided, skip non-matching traces early
528- try :
529- if not _trace_matches_metadata_filters (trace_full ):
530- continue
531- except Exception :
532- # Be permissive on filter errors; treat as non-match
533- continue
534-
535- # If observations carry requester_metadata, allow substring filtering
536- if requester_metadata_contains :
537- contains_val = requester_metadata_contains
538- found_match = False
539- try :
540- for obs in getattr (trace_full , "observations" , []) or []:
541- obs_rmd = getattr (obs , "requester_metadata" , None )
542- if isinstance (obs_rmd , dict ) and any (
543- (isinstance (v , str ) and contains_val in v ) for v in obs_rmd .values ()
544- ):
545- found_match = True
546- break
547- obs_md = getattr (obs , "metadata" , None )
548- if isinstance (obs_md , dict ):
549- nested = obs_md .get ("requester_metadata" )
550- if isinstance (nested , dict ) and any (
551- (isinstance (v , str ) and contains_val in v ) for v in nested .values ()
552- ):
553- found_match = True
554- break
555- except Exception :
556- found_match = False
557- if not found_match :
558- continue
559-
560440 try :
561441 if converter :
562442 eval_row = converter (trace_full , include_tool_calls , span_name )
0 commit comments