Skip to content

spans_to_trace

autogen.beta.eval.sources._spans.spans_to_trace #

spans_to_trace(spans, *, conventions=None, duration_ms=None)

Reconstruct a :class:Trace from captured spans.

Spans are ordered by start time; each is mapped to typed events by the first conventions entry that recognizes it (default: AG2 gen_ai + OpenInference, auto-detected per span). duration_ms defaults to the root span's wall-clock; pass an explicit value to override (e.g. the producer's measured ask duration).

Source code in autogen/beta/eval/sources/_spans.py
def spans_to_trace(
    spans: Sequence[SpanData],
    *,
    conventions: Sequence[SpanConvention] | None = None,
    duration_ms: int | None = None,
) -> Trace:
    """Reconstruct a :class:`Trace` from captured spans.

    Spans are ordered by start time; each is mapped to typed events by the first
    ``conventions`` entry that recognizes it (default: AG2 ``gen_ai`` + OpenInference,
    auto-detected per span). ``duration_ms`` defaults to the root span's wall-clock;
    pass an explicit value to override (e.g. the producer's measured ``ask`` duration).
    """
    ordered = sorted(spans, key=lambda s: s.start_ns)
    active = DEFAULT_CONVENTIONS if conventions is None else conventions

    events: list[BaseEvent] = []
    for span in ordered:
        for convention in active:
            mapped = convention.to_events(span)
            if mapped is not None:
                events.extend(mapped)
                break

    if ordered and not events:
        logger.warning(
            "spans_to_trace reconstructed 0 events from %d span(s) — the producer's span dialect may be "
            "unrecognized by %s.",
            len(ordered),
            "/".join(type(c).__name__ for c in active) or "(no conventions)",
        )

    resolved_duration = duration_ms if duration_ms is not None else _root_duration_ms(ordered)
    return Trace(events=events, exception=_root_exception(ordered), duration_ms=resolved_duration)