Skip to main content

Context Replay

Context Replay allows you to track and replay the context passed to agents during execution. This is invaluable for debugging, understanding agent behavior, and optimizing context usage.

Quick Start

1. Run with Replay Saving

# Run a recipe and save the replay trace
praisonai recipe run my-recipe --save

# Run agents.yaml with replay saving
praisonai agents.yaml --save

# Run workflow with replay saving
praisonai workflow run my-workflow --save

2. List Available Replays

praisonai replay list

3. Replay a Session

# Interactive step-through replay
praisonai replay context <session_id>

# View agent flow visualization
praisonai replay flow <session_id>

# Show all events (non-interactive)
praisonai replay show <session_id>

4. Clean Up Old Traces

praisonai replay cleanup --max-age 7

Enable Tracing

from praisonaiagents import Agent
from praisonaiagents.trace import ContextTraceEmitter, ContextListSink

# Create a trace sink
sink = ContextListSink()
emitter = ContextTraceEmitter(sink=sink, session_id="my-session")

# Use the emitter to track context changes
emitter.session_start()
emitter.agent_start("researcher")
emitter.message_added("researcher", "user", "Find info about AI", 1, 100)
# ... agent execution ...
emitter.agent_end("researcher")
emitter.session_end()

# Access events
for event in sink.get_events():
    print(f"{event.event_type}: {event.agent_name}")

Persist to File

from praisonai.replay import ContextTraceWriter
from praisonaiagents.trace import ContextTraceEmitter

# Write traces to disk
writer = ContextTraceWriter(session_id="my-session")
emitter = ContextTraceEmitter(sink=writer, session_id="my-session")

emitter.session_start()
# ... your agent code ...
emitter.session_end()
writer.close()  # Flush and close

Replay via CLI

# List available traces
praisonai replay list

# Interactive replay
praisonai replay context my-session

# Show events without interaction
praisonai replay show my-session

# Filter by agent
praisonai replay show my-session --agent researcher

# JSON output
praisonai replay show my-session --json

Event Types

Event TypeDescription
SESSION_STARTSession begins
SESSION_ENDSession ends
AGENT_STARTAgent starts processing
AGENT_ENDAgent finishes processing
AGENT_HANDOFFAgent hands off to another agent
MESSAGE_ADDEDMessage added to context
TOOL_CALL_STARTTool execution begins
TOOL_CALL_ENDTool execution ends
LLM_REQUESTLLM API request sent
LLM_RESPONSELLM API response received
CONTEXT_SNAPSHOTFull context state captured

CLI Commands

praisonai replay flow <session_id>

Visualize agent flow from a trace. Shows agent execution order, handoffs, and statistics.
praisonai replay flow my-session
praisonai replay flow my-session --format json  # JSON output
Example Output:
============================================================
  AGENT FLOW: my-session
============================================================

  ┌────────────────────────────────────────┐
  │ Agent: researcher                      │
  │                                        │
  │   Messages: 2                         │
  │   LLM Calls: 1                        │
  │   Tools: web_search                  │
  └────────────────────────────────────────┘


    [Research complete, ready for writing]

  ┌────────────────────────────────────────┐
  │ Agent: writer                          │
  │                                        │
  │   Messages: 2                         │
  │   LLM Calls: 1                        │
  └────────────────────────────────────────┘

────────────────────────────────────────────────────────────
  Summary:
    Agents: 2
    Handoffs: 1
    Total Events: 15
────────────────────────────────────────────────────────────

praisonai replay list

List available context traces.
praisonai replay list
praisonai replay list --limit 50
praisonai replay list --json

praisonai replay context <session_id>

Interactive step-through replay of a trace.
praisonai replay context my-session
praisonai replay context my-session --start 5  # Start from event 5
praisonai replay context my-session --no-rich  # Plain text output
Navigation:
  • Enter / n / - Next event
  • p / - Previous event
  • g <N> - Go to event N
  • q - Quit

praisonai replay show <session_id>

Display trace events without interactive mode.
praisonai replay show my-session
praisonai replay show my-session --event 5      # Show specific event
praisonai replay show my-session --agent writer # Filter by agent
praisonai replay show my-session --type agent_start  # Filter by type
praisonai replay show my-session --json         # JSON output

praisonai replay delete <session_id>

Delete a trace.
praisonai replay delete my-session
praisonai replay delete my-session --force  # Skip confirmation

praisonai replay cleanup

Clean up old traces.
praisonai replay cleanup
praisonai replay cleanup --max-age 14      # Delete traces older than 14 days
praisonai replay cleanup --max-size 200    # Keep total size under 200MB
praisonai replay cleanup --dry-run         # Preview what would be deleted

Python API

ContextEvent

from praisonaiagents.trace import ContextEvent, ContextEventType

event = ContextEvent(
    event_type=ContextEventType.MESSAGE_ADDED,
    timestamp=time.time(),
    session_id="my-session",
    agent_name="researcher",
    messages_count=5,
    tokens_used=1500,
    tokens_budget=128000,
    data={"role": "user", "content": "Hello"},
)

# Serialize
json_str = event.to_json()
event_dict = event.to_dict()

# Deserialize
event = ContextEvent.from_dict(event_dict)

ContextTraceEmitter

from praisonaiagents.trace import ContextTraceEmitter, ContextListSink

sink = ContextListSink()
emitter = ContextTraceEmitter(
    sink=sink,
    session_id="my-session",
    enabled=True,
    redact=True,  # Redact sensitive data
)

# Session lifecycle
emitter.session_start()
emitter.session_end()

# Agent lifecycle
emitter.agent_start("agent_name")
emitter.agent_end("agent_name")

# Messages
emitter.message_added(
    agent_name="agent",
    role="user",
    content="Hello",
    messages_count=1,
    tokens_used=10,
)

# Tool calls
emitter.tool_call_start("agent", "tool_name", {"arg": "value"})
emitter.tool_call_end("agent", "tool_name", "result", duration_ms=100)

# LLM calls
emitter.llm_request("agent", messages_count=5, tokens_used=1000, tokens_budget=128000)
emitter.llm_response("agent", response_tokens=500, duration_ms=1500)

# Full context snapshot
emitter.context_snapshot(
    agent_name="agent",
    messages_count=10,
    tokens_used=5000,
    tokens_budget=128000,
    messages=[{"role": "user", "content": "..."}],
)

# Agent handoff (for flow visualization)
emitter.agent_handoff(
    from_agent="researcher",
    to_agent="writer",
    reason="Research complete, ready for writing",
    context_passed={"findings": ["result1", "result2"]},
)

ContextTraceWriter

from praisonai.replay import ContextTraceWriter

# Basic usage
writer = ContextTraceWriter(session_id="my-session")
writer.emit(event)
writer.close()

# Context manager
with ContextTraceWriter(session_id="my-session") as writer:
    writer.emit(event)

ContextTraceReader

from praisonai.replay import ContextTraceReader

reader = ContextTraceReader("my-session")

# Check existence
if reader.exists:
    # Iterate
    for event in reader:
        print(event.event_type)
    
    # Random access
    event = reader[0]
    
    # Get all
    events = reader.get_all()
    
    # Filter
    agent_events = reader.get_by_agent("researcher")
    tool_events = reader.get_by_type("tool_call_start")

ReplayPlayer

from praisonai.replay import ContextTraceReader, ReplayPlayer

reader = ContextTraceReader("my-session")
player = ReplayPlayer(reader, use_rich=True)

# Interactive mode
player.run()

# Programmatic navigation
player.display_current()
player.next()
player.previous()
player.goto(5)

Storage

Traces are stored as JSONL files in ~/.praisonai/traces/.
~/.praisonai/traces/
├── session-abc123.jsonl
├── session-def456.jsonl
└── ...
Each line is a JSON object representing one event.

Performance

  • Zero overhead when disabled: enabled=False skips all processing
  • Buffered writes: Events are buffered before writing to disk
  • Lazy loading: Reader loads events on first access
  • Automatic cleanup: Old traces can be auto-rotated

Best Practices

  1. Use meaningful session IDs: Include timestamp or task identifier
  2. Enable redaction: Sensitive data is redacted by default
  3. Clean up old traces: Use praisonai replay cleanup periodically
  4. Use snapshots sparingly: Full context snapshots can be large