14. Debug Console And Session Viewer
This chapter explains how the frontend splits a single transcript into three views: an end-user Agent page, a developer Debug Console, and a durable Session Viewer.
After reading this chapter, you should understand:
- who the Agent page, Debug page, and Session page are for
- why model input and model output both belong in debug
- why JSONL session records are not Debug Console state
- why permission audit belongs in Debug while run policy belongs in API, Debug, and Session surfaces
- why tool inputs and outputs are collapsed by default
Background
Once the runtime had streaming rounds and real tools, the frontend needed to show more than a final answer.
The first Debug Console exposed a semantic gap: it showed model requests, but not enough of the corresponding model output and committed history.
Three Views
The frontend now separates:
Agent page end-user-facing transcript
Debug page runtime inspection
Session page persisted JSONL recordsThis split prevents debug terminology from leaking into the normal agent experience.
Agent Page
The Agent page shows:
- assistant text
- grouped tool batches
- final answer
- collapsed run details
It does not expose "round 1", "round 2" style runtime labels.
Assistant text renders as Markdown with GFM support because models commonly produce lists, tables, and code blocks.
Debug Page
The Debug page shows:
- run policy
- permission audit decisions
- model input
- model output
- assistant deltas
- committed assistant messages
- tool calls
- tool arguments
- tool results
- model-visible
modelOutput - internal tool details
- usage and raw usage
- history commits
Debug data comes from runtime events plus stream-only debug events.
Session Page
The Session page browses persisted JSONL through:
GET /api/agent/sessions
GET /api/agent/sessions/[id]It first lists local sessions, then loads the selected session's raw records because this page is meant to inspect the replay substrate directly.
The session list shows model, session id suffix, approvalPolicy, and sandboxMode. The full JSONL still renders as raw records instead of being reshaped into the Debug Console event view.
Why Debug And Session Are Separate
Debug is operational. Session is durable.
debug.historyCommitted is not stored as another agent_event because the session already stores authoritative response_item records.
This avoids polluting future resume state with debug-only duplication.
Permission audit follows the same boundary. The Debug page uses it to explain allow/ask/deny decisions to developers. The Session page shows the actual agent_event and response_item records written to JSONL.
Frontend Implementation
The main file is:
components/chat-playground.tsxSupporting types and clients:
lib/agent-api-types.ts
lib/agent-api-client.ts
lib/agent-stream-projection.tsCurrent Status
This layer makes the Debug Console and Session Viewer a permanent part of the workbench: model inputs and outputs, tool details, the permission audit, and JSONL session records each have a stable place to be inspected. It is the first tool to reach for when diagnosing agent behavior.
Verification
Manual verification is important here:
- start the dev server
- run an agent task that uses
ls/find/grep/read - check Agent page for readable transcript
- check Debug page for model input/output and tool details
- check Debug page for permission audit
- check Session page for the session list and selected JSONL records
Common Misunderstandings
Misunderstanding 1: Debug Data Belongs On The Agent Page
The Agent page is for end users and should show a natural process: assistant text, tool batches, and final answer. Rounds, raw requests, usage, and JSONL belong to debug/session views.
Misunderstanding 2: Model Input Is Enough
It is not enough. Model output, committed assistant messages, tool calls, and usage are core telemetry facts. The Debug Console needs input/output pairing.
Misunderstanding 3: Tool Details Should Expand By Default
Tool inputs and outputs can be long. Collapsing them by default protects the reading flow while keeping details available.
Chapter Summary
This chapter separates frontend observation surfaces: the Agent page tells the end-user story, the Debug Console inspects runtime details, and the Session Viewer shows durable JSONL records.
Chapter Checkpoint
The first item needs no key. Start the dev server (npx next dev -p 3102), then ask the session read API for an id that does not exist:
curl -i http://localhost:3102/api/agent/sessions/does-not-existMeasured response (status line and body):
HTTP/1.1 404 Not Found
{"ok":false,"error":"Agent session was not found."}GET /api/agent/sessions returns {"ok":true,"sessions":[]} on a fresh checkout with no runs yet. These two endpoints are exactly what the Session Viewer consumes — list first, then load raw records by id.
The second item requires .env.local configured per chapter 0: run an Agent task that uses ls/grep/read, then walk the three views — the Agent page is a clean transcript (no "round" labels), the Debug page shows model input/output, tool details, and the permission audit, and the Session page lists the run and expands its line-by-line JSONL records.