99import random
1010import time
1111from datetime import datetime , timedelta
12- from typing import Any , Callable , Dict , Iterator , List , Optional , cast
12+ from typing import Any , Dict , List , Optional , Protocol
1313
1414from eval_protocol .models import EvaluationRow , InputMetadata , Message
1515
1616logger = logging .getLogger (__name__ )
1717
18+
19+ class TraceConverter (Protocol ):
20+ """Protocol for custom trace-to-EvaluationRow converter functions.
21+
22+ A converter function should take a Langfuse trace along with processing
23+ options and return an EvaluationRow or None to skip the trace.
24+ """
25+
26+ def __call__ (
27+ self ,
28+ trace : "TraceWithFullDetails" ,
29+ include_tool_calls : bool ,
30+ span_name : Optional [str ],
31+ ) -> Optional [EvaluationRow ]:
32+ """Convert a Langfuse trace to an EvaluationRow.
33+
34+ Args:
35+ trace: The Langfuse trace object to convert
36+ include_tool_calls: Whether to include tool calling information
37+ span_name: Optional span name to extract messages from
38+
39+ Returns:
40+ EvaluationRow or None if the trace should be skipped
41+ """
42+ ...
43+
44+
1845try :
1946 from langfuse import get_client # pyright: ignore[reportPrivateImportUsage]
2047 from langfuse .api .resources .trace .types .traces import Traces
@@ -35,7 +62,7 @@ def convert_trace_to_evaluation_row(
3562 trace: Langfuse trace object
3663 include_tool_calls: Whether to include tool calling information
3764 span_name: If provided, extract messages from generations within this named span
38- converter: Optional custom function to convert trace to EvaluationRow
65+ converter: Optional custom converter implementing TraceConverter protocol
3966
4067 Returns:
4168 EvaluationRow or None if conversion fails
@@ -290,7 +317,7 @@ def get_evaluation_rows(
290317 sleep_between_gets : float = 2.5 ,
291318 max_retries : int = 3 ,
292319 span_name : Optional [str ] = None ,
293- converter : Optional [Callable [[ TraceWithFullDetails , bool , Optional [ str ]], Optional [ EvaluationRow ]] ] = None ,
320+ converter : Optional [TraceConverter ] = None ,
294321 ) -> List [EvaluationRow ]:
295322 """Pull traces from Langfuse and convert to EvaluationRow format.
296323
@@ -312,7 +339,7 @@ def get_evaluation_rows(
312339 sleep_between_gets: Sleep time between individual trace.get() calls (2.5s for 30 req/min limit)
313340 max_retries: Maximum retries for rate limit errors
314341 span_name: If provided, extract messages from generations within this named span
315- converter: Optional custom function to convert trace to EvaluationRow .
342+ converter: Optional custom converter implementing TraceConverter protocol .
316343 If provided, this will be used instead of the default conversion logic.
317344
318345 Returns:
@@ -455,15 +482,15 @@ def get_evaluation_rows_by_ids(
455482 trace_ids : List [str ],
456483 include_tool_calls : bool = True ,
457484 span_name : Optional [str ] = None ,
458- converter : Optional [Callable [[ TraceWithFullDetails , bool , Optional [ str ]], Optional [ EvaluationRow ]] ] = None ,
485+ converter : Optional [TraceConverter ] = None ,
459486 ) -> List [EvaluationRow ]:
460487 """Get specific traces by their IDs and convert to EvaluationRow format.
461488
462489 Args:
463490 trace_ids: List of trace IDs to fetch
464491 include_tool_calls: Whether to include tool calling traces
465492 span_name: If provided, extract messages from generations within this named span
466- converter: Optional custom function to convert trace to EvaluationRow .
493+ converter: Optional custom converter implementing TraceConverter protocol .
467494 If provided, this will be used instead of the default conversion logic.
468495
469496 Returns:
0 commit comments