Vis Series
VisReplay
Local session recorder and debugger for AI agents. Wrap an agent or WebSocket, save a portable session file, replay, compare runs, export structured debug views. v1.1.
Quick start
Start with the primary command, then continue with the full workflow below.
import { VisReplay } from "@latticeag/visreplay";Problem
Agent failures are nearly impossible to debug after the fact. Tool calls are text, reasoning traces are lost, and non-deterministic behavior means the same prompt produces different results run to run - so 'what happened?' cannot be answered by re-running, and log greps only show what was logged, not what the agent decided and why. Developers debug by guessing from logs, then re-run the agent hoping to reproduce the failure - which often just produces a different path. Session-level state - the inputs, the reasoning, the tool calls and their results, the errors - exists only in memory and vanishes when the session ends. There is no portable record of an agent run that can be stepped through like a video, forked, compared against another run, or exported into a structured debug view.
Solution
VisReplay is a local session recorder and debugger for AI agents. Wrap an agent object or WebSocket connection with the recorder, run the session, and every decision is captured as an ordered, timestamped event stream - inputs, reasoning, tool calls, tool results, outputs, and errors - plus optional decision records that capture what the agent believed, assumed, and ignored. Sessions save to a portable, self-contained .vrs file (versioned visreplay/session/1.0) that can be replayed deterministically, compared against other runs, and exported into JSON, Markdown incident reports, HTML timelines, or an interactive local debug viewer. v1.1 is deliberately local-first: it makes no network requests, uploads nothing, and never reruns agents or tools - replay reads recorded data only. It also redacts secrets by default (keys and regex patterns) and ships file-only interop exporters that emit Langfuse, OTLP, and LangSmith documents from a session file without talking to any vendor API.
How it works
A developer installs @latticeag/visreplay and creates a VisReplay recorder with a session name and agent type. The recorder wraps any agent object: const agent = recorder.wrap(new DeploymentAgent()), so calls through the wrapped object produce ordered input and output or error events while preserving return values and thrown errors.
The developer runs the agent's task through the wrapped object. Every method call is recorded automatically; manual recording methods - recordReasoning, recordToolCall, recordToolResult - capture agent-specific context a generic proxy cannot know, such as model reasoning and tool semantics.
When the developer knows why a step happened, recordDecision writes a reasoning event with a visreplay/decision/1.0 schema capturing what the agent believed, assumed, and ignored, plus a summary - a structured decision ledger alongside the raw event stream.
For WebSocket-based agents, recordWebSocket observes the connection: incoming messages become output events and send() calls become input events, with JSON text frames parsed so nested secrets get redacted. The recorder never opens a connection or sends traffic itself; text frames are bounded to 1 MiB by default.
The developer calls recorder.end() to mark the logical end of the run and recorder.save('sessions/deploy-staging.vrs') to write a single self-contained UTF-8 JSON document (parent directories are created automatically). Values convert to safe JSON - circular references, bigints, and errors are represented visibly instead of failing the recording.
Replay is deterministic: npx visreplay replay session.vrs steps through each recorded event (Enter advances, q stops), with --auto and --delay for unattended playback. The Player class offers cursor-level stepForward, stepBackward, jumpTo, and reset, plus pause, resume, and stop for host UIs.
Two recordings are compared with npx visreplay compare baseline.vrs candidate.vrs - deterministic and index-aligned, ignoring IDs and timestamps by default so the result focuses on behavioral changes, reporting unchanged, changed, added, and removed events.
Structured debugging is exported from the session: npx visreplay export writes JSON, Markdown incident reports, or a self-contained HTML timeline (no remote assets), and npx visreplay debug generates an interactive local viewer with search, event-type filtering, and keyboard navigation. Interop exporters (--format langfuse|otlp|langsmith) write vendor ingestion documents to files only - never to a network.
Technical architecture
Each handoff carries structured context through the product's execution path. Hover a node to inspect its role.
01
Agent Wrap
02
Event Capture
03
Decision Ledger
04
Session Save
05
Deterministic Replay
06
Run Compare
07
Debug Export
08
Interop Export
When to use
- Debugging non-deterministic agent behavior - same prompt, different results across runs - by comparing recorded sessions.
- Post-incident analysis when an agent took an unexpected path - step through the exact recorded session instead of guessing from logs.
- Comparing how different models or prompts handle the same task - record both runs and diff the event streams.
- Auditing what an agent believed before a bad decision - the decision ledger records assumed and ignored context.
- Exporting an agent run into Langfuse, OTLP, or LangSmith without uploading the session to any vendor.
Not for
- High-throughput production monitoring - VisReplay is a debugging tool, not a metrics pipeline.
- Agents that do not need session-level replay - single-shot completions have nothing to step through.
- Streaming-token capture or framework-specific instrumentation - out of scope for v1.1.
Features
Wrap any agent object - ordered input/output/error events with preserved return values and thrown errors
WebSocket recording - recordWebSocket observes browser-style and Node EventEmitter sockets; send() calls become input events
Six v1 event types - input, reasoning, tool_call, tool_result, output, and error, ordered and UTC-timestamped
Decision ledger - recordDecision captures believed, assumed, and ignored with a visreplay/decision/1.0 schema
Portable session files - self-contained .vrs (visreplay/session/1.0) or .json, with parent directory creation
Deterministic replay - step through events interactively, --auto with configurable delay, never reruns the agent or tools
Run comparison - compareSessions/compareSessionFiles are deterministic and index-aligned, ignoring IDs and timestamps
Secret redaction by default - common keys and OpenAI/GitHub/AWS/JWT-shaped strings redacted recursively, with custom redactKeys and redactPatterns
Structured debug export - JSON, Markdown incident reports, HTML timelines, and an interactive self-contained debug viewer
Interop exporters - file-only Langfuse, OTLP, and LangSmith documents from a local session, never uploaded
Player API for host UIs - stepForward, stepBackward, jumpTo, reset, pause, resume, stop
Local-first by design - makes no network requests, uploads, hosts, or reruns sessions
Safe JSON handling - circular references, undefined, bigints, errors, and functions represented visibly, not failing the recording
Robust session loading - rejects corrupt, non-UTF-8, oversized (>64 MiB) or >500K-event files with actionable errors
MIT licensed - v1.1.0, works on Node.js 20+
Install and usage
# Record a session
import { VisReplay } from "@latticeag/visreplay";
const recorder = new VisReplay({
sessionName: "deploy-staging",
agentType: "custom",
});
const agent = recorder.wrap(new DeploymentAgent());
await agent.run("Deploy to staging");
recorder.recordReasoning("Tests passed, so staging deployment can proceed.");
recorder.recordToolCall("deploy", { environment: "staging" });
recorder.recordToolResult({ deploymentId: "dep_123", status: "complete" });
recorder.end();
await recorder.save("sessions/deploy-staging.vrs");
# Replay step by step
npx visreplay replay sessions/deploy-staging.vrs
# Compare two runs (behavioral changes only)
npx visreplay compare sessions/baseline.vrs sessions/candidate.vrs
# Export a structured debug view
npx visreplay export sessions/deploy-staging.vrs --format markdown --output deploy-report.md
npx visreplay debug sessions/deploy-staging.vrs --output deploy-debug.html
# Write a vendor ingestion document (file only, never uploaded)
npx visreplay export sessions/deploy-staging.vrs --format langfuse --output ingest.jsonArchitecture explorer
Problem
Agent failures are nearly impossible to debug after the fact. Tool calls are text, reasoning traces are lost, and non-deterministic behavior means the same prompt produces different results run to run - so 'what happened?' cannot be answered by re-running, and log greps only show what was logged, not what the agent decided and why. Developers debug by guessing from logs, then re-run the agent hoping to reproduce the failure - which often just produces a different path. Session-level state - the inputs, the reasoning, the tool calls and their results, the errors - exists only in memory and vanishes when the session ends. There is no portable record of an agent run that can be stepped through like a video, forked, compared against another run, or exported into a structured debug view.
Solution
VisReplay is a local session recorder and debugger for AI agents. Wrap an agent object or WebSocket connection with the recorder, run the session, and every decision is captured as an ordered, timestamped event stream - inputs, reasoning, tool calls, tool results, outputs, and errors - plus optional decision records that capture what the agent believed, assumed, and ignored. Sessions save to a portable, self-contained .vrs file (versioned visreplay/session/1.0) that can be replayed deterministically, compared against other runs, and exported into JSON, Markdown incident reports, HTML timelines, or an interactive local debug viewer. v1.1 is deliberately local-first: it makes no network requests, uploads nothing, and never reruns agents or tools - replay reads recorded data only. It also redacts secrets by default (keys and regex patterns) and ships file-only interop exporters that emit Langfuse, OTLP, and LangSmith documents from a session file without talking to any vendor API.