Skip to content

Turn Inspector

The turn inspector is the panel that explains a single turn: which nodes ran, how long each took, what prompt the model actually received, what it produced, and what the turn retrieved or called along the way.

It is one component with three hosts. The same blocks, in the same order, with the same behaviour, appear in:

Host Where How you select a turn
Chat Window Window ▸ Tryll ▸ Chat Click an assistant bubble
Agent Log Window ▸ Tryll ▸ Agent Log Click a received turn row
Dialog Lab Window ▸ Tryll ▸ Dialog Lab Click a grid cell

This page is the reference for the panel itself. Each host page covers only what is specific to that host — how turns get selected there, and what else that window does.

Prerequisite: diagnostics must be on

The inspector renders the debug_info payload a turn carries, which requires enable_diagnostics at CreateAgent. That flag is structural — it cannot be turned on for an agent that already exists.

You do not normally set it yourself. Chat enables it for the agent it creates, and the Agent Log holds a diagnostics-demand lease so agents created while it is open request diagnostics too. Neither writes to your scene or assets. The consequence is that the Agent Log must be open before an agent is created to get depth on that agent's turns — see Use the Agent Log.


The one thing to understand first: everything is node-attributed

A Tryll turn is a graph run, not a single model call. A turn can run a classifier, then a retriever, then a generator — each with its own parameters, its own prompt, and its own output.

So every block below the Route breadcrumb reads per node execution, not per turn. A graph with two Retrieve nodes shows two hit tables. A graph with a classifier and a generator shows two prompt subsections, each with its own heading (#2 answer (GenerateNode) [default]).

Click a node chip in the Route breadcrumb to narrow the entire panel to that one node — its parameters, its prompt, its retrieval hits, its raw JSON. Click the same chip again to go back to the whole turn. This is the fastest way to answer "what exactly did the classifier see?" in a multi-node graph, and it is the primary navigation control of the panel.


Block reference

Block Shown when Starts Copy
Route Always Expanded
Timing Always Expanded
Parameters Diagnostics present Collapsed
Checks Dialog Lab only, with authored checks Expanded
Prompt & output A node produced a prompt or output Expanded
Retrieval The turn ran a Retrieve node Expanded
Tool calls The turn ran a ToolCall node Expanded
Errors The turn ended in error or cancellation Expanded
Raw JSON Always Collapsed

A block with nothing to say is hidden, not rendered empty. If you do not see Retrieval, the turn did not retrieve.

Route

The execution order, as a breadcrumb of node name [exit taken] chips — one chip per node execution, so a node entered twice appears twice.

Chips are selectable: click one to scope the whole panel to that node, click it again to clear the scope. The scoped chip is highlighted and the Route header's trailing text changes to <node> only.

"Other branch" exits (not_found, triggered, no_tool_called) are coloured distinctly from errors — they are usually correct behaviour, not failures.

If the turn never executed, the block says so rather than rendering an empty breadcrumb.

Timing

A stacked bar of per-node duration, plus the turn total in the header.

  • Each node gets a segment sized by its own duration_s. Nodes that took no measurable time render grey at zero width — a model-free node like Branch or Transform normally does.
  • Time to first token is marked separately: the delay before the first token arrived, which is the number that governs perceived responsiveness.
  • Pause-related figures (paused_duration_s, pause_count) appear for turns that paused.

Parameters

The parameters each node actually ran with, dumped from the turn's diagnostics.parameters grouped under a heading per node.

This is the parameters the server records into diagnostics, not every field on the node. Some node fields are deliberately not recorded. When a value is an array — a ToolCall node's tools signatures, for instance — the elements stack down the value column rather than collapsing to a bare count.

Starts collapsed, because on most turns it restates configuration you already know.

Checks

Dialog Lab only. The authored deterministic checks for that step — Must Contain, Must Not Contain, Regex Forbid, Max Words — with pass/fail per check. The header shows N failed or all passed.

The other two hosts have no authored checks, so the block is absent there rather than empty.

Prompt & output

The block most often worth opening. For each node that prompted a model, it shows the rendered prompt in the form actually sent — system, user and assistant messages as the model received them — followed by what that node generated.

This is where projection becomes visible: history replay, {{#instructions}} blocks, knowledge components and Mustache slot substitution have all already happened in what you see here. If a prompt does not contain what you expected, this block is where that shows up.

Copy on the header lifts the transcript to the clipboard without expanding the section. When a node scope is active it copies the scoped node only, matching what is on screen.

Dialog Lab: two-sided prompt diff

Pinning two cells in the Lab (⇧-click, or the ⊙ in a column header) turns this block into a line diff — green + for lines only in the selected cell, red for lines only in the other. The red side is usually the interesting one: it shows what a variant dropped. Each node is diffed against its own counterpart, and a node that ran on only one side is called out as such.

Retrieval

One subsection per Retrieve node execution. The header is a funnel — input.queryraw_result_countfiltered_countresult_count — with threshold, top_k and the storage name.

The body is the hit table: each retrieved chunk with its distance, in server order (which for Hybrid retrieval is RRF rank). Rows beyond the threshold are dimmed rather than removed, so you can see the near-misses that did not make it in. A null distance renders as .

See Retrieve and Embedded String Storage.

Tool calls

For each ToolCall node execution: which function the model called, the arguments it passed, and the result that came back — as JSON. The header shows the call count and the exit taken.

Two things gate what appears here, and both are configuration rather than defects:

  • The node's disposition. Whether a result is returned to the model at all, and whether the client is notified, is decided by ToolCallParams.disposition. A disposition that does not return results leaves the result side empty. See Tool Call.
  • Server config include_interaction_in_diagnostics. Tool-call results are joined through the turn's interaction components. With this off, the panel explains that rather than silently rendering a short list.

Errors

Present only for turns that ended in error or cancellation, carrying the terminal status and the error detail. The header shows the status.

Raw JSON

The escape hatch: the complete debug_info payload the turn carried, pretty-printed. Everything above is a purpose-built view over this — so anything the panel has no dedicated block for is still reachable here.

Copy on the header puts the formatted JSON on the clipboard.

Two things currently live here and nowhere else:

  • Intent classification. There is no dedicated block for ClassifyIntent / ClassifyIntentLLM yet. Whether classification matched, and against what, is visible in Raw JSON. (Note this is separate from whether the Agent Log shows a classification event at all, which depends on the node's notify_client parameter — see Use the Agent Log.)
  • Variable replacements and engine/scheduler counters, including the KV-reuse figures that often explain why one sample was slower than another.

When a block is missing or the panel is thin

The panel distinguishes these cases rather than rendering an empty section. If you see less than you expected, it is one of:

What you see Why
"Created before diagnostics capture" The agent existed before the Agent Log opened. Recreate it, or create new agents while the window is open.
"Unsupported schema" The turn's debug_info is not schema_version 2. Raw JSON may still be offered.
"Turn was not executed" Dialog Lab: a seeded turn (injected without running the graph), or a turn after an error in the same column.
A block simply absent The turn did not do that thing — no Retrieve node ran, no tool was called, no error occurred.
Tool-call results empty The node's disposition does not return results, or include_interaction_in_diagnostics is off server-side.

Host differences

The panel is the same in all three windows and in both engines. What differs is its framing:

Chat Agent Log Dialog Lab
Default visibility Visible Collapsed Visible
Width persisted Per window, independently of the other hosts Per window Per window
Checks block
Prompt diff (pinning)
Non-turn rows Sent / system rows use a different, simpler inspector

In the Agent Log, only received turn rows open this panel. Sent rows and system rows are selectable too, but they open simpler panels showing the wire payload, deferred variable batches, and the server's Ack or error — see Use the Agent Log.

Unity and Unreal parity

Both engines implement the same nine blocks in the same order. Chrome — fonts, splitter behaviour, scrollbar feel — differs, and that is expected.