Trace format (public contract)
This page describes the public trace format for AgentDbg (spec_version: "0.1"). Traces are stored locally as JSONL events plus a run metadata file (run.json). The format is a public contract: consumers can rely on it for tooling and integrations.
Versioning: The trace format is versioned independently from the package version via spec_version (currently "0.1"). All AgentDbg releases (v0.1.x, v0.2.x, etc.) that use spec_version "0.1" share the same trace format. Additive changes (new optional fields, new event types) may be introduced without a spec version bump. Breaking changes will result in a new spec_version.
Overview
- Per run: One directory
runs/<run_id>/containing: - events.jsonl - append-only; one JSON object per line (one event per line).
- run.json - run metadata; written at run start and updated at run end.
- Ordering: Events in
events.jsonlare in write order; when timestamps tie, this order is authoritative. - Flushing: Events are flushed after every write so that crashes do not lose the last event.
Redaction and truncation: All payloads (and meta) written to disk pass through redaction and truncation before being written. This includes ERROR payloads and RUN_START.argv (option values matching redact keys are redacted). See the configuration reference for redact, redact_keys, and max_field_bytes.
Event envelope (all events)
Every event is a single JSON object with these required top-level fields:
| Field | Type | Description |
|---|---|---|
spec_version |
string | Schema version, e.g. "0.1" |
event_id |
string | UUIDv4, unique per event |
run_id |
string | UUIDv4, run this event belongs to |
parent_id |
string | null | UUIDv4 of parent event, or null |
event_type |
string | One of the event types below |
ts |
string | UTC ISO8601 with milliseconds and trailing Z, e.g. 2026-02-15T20:31:05.123Z |
duration_ms |
integer | null | Duration in milliseconds if applicable |
name |
string | Label (e.g. tool name, model name, run name) |
payload |
object | Event-type-specific data (see below) |
meta |
object | Freeform metadata (tags, user-defined) |
Timestamp and ID rules
- Timestamps:
tsMUST be UTC ISO8601 with millisecond precision and trailingZ. - IDs:
run_idandevent_idMUST be UUIDv4 strings (canonical form with hyphens).
Event types
| Type | Description |
|---|---|
RUN_START |
Run started (emitted by @trace / traced_run) |
RUN_END |
Run finished (ok or error) |
LLM_CALL |
One LLM invocation (model, prompt, response, usage) |
TOOL_CALL |
One tool invocation (name, args, result, status) |
STATE_UPDATE |
State snapshot or diff (e.g. between steps) |
ERROR |
Exception captured (type, message, stack) |
LOOP_WARNING |
Loop detection: repeated pattern in recent events |
Payload schemas by event type
RUN_START
{
"run_name": "optional string or null",
"python_version": "3.11.7",
"platform": "darwin | linux | win32",
"cwd": "/path/to/cwd",
"argv": ["script.py", "arg1"]
}
- run_name is set from:
AGENTDBG_RUN_NAME(env), explicit@trace("...")/@trace(name="...")ortraced_run(name="..."), or defaultpath:function - YYYY-MM-DD HH:MM. See configuration reference. - argv may contain secrets; values for options matching redact keys are redacted before write.
RUN_END
{
"status": "ok | error",
"summary": {
"llm_calls": 3,
"tool_calls": 5,
"errors": 0,
"duration_ms": 1234
}
}
LLM_CALL
{
"model": "string",
"prompt": "string | object | null",
"response": "string | object | null",
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0
},
"provider": "openai | anthropic | local | unknown",
"temperature": 0.0,
"stop_reason": "string | null",
"status": "ok | error",
"error": "object | null"
}
usagefields may benullif unknown.promptandresponsemay be redacted or truncated by config.- When
statusis"error",erroris an object witherror_type,message, optionaldetails, optionalstack(same shape as ERROR event payload).
TOOL_CALL
{
"tool_name": "string",
"args": "object | string | null",
"result": "object | string | null",
"status": "ok | error",
"error": "object | null"
}
- When
statusis"error",erroris an object witherror_type,message, optionaldetails, optionalstack(same shape as ERROR event payload).
STATE_UPDATE
{
"state": "object | string | null",
"diff": "object | string | null"
}
diffis optional; may be omitted if not computed.
ERROR
Error payloads use a consistent shape (same for standalone ERROR events and nested error in LLM_CALL/TOOL_CALL):
{
"error_type": "ExceptionClassName",
"message": "string",
"stack": "string | null",
"details": "optional, any"
}
- Use
error_type(nottype) for the exception class name. - Guardrail aborts also use
ERROR. In that case the payload includes the normal fields above plus guardrail-specific fields such asguardrail,threshold, andactualso consumers can tell the run was intentionally stopped by a configured limit.
LOOP_WARNING
{
"pattern": "string",
"repetitions": 3,
"window_size": 6,
"evidence_event_ids": ["event_uuid_1", "event_uuid_2"]
}
- Emitted at most once per run per distinct pattern (deduplicated).
- If
stop_on_loopguardrails are enabled,LOOP_WARNINGis still written first and is then followed byERRORandRUN_END(status="error").
run.json schema
Each run has a run.json file in its directory. It is created at run start and updated at run end.
Required fields:
| Field | Type | Description |
|---|---|---|
spec_version |
string | "0.1" |
run_id |
string | UUIDv4 |
run_name |
string | null | Optional run label |
started_at |
string | UTC ISO8601 with ms and Z |
ended_at |
string | null | Set when run finishes; null while running |
duration_ms |
integer | null | Total run duration in ms; null while running |
status |
string | "running" | "ok" | "error" |
counts |
object | See below |
last_event_ts |
string | null | Timestamp of last event; set at finalize |
counts object:
{
"llm_calls": 0,
"tool_calls": 0,
"errors": 0,
"loop_warnings": 0
}
Lifecycle semantics
- On run start:
run.jsonis written withstatus: "running",ended_at: null,duration_ms: null(or 0), and zero counts. - On run end:
run.jsonis updated withstatus: "ok"or"error",ended_at,duration_ms, finalcounts, andlast_event_ts.
Versioning note
The trace format is a public contract versioned independently from the AgentDbg package version. All releases using spec_version "0.1" share this format. Additive changes (e.g. new optional fields, new event types) are allowed without a spec version bump. Breaking changes (removing fields, changing types or semantics) will be accompanied by a new spec_version. The markdown reference on this page is canonical; JSON schemas in the repo root schemas/ folder (run.schema.json, event.schema.json) are best-effort for tooling.