nvoken
DocumentationObservability

Operate

Observability

Read the durable timeline, hosted traces, and structured logs for a turn — three views with different authority, none of which contain your prompts.

When a turn takes ninety seconds, three questions follow: where did the time go, what did it actually do, and what went wrong. nvoken answers them with three different records, and knowing which one to trust matters.

What it isAuthority
TimelineThe durable execution waterfall, assembled from one database snapshotAuthoritative
TracesOpenTelemetry spans exported from the agent loopDiagnostic, best-effort
LogsStructured lifecycle logs for the turnDiagnostic, best-effort

The timeline is the one that is always right

GET /v1/turns/{turn_id}/timeline

Lifecycle waits, model calls, tool calls, nudges, and compactions, with their timings and usage, read from one consistent snapshot of the database that runs the turn. If a trace and the timeline disagree, the timeline is correct.

It survives Conversation erasure, degrading to the retained facts-only skeleton — what ran, when, and what it cost, after the transcript is gone. That is the record your support and billing questions should be built on.

Traces show the shape of the loop

GET /v1/turns/{turn_id}/traces
GET /v1/traces/{trace_id}

Traces come from the agent runtime through OpenTelemetry, newest first. A summary carries span_count, error_count, duration_ms, and attempt; reading one trace returns a projection of up to 200 spans, each with its operation, provider, model, and timing.

Two things to expect:

Partial traces are normal, not broken. is_partial: true means the agent root span has not arrived yet — you are watching a turn that is still running — or a bounded read omitted spans, or a process exited before the root was exported. A partial trace is still worth reading.

Attribution is grounded server-side. nvoken checks a trace against its own durable Turn record before returning it. Knowing a W3C trace ID grants no authority; you can only read traces for turns you can already read.

For logs belonging to one trace, page the Turn log endpoint with that trace_id.

Logs are lifecycle, not application output

GET /v1/turns/{turn_id}/logs

Structured records with severity, event, component, outcome, and error_class, correlated to a trace_id and span_id. Arbitrary attributes and raw error values are omitted.

These are nvoken's logs about running your turn — not your agent's output, and not a place your instructions can write to.

None of it contains your content

This is a guarantee, not a default you can change. Timelines, traces, and logs carry timings, counts, statuses, model names, and error classes. They never carry prompts, model responses, tool arguments, tool results, or error text.

That is why they are safe to leave visible to your support team and safe to keep after a transcript is erased. When you need what was actually said, read the Conversation transcript — the place where content lives, under the retention and deletion rules you set.

It is also why error_class is what you get instead of an error message. Group by it, alert on it, and go to the transcript for the specifics.

When observation is turned off

Both trace and log responses carry a status, and it reads disabled when the service has no configured observation store. That is an explicit answer rather than an empty list, so "no traces" and "tracing is off" never look the same.

The timeline has no such switch. It is part of the runtime, not an add-on.

Where to start

For a slow turn, read the timeline: the waterfall usually names the culprit without further digging — a long provider call, a tool call nobody settled, a compaction pass.

For a turn that failed, read the logs first, filtered by severity, then follow trace_id into the trace for the span that broke.

For a turn that is still running, all three are live. Traces will be partial and that is expected.