Tracing

Tracing records an agent's behavior as a stream of typed events, which is what powers EntroPy's behavioral, tool, reasoning and drift metrics. There are three ways to capture events.

Manual: trace() + event()

Open a trace context and emit events as the agent runs:

from entropy import trace, event

with trace() as t:
    event("action", "tool:search", query="weather")
    event("observation", "result", n=12)
    event("action", "reply", text="It will rain.")
# t.events holds the captured Event objects

Automatic: instrument()

Wrap any callable so it returns an AgentRun with an input/output event pair. If the object matches a registered framework adapter, it is routed there automatically.

from entropy import instrument

wrapped = instrument(my_agent)        # returns an AgentRun per call
run = wrapped("book a flight")
print(run.output, run.events)

Exceptions are captured rather than raised — the resulting AgentRun carries an ErrorEvent and metadata["error"], so a flaky agent degrades gracefully instead of crashing the suite.

Returning a rich run

An agent may return an AgentRun directly, or a dict with output, events, cost and metadata:

from entropy import AgentRun, ToolCallEvent

def agent(inp):
    return AgentRun(
        run_id="",
        input=inp,
        output="done",
        events=[ToolCallEvent("search", {"q": inp})],
        cost=0.002,
        metadata={"latency": 0.31},
    )

Typed events

Use the typed subclasses for clearer semantics:

from entropy import (ActionEvent, ReasoningEvent, ToolCallEvent,
                     ObservationEvent, MemoryWriteEvent, ErrorEvent,
                     StateTransitionEvent)

events = [
    ReasoningEvent("plan:search_then_reply"),
    ToolCallEvent("search", {"q": "paris"}),
    MemoryWriteEvent("facts", {"correct": True}),
    StateTransitionEvent("idle->working"),
]

Accessing the active trace

current_trace() builds a Trace from events captured so far (best-effort), useful for ad-hoc inspection.