Bridle
Reference

Trace API

Event, Trace, observers, and the active-trace context.

bridle.Trace is an ordered, observable list of bridle.Event. The active trace is held in a ContextVar. See traces for usage patterns.

Event

@dataclass(frozen=True)
class Event:
    id: str
    parent_id: str | None
    kind: EventKind
    call_kind: str | None
    label: str | None
    timestamp: float
    duration_ms: float | None
    payload: dict[str, Any]
    error: str | None = None

Frozen dataclass. Constructed via Event.new:

Event.new(
    kind: EventKind,
    *,
    parent_id: str | None = None,
    call_kind: str | None = None,
    label: str | None = None,
    duration_ms: float | None = None,
    payload: dict[str, Any] | None = None,
    error: str | None = None,
) -> Event

id is a fresh uuid4().hex; timestamp is time.time().

EventKind

EventKind = Literal[
    "call_start",
    "call_end",
    "model_request",
    "model_response",
    "tool_call",
    "tool_result",
    "cache_hit",
    "cache_miss",
    "retry",
]

Trace

class Trace:
    def __init__(self) -> None: ...
    def emit(self, event: Event) -> None: ...
    @property
    def events(self) -> list[Event]: ...
    def __iter__(self) -> Iterator[Event]: ...
    def __len__(self) -> int: ...
    def subscribe(self, fn: Observer) -> Callable[[], None]: ...
    def to_dict(self) -> list[dict[str, Any]]: ...
    def to_jsonl(self) -> str: ...
    def tree(self) -> list[dict[str, Any]]: ...
MethodDescription
emit(event)Append event and notify observers synchronously.
eventsReturn a copy of the events list.
subscribe(fn)Register an observer. Returns an unsubscribe callable.
to_dict()List of dicts, one per event (via dataclasses.asdict).
to_jsonl()One JSON document per line, ordered.
tree()Roots-and-children structure grouped by parent_id. Each node is {"event": dict, "children": [...]}.

Trace is iterable (events) and supports len().

Observer

Observer = Callable[[Event], None]

Observers fire synchronously on emit. Subscriber list is snapshotted before each emit, so subscribing inside an observer does not fire on its own registration.

Active trace

bridle.trace.current_trace() -> Trace | None
bridle.trace.set_active_trace(trace: Trace | None) -> Token
bridle.trace.reset_active_trace(token: Token) -> None

set_active_trace returns a contextvars.Token. Pass it to reset_active_trace to restore the previous trace. Threads and tasks that copy context (e.g. asyncio.Task, contextvars.copy_context) inherit the active trace.

When no trace is active, primitives create a local Trace for the duration of the call so events do not get dropped — but you cannot inspect it after. Set one yourself if you want to read it.

Event nesting

bridle.trace.current_event_id() -> str | None
bridle.trace.push_event_id(event_id: str) -> Token
bridle.trace.reset_event_id(token: Token) -> None

Each call's call_start event id is pushed as the current parent for the duration of the call. Inner events use it as their parent_id. This is the mechanism that makes Trace.tree() produce a meaningful structure.

You should not need to push event ids manually — primitives and wrappers do it. The functions are exposed for advanced use (custom dispatchers, third-party wrappers).

Re-exported convenience names

Available from bridle:

  • Trace
  • Event
  • current_trace

On this page