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 = NoneFrozen 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,
) -> Eventid 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]]: ...| Method | Description |
|---|---|
emit(event) | Append event and notify observers synchronously. |
events | Return 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) -> Noneset_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) -> NoneEach 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:
TraceEventcurrent_trace