Skip to main content
AgentDbg stores every agent run as two plain files under ~/.agentdbg/runs/<run_id>/. These files are the public trace format (spec_version: "0.1") — a stable contract you can rely on for building tooling, writing scripts, or integrating with other systems. Nothing is sent to any server; everything lives on your machine as human-readable JSON.
All AgentDbg releases that share spec_version "0.1" use the same format. Additive changes (new optional fields, new event types) may be introduced without bumping the spec version. Breaking changes (removed fields, changed types) always result in a new spec_version.

Files per run

Each run lives in its own directory:
~/.agentdbg/
└── runs/
    └── <run_id>/
        ├── run.json       # Run metadata — created at start, updated at end
        └── events.jsonl   # Append-only event log — one JSON object per line
You can override the base directory with the AGENTDBG_DATA_DIR environment variable.

run.json

run.json is created when the run starts and updated when it finishes. It gives you a quick summary of the run without reading the full event log. Required fields:
FieldTypeDescription
spec_versionstringAlways "0.1"
run_idstringUUIDv4 — unique identifier for this run
run_namestring | nullOptional human-readable label
statusstring"running" while active · "ok" on success · "error" on failure
started_atstringUTC ISO8601 timestamp with milliseconds, e.g. "2026-04-12T10:30:00.000Z"
ended_atstring | nullSet when the run finishes; null while still running
duration_msinteger | nullTotal run duration in milliseconds; null while running
countsobjectCumulative event counts (see below)
last_event_tsstring | nullTimestamp of the last event; set when the run finalizes
counts object:
{
  "llm_calls": 0,
  "tool_calls": 0,
  "errors": 0,
  "loop_warnings": 0
}
Full example:
{
  "spec_version": "0.1",
  "run_id": "a1b2c3d4-1234-5678-90ab-cdef12345678",
  "run_name": "customer-support-agent",
  "status": "ok",
  "started_at": "2026-04-12T10:30:00.000Z",
  "ended_at": "2026-04-12T10:30:04.210Z",
  "duration_ms": 4210,
  "counts": {
    "llm_calls": 3,
    "tool_calls": 5,
    "errors": 0,
    "loop_warnings": 0
  },
  "last_event_ts": "2026-04-12T10:30:04.205Z"
}

events.jsonl

events.jsonl is an append-only log where each line is a complete JSON event object. Events are written in the order they occur; when timestamps are identical, the file order is authoritative. AgentDbg flushes after every write so that crashes do not lose the final event.

Event envelope

Every event — regardless of type — has these top-level fields:
FieldTypeDescription
spec_versionstring"0.1"
event_idstringUUIDv4 — unique per event
run_idstringUUIDv4 — run this event belongs to
parent_idstring | nullUUIDv4 of a parent event, or null
event_typestringOne of the event types listed below
tsstringUTC ISO8601 with milliseconds and trailing Z
duration_msinteger | nullDuration in milliseconds if applicable; otherwise null
namestringLabel — tool name, model name, run name, etc.
payloadobjectEvent-type-specific data (see schemas below)
metaobjectFreeform metadata — tags, user-defined fields

Event types

TypeDescription
RUN_STARTEmitted when the traced function begins
RUN_ENDEmitted when the traced function finishes (ok or error)
LLM_CALLOne LLM invocation — model, prompt, response, usage
TOOL_CALLOne tool invocation — name, args, result, status
STATE_UPDATEState snapshot or diff captured between agent steps
ERRORAn exception was captured
LOOP_WARNINGA repeated pattern was detected in recent events

Payload schemas

RUN_START

{
  "run_name": "customer-support-agent",
  "python_version": "3.11.7",
  "platform": "linux",
  "cwd": "/home/user/projects/my-agent",
  "argv": ["run_agent.py", "--env", "staging"]
}
  • run_name comes from AGENTDBG_RUN_NAME, the @trace("name") argument, or a default path:function - YYYY-MM-DD HH:MM label.
  • argv values matching configured redact keys are replaced with __REDACTED__ before being written.

RUN_END

{
  "status": "ok",
  "summary": {
    "llm_calls": 3,
    "tool_calls": 5,
    "errors": 0,
    "duration_ms": 4210
  }
}
status is either "ok" or "error".

LLM_CALL

{
  "model": "gpt-4",
  "prompt": "Summarize the search results.",
  "response": "There are 42 active users.",
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 8,
    "total_tokens": 20
  },
  "provider": "openai",
  "temperature": 0.7,
  "stop_reason": "stop",
  "status": "ok",
  "error": null
}
  • prompt and response may be strings or objects. They may be redacted (__REDACTED__) or truncated (__TRUNCATED__) based on your configuration.
  • usage fields may be null if the provider did not return token counts.
  • When status is "error", the error field contains an object with error_type, message, and optionally stack and details.
  • provider is one of "openai", "anthropic", "local", or "unknown".

TOOL_CALL

{
  "tool_name": "search_db",
  "args": { "query": "active users" },
  "result": { "count": 42 },
  "status": "ok",
  "error": null
}
  • args and result may be objects, strings, or null.
  • When status is "error", error has the same shape as in LLM_CALL.

STATE_UPDATE

{
  "state": { "step": 2, "context_length": 512 },
  "diff": { "step": 2 }
}
  • state is the full snapshot; diff captures only what changed. diff may be null or omitted if not computed.

ERROR

{
  "error_type": "ValueError",
  "message": "Invalid response format from tool.",
  "stack": "Traceback (most recent call last):\n  ...",
  "details": null
}
  • error_type is the Python exception class name.
  • stack may be null if no traceback was available.
  • Guardrail aborts produce an ERROR event with additional fields:
{
  "error_type": "AgentDbgGuardrailExceeded",
  "message": "max_llm_calls exceeded",
  "stack": null,
  "guardrail": "max_llm_calls",
  "threshold": 10,
  "actual": 11
}

LOOP_WARNING

{
  "pattern": "search_db → summarize → search_db",
  "repetitions": 3,
  "window_size": 6,
  "evidence_event_ids": [
    "uuid-of-event-1",
    "uuid-of-event-2"
  ]
}
  • Each distinct pattern triggers at most one LOOP_WARNING per run (deduplicated).
  • When stop_on_loop is enabled, LOOP_WARNING is written first, followed by an ERROR event and RUN_END(status="error").

Redaction and truncation

Before any payload is written to disk, AgentDbg applies redaction and truncation:
  • Redaction: Field values whose key matches a configured pattern (default: api_key, token, authorization, cookie, secret, password) are replaced with the string __REDACTED__. Redaction applies to RUN_START.argv option values and to all event payloads and meta objects.
  • Truncation: Fields that exceed the configured max_field_bytes limit (default 20000 bytes) are replaced with __TRUNCATED__.
Redaction is on by default. You can adjust which keys are redacted or disable redaction entirely via environment variables or config YAML. See the configuration reference.

Using the exported format

When you run agentdbg export, the output file wraps the same data in a single JSON object:
{
  "spec_version": "0.1",
  "run": { "...same fields as run.json..." },
  "events": [ "...array of event objects from events.jsonl..." ]
}
This makes it easy to load a run into any JSON-capable tool, share it with a teammate, or write scripts that process specific event types.