Skip to main content
traces shows what a conversation’s runs did, step by step: each model call with its tokens and finish reason, each tool call with its outcome and the size of what it returned, the wait on an approval, and the reply’s delivery, each with its start and duration. It runs in the project directory and reads the agent named in agent.json. With a conversation alone, it lists that conversation’s newest runs, one line each:
With a run id too, it shows that run as a waterfall, each step’s time from the run’s start on the left:
invoke --trace prints the same waterfall under the reply, and /trace inside chat prints it for the last turn. invoke and chat print the conversation and run they used. A run that failed is the one most worth reading: invoke --trace puts its trace on stderr ahead of the error. Against an agent deployed before traces existed, invoke --trace still prints the reply, with a warning in place of the trace.

What a Trace Holds

A trace is metadata only. It never holds message text, a tool’s arguments or its result, or an error’s message: an error is recorded as its type, its code and its HTTP status, because a provider’s error body or a tool’s thrown message can carry a secret, such as a URL with a token. So a browser_fill value or an MCP server’s secret header never reaches a trace. Traces are kept in the conversation’s own store, next to its messages: the newest 50 runs, at most 200 steps each, the oldest going first. Recording is best effort; a step that cannot be written is dropped with one log line, and the run goes on. Phone calls are not traced. Under --json, a run’s trace is data.trace, { run, spans }, each span with id, parent, kind, name, start (epoch milliseconds), durationMs, status and attrs. The list is data.runs. eval reads the same trace for its tool and noTool checks.
Traces live in the agent and are read through the CLI only; they are not exported to an OpenTelemetry collector or a tracing service yet.