Tracing
Every turn emits one typed event stream. Sinks read it: a local JSONL file, the live feed, and OTLP traces.
Locally: the JSONL file and newt-report
Section titled “Locally: the JSONL file and newt-report”[events]jsonl = "newt-events.jsonl"capture_content = falseThe file leaves out message content unless capture_content = true. Run newt-report newt-events.jsonl for timing and flags per turn, and a cache report card: the cached share of all input and, for every call that read under half from cache, what broke it.
| Miss cause | Example |
|---|---|
| First call of the session | Expected once |
| A changed piece of the prefix | tool \search` changed, about 6120 bytes into the prefix` |
| History rewritten from message n | Usually compaction |
| An idle gap past the cache lifetime | The person came back later |
| Routing | Prefix and history unchanged, no gap: the provider sent it to a machine without the cache |
--prices input,cached,output adds the cost.
In production: OTLP traces
Section titled “In production: OTLP traces”[tracing]endpoint = "https://cloud.langfuse.com/api/public/otel/v1/traces"profile = "langfuse"headers_env = "NEWT_OTLP_HEADERS"capture_content = truenewt exports one trace per turn over OTLP/HTTP JSON:
- an
invoke_agentroot span; - a
chatspan per model call, with token usage, timings and the messages new to that call; - an
execute_toolspan per tool call.
A session’s turns share gen_ai.conversation.id. The langfuse profile also sets the Langfuse session, observation types and usage details. Span ids derive from session, turn and call, so a re-export overwrites rather than duplicates.
Your spans under the turn
Section titled “Your spans under the turn”Every tool call carries a traceparent in its _meta. Parent your own spans on it to see them inside the turn’s trace. Library users can add an Enricher (extra attributes per session) and a Redactor (runs over every captured message before it leaves the process).