language:
- en
- zh
license: mit
task_categories: - text-generation
tags: - agent
- tool-calls
- trajectories
- audit
- llm-agents
size_categories: - 1K<n<10K
configs: - config_name: default
data_files:- split: train
path: data/train.parquet
- split: train
- config_name: legacy
data_files:- split: train
path: data/legacy.parquet
- split: train
MimirAether Agent Traces
9,299 unique real agent sessions · 90,608 tool calls in the curated view from a multi-agent system in daily production — four cooperating agents (orchestrator, executor, red-team reviewer, verifier) running real workloads since May 2026.
What makes this corpus different: it is not single-agent coding transcripts. It captures inter-agent collaboration in production — task dispatch, cross-audits, failure & recovery (real incidents: gateway freezes, API outages, deadlocks — with their debug sessions included), and self-correction loops. If you train or evaluate agents on cooperation, failure recovery, or long-horizon operations, this is the rare real-world source.
🔗 This dataset is the runtime trace of MimirAether — an open-source, self-hosted agent runtime under active development (code, docs, roadmap & CI on GitHub). Issues and feedback on data quality are welcome on either repo.
🔄 Continuously updated — new sessions are appended in small batches (~every 100 sessions) as the runtime keeps operating.
Loading
from datasets import load_dataset
# curated corpus: 4,404 sessions, schema v1+v2 mixed, one row = one agent session
ds = load_dataset("kelikelibababian/mimir-agent-traces", split="train")
# pre-filter archive: 8,670 sessions, v1-era, kept as-is for provenance
legacy = load_dataset("kelikelibababian/mimir-agent-traces", "legacy", split="train")
Both configs are Parquet views: data/train.parquet over the append-only JSONL data/mimir-agent-traces.jsonl, and data/legacy.parquet over data/mimir-agent-traces-legacy-full.jsonl. Raw JSONL is never rewritten — Parquet is the view, JSONL is the source of truth. Rows uploaded before schema v2 carry null in the seven v2-only columns, so the curated corpus loads as a single table.
Statistics
Snapshot: 2026-10-19.
| Metric | Curated (default) |
Pre-filter archive (legacy) |
|---|---|---|
| Rows (sessions) | 4,404 | 8,670 |
| Unique sessions (union of both configs) | 9,299 | — |
| Total tool calls | 90,608 | 73,740 |
| Avg / median tool calls per session | 20.6 / 13 | — |
| Sessions with zero tool calls | 23 (0.5%) | — |
| Duration p50 / p90 | 113 s / 593 s | — |
| Schema v2 rows | 2,236 (50.8%) | — |
Schema v1 rows (no schema_version) |
2,168 (49.2%) | — |
exit_reason (curated): null 3,305 · natural 983 · empty_response 43 · max_turns 29 · empty_content 26 · interrupt 12 · verify_exhausted 4 · billing_exhausted 2.
exit_reasoncaveat: most v1 rows arenull— the recorder only started writingsession_endtelemetry partway through the corpus, and pre-2026-08-29session_endevents lack theexit_reasonkey. Even in schema v2 batches the value can benullwhen the underlying telemetry omits it. The v2 gate guarantees the session ended; it cannot backfill a missing reason.
What's inside
Each row = one complete agent session.
Schema note: v1 rows cap
task_desc_sanitizedat 200 chars; from schema v2 (2026-09-13) the cap is 300. v1 rows lack theschema_versionfield — absence of the field = v1.
| Field | Type | Description |
|---|---|---|
session_id |
string | session identifier (two conventions — see Known limitations) |
n_tool_calls |
int64 | number of tool calls in session |
duration_seconds |
float64? | wall-clock duration |
exit_reason |
string? | how the run ended (natural / max_turns / interrupt / circuit_breaker / tool_storm / api_failure / empty_response / empty_content); null for many v1 sessions |
tool_sequence |
list |
ordered sequence of tool names (capped at 80) |
has_exit_reason |
bool | whether telemetry recorded an exit reason |
task_desc_sanitized |
string | task description, truncated (200 chars v1 / 300 chars v2) |
schema_version |
string? | "2.0" for v2 rows; null for v1 rows |
agent_id |
string? | which agent ran it — mimir / hermes / openclaw / loki |
model |
string? | batch-level model name (see Model field caliber) |
trace_id_prefix |
string? | first 8 hex of the trace id, for joining the audit stream |
trigger_source |
string? | feishu / api / hermes-dispatch / buzz-watcher / cli / cron |
task_category |
string? | heuristic task class (weak signal — see below) |
task_subcategory |
string? | finer task class |
Categories (heuristic, curated v2 rows only)
Assigned by a deterministic tool-name voting table (no LLM), so treat them as a weak signal for stratification, not ground truth.
| Category | Rows |
|---|---|
| Terminal & Coding | 1,455 |
| Retrieval | 584 |
| Other (zero-tool or tied votes) | 111 |
| Browser | 48 |
| Agent Tools | 22 |
| Memory | 16 |
| Communication / Creative / Analysis | 0 in this snapshot |
Model field caliber
model is a batch-level value (trajectories carry no per-session model). Resolution order: runtime telemetry (last_context_usage.json, what the gateway actually used) → config.yaml model.default → legacy .env MIMIR_MODEL. A model switch mid-window makes the batch value approximate for sessions before the switch; exact per-session models land once the runtime writes model into session_start (planned).
Why this matters
Real-world agent behavior data is scarce; real-world multi-agent failure data is nearly nonexistent. Most published agent benchmarks are synthetic. This dataset captures what agents actually do in production — including genuine incident-response sessions (e.g., a cron job freezing the event loop, diagnosed via py-spy and fixed live; API-provider outages with retry/backoff traces), tool-usage patterns, and self-audit loops where an agent finds its own bug and files a correction. Failure trajectories are included deliberately: they are the hardest data to synthesize and the most valuable for robustness training.
Useful for: agent behavior modeling, tool-use pattern mining, failure analysis, run-boundary research, agent memory studies.
How sessions are recorded
runtime session (local JSONL, never uploaded)
→ aggregator: metadata only (task description, tool-name sequence, counts, timing)
→ sanitizer: hash session id, redact names/paths/emails, truncate task description
→ batch lint: per-row identifier scan — a row that fails is dropped, not masked
→ upload in small batches (~100 sessions) + one line per batch in manifest.jsonl
Message bodies and tool arguments/outputs never leave the machine: a row carries the shape of the session (which tools, in what order, how long, how it ended), not its contents.
Sanitization
All identifiers are hashed; user names, paths, emails and internal infrastructure names are redacted. Task descriptions truncated (200 chars v1 / 300 chars v2). Tool arguments/outputs are not included (privacy) — only the tool-name sequence and metadata. Every batch is scanned for personal identifiers before upload; any row that fails the scan is dropped.
Known limitations
- Session identity has two conventions. Curated v2 rows use a salt-free SHA-1 prefix of the runtime session id; legacy rows use the first 8 characters of the raw session id. Both are deterministic and stable, but do not mix them when joining across configs.
- Session continuation: a session continued across midnight (≈4% of sessions) keeps the same id; the dataset keeps the first uploaded version and later continuation files are skipped (no upsert). Rows are always duplicate-free — at worst the tail of a continued session is missing.
- Batch-level
model: see Model field caliber above. task_categoryis heuristic — see the caveat above.
Provenance
Every upload is recorded in manifest.jsonl (batch / date / sessions / notes); schema_v2.json documents the v2 row contract. Raw runtime session files are never uploaded — only aggregated statistic rows.
Related
- 💻 Runtime source: MimirAether (actively developed)
- 📖 Attribution system: commit trailer
Agent: <id>+ dual-stream audit (tool-level + hook-level) +who_did.pyself-check entry point