Runtime / Agent Compatibility

August 29, 2026 · View on GitHub

ClawMetry observes 30 AI-agent runtimes. Each runtime that isn't OpenClaw ships a dedicated reader adapter (clawmetry/adapters/) that translates its native session format into ClawMetry's unified Session/Event shapes; the daemon then ingests them into the same local DuckDB store and cloud snapshot, tagged with the runtime. When more than one runtime is present on a node, the Session replay tab shows a runtime switcher (All / per runtime). This page tracks each one's real status, honestly.

New to NanoClaw / PicoClaw? See RUNTIME_FAMILY.md for a primer on the OpenClaw-family runtimes specifically.

Running Perplexity's numbat agent-security tool? ClawMetry ingests its findings and enforcement decisions out of the box. See NUMBAT.md.

Runtime / AgentStatusSession storeNotes
OpenClawNativev3 JSONL ~/.openclaw/agents/main/sessions/Reference runtime; auto-detected.
NVIDIA NemoClawNativeOpenClaw v3 JSONL on the host or inside an OpenShell containerAuto-detected (binary + container scan). See NEMOCLAW.md.
PicoClawBeta adapterFlat providers.Message JSONL ~/.picoclaw/workspace/sessions/Transcripts, model, tool calls. Tokens/cost not on disk.
NanoClawBeta adapterPer-session SQLite data/v2-sessions/<group>/<session>/{inbound,outbound}.dbTranscripts. Model/tokens/cost not on disk.
HermesBeta adapterSQLite ~/.hermes/state.db (sessions + messages)Transcripts, model, pre-computed tokens/cost.
Claude CodeBeta adapterJSONL ~/.claude/projects/<cwd>/<id>.jsonl (v-type lines)Transcripts, model, tool calls + thinking, token usage.
CodexBeta adapter"rollout" JSONL ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonlTranscripts, model, tool calls, token usage (from token_count events).
CursorBeta adapterSQLite state.vscdb (cursorDiskKV / ItemTable, global + per-workspace)Chat/composer transcripts, model. No billed cost on disk (server-side).
AiderBeta adapterMarkdown .aider.chat.history.md per project dir (+ .aider.input.history)Transcripts, model, token counts. Per-project history (set AIDER_HISTORY_DIRS).
GooseBeta adapter (free)SQLite <goose data dir>/sessions/sessions.db${XDG_DATA_HOME:-~/.local/share}/goose on macOS and Linux, %APPDATA%\Block\goose\data on Windows, or $GOOSE_PATH_ROOT/data when that is set (sessions + messages tables)Transcripts, model, tool calls, real token totals. Adapter ships in the OSS package (clawmetry/adapters/goose.py) — no plan required.
opencodeBeta adapterSQLite ~/.local/share/opencode/opencode.db (session/message/part)Transcripts, model, tool calls, real tokens + cost.
Qwen CodeBeta adapterJSONL ~/.qwen/projects/<hash>/chats/<id>.jsonl (Gemini-CLI lineage)Transcripts, model, tool calls + thinking, real token usage.
PiBeta adapterJSONL ~/.pi/agent/sessions/Transcripts, model, tool calls, real tokens + cost.
Deep AgentsBeta adapterSQLite ~/.deepagents/.state/sessions.dbTranscripts, model, tool calls, real tokens + cost.
n8nBeta adapterSQLite ~/.n8n/database.sqlite (execution_entity/execution_data, WAL)Workflow executions as sessions, node runs as tool calls, AI Agent prompts + model attribution; tokens + cost where the model sub-node records usage. Postgres and n8n Cloud installs are not covered by this adapter.
AntigravityBeta adapterBrain JSONL under ~/.gemini/<flavor>/brain/<uuid>/ (flavors: antigravity, antigravity-cli, antigravity-ide, jetski) + conversations/<uuid>.db (SQLite, WAL)Conversations as sessions, planner/tool steps as events, thinking + checkpoint (compaction) events; per-generation model, token split (prompt/thinking/response) and cost decoded from gen_metadata; background-generation burn; subagent + battle-mode metadata.
GitHub CopilotBeta adapterCopilot CLI events.jsonl under ~/.copilot/session-state/ + the session-store.db per-call usage ledgerConversations, tool calls, model routing, cache-aware token split, vendor-billed AI-credit cost.
Grok BuildBeta adapterxAI Grok Build CLI: ~/.grok/logs/unified.jsonl + per-session ~/.grok/sessions/<enc-cwd>/<uuid>/{events.jsonl,summary.json}Conversations, per-turn token split, model routing, and the outbound repo payload staged under ~/.grok/upload_queue/.
Grok BotBeta adapterxAI Grok Bot desktop client (Anysphere com.anysphere.sand): ~/Library/Application Support/Grok Bot/sand-client-persistence/*.blob (base32-named plaintext JSON) + ~/.grokbot/Full transcripts, both sides, plus local tool-permission asks and the MCP / egress-tunnel posture. No tokens, model or cost: the bot infers on its own cloud VM and none of that reaches the client, so no spend is reported rather than a derived guess. One desktop process serves every bot, so there is no per-bot pause/stop/kill.
QMBeta adapterPostgres (no on-disk session store); adapter reads DATABASE_URL / CLAWMETRY_QM_DATABASE_URL read-onlyYC's multiplayer harness; delegates to Pi / opencode / Codex / Claude Code, which show up as their own runtimes.
DeepSeek HarnessBeta adapterJSONL under $DSH_HOME/sessions (default ~/.dsh/sessions), zstd-compressed by defaultTranscripts, model, tool calls. zstandard is installed lazily, only once compressed dsh data is detected.
ExoBeta adapterOne pretty-printed JSON file per event under <workspace>/.exo/exoharness/agents/*/conversations/*/events/Per-call usage + cost persisted by Exo itself. State dir is workspace-relative; set CLAWMETRY_EXO_ROOTS for unusual layouts.
Kimi CLIBeta adapterOne wire.jsonl event log per session under <share>/sessions/<md5(workdir)>/<uuid>/Reads both share dirs (~/.kimi, ~/.kimi-code) plus $KIMI_SHARE_DIR. Model id is not written to disk.
Gemini CLIBeta adapterOne JSONL chat recording per session under ~/.gemini/tmp/<project-basename>/chats/session-<ts>-<id8>.jsonlRecording is always on (no setting to enable). Per-turn token split + model id + tool calls with results, and nested chats/<parentSessionId>/ sub-agent transcripts. The project dir is the cwd's BASENAME; the sha256 is stored inside the file as projectHash. GEMINI_CLI_HOME names the dir containing .gemini.
ClineBeta adapterSQLite index at ~/.cline/data/db/sessions.db plus ~/.cline/data/sessions/<id>/<id>.messages.json per sessionCost in USD is on disk, which is rare. The index records pid, status and sub-agent lineage, so liveness is reported rather than guessed. Rejected tool calls are surfaced as errors. Note the data leaf: ~/.cline itself holds only hooks and worktrees.
OpenHandsBeta adapterOne directory per conversation under ~/.openhands/conversations/<hex>/base_state.json plus one immutable JSON file per eventTokens and per-call cost live in the sidecar, never on the events. The directory name is the conversation id with dashes stripped. prompt_tokens is cumulative across calls, and cost reads 0.0 both for a free local model and for a failed pricing lookup. Delegated sub-agents nest under subagents/.
DevinBeta adapterOne SQLite store for every session ($XDG_DATA_HOME/devin/cli/sessions.db) holding a message forest plus the ACP tool-call recordsSessions and tool calls. Fork and revert leave abandoned branches, which the adapter excludes so they are never billed. Whether usage and cost are recorded has not been verified against a real capture yet, so no token or cost number is claimed. Devin Cloud sessions are API-only and not ingested.
LovableBeta adapterA local git clone of the Lovable-synced GitHub repo — Lovable's agent runs entirely in the vendor cloud, and its GitHub two-way sync writes one bot commit per accepted agent edit, so the clone is a real per-edit activity record (CLAWMETRY_LOVABLE_DIRS points at clone roots)One session per project, one event per accepted edit, with the prompting teammate attributed from the co-author trailer. No tokens, model or cost: Lovable bills credits in the vendor cloud and none of it reaches the clone, so no spend is reported rather than a derived guess. Data is only as fresh as the last git fetch, which the session states. No liveness claims and no per-session control: nothing runs locally.
Replit AgentBeta adapterOne transcript.jsonl journal per session under <workspace>/.local/state/replit/agent/transcript/<uuid>/ — the agent loop runs on Replit's infrastructure but serializes into the Repl workspace, so the daemon reads it from inside the Repl (pip install clawmetry in the workspace shell) or over a clone (CLAWMETRY_REPLIT_ROOTS)Full transcripts with tool calls (write/edit/bash/screenshot vocabulary), typed prompts extracted from the injected wrapper, structural tool errors. No tokens, model, cost or timestamps in the workspace journal: Replit bills effort-based checkpoints server-side, so no spend is reported rather than a derived guess, and session times come from file mtimes with the basis declared. No per-session pause/stop/kill: the loop is not a workspace process.
OpenWorkerBeta adapterA SQLite index plus one append-only JSONL per session under ~/.config/coworker/ ($COWORKER_STATE_DIR, or %APPDATA%\coworker on Windows). The same coworker.db file holds both the session index and the audit logSessions, events, cost and sub-agents. The token split rides a per-message sidecar tagged with the model that produced that turn, so a session that switches models is priced per model. OpenWorker writes no dollars, so cost is always derived and never reported. Team workers carry their lead session, which becomes real sub-agent lineage. The audit log's token columns meter the Auto-Approve reviewer rather than the agent, so they are excluded from session cost. Per-session pause and stop are not offered: one desktop process serves every session.
ZeroClaw / TrustClaw / NanobotNot yetunverifiedOpen an issue with a real session capture.

OpenClaw, NVIDIA NemoClaw and Goose are free in the OSS package — their adapters ship in pip install clawmetry, so observing them needs no account, no licence key and no network call. The rule: an open-source runtime gets a free, open-source adapter; a commercial vendor product (Claude Code, Codex, GitHub Copilot, Cursor, Antigravity, Grok) needs a Starter or Pro plan, or a self-hosted licence key. See ENTITLEMENTS.md.

What "Beta adapter" means (and what it does not)

A Beta adapter means ClawMetry ships a reader for that runtime's real on-disk format, validated against a session captured from a real install of that runtime (we installed and ran both, see tests/fixtures/runtimes/<runtime>/REAL/PROVENANCE.md), with fixture-backed CI tests that fail if the parse path regresses. It is not the same as the earlier "Verified" claim, which was withdrawn: that had been based on fixtures that were actually OpenClaw v3 records relabeled, and so proved only that ClawMetry parses OpenClaw's shape. Running the real runtimes caught real bugs the relabeled fixtures could never have (PicoClaw's nested tool-call shape and Go's trailing-zero timestamps; NanoClaw's CWD-relative data dir).

PicoClaw and NanoClaw do not share OpenClaw's layout (verified 2026-05-25 against the real sources):

  • PicoClaw (github.com/sipeed/picoclaw, Go) writes a flat providers.Message per JSONL line (fields role, content as a string, model_name, created_at, tool_calls, ...), under $PICOCLAW_HOME/workspace/sessions/<key>.jsonl with a <key>.meta.json sidecar. There is no token/cost field on disk, so ClawMetry shows transcripts, model, and tool calls but reports tokens/cost as unavailable. See PRD_PICOCLAW.md.
  • NanoClaw (github.com/nanocoai/nanoclaw, TypeScript) stores each session as a pair of SQLite files (inbound.db / outbound.db) under data/v2-sessions/<agent_group_id>/<session_id>/. The message tables carry no model/token/cost columns, so ClawMetry shows transcripts and message counts but reports model/tokens/cost as unavailable. See PRD_NANOCLAW.md.

A "Verified" badge will be restored per runtime only after a session captured from a real install of that runtime passes its adapter test, and the live end-to-end path (dashboard + cloud snapshot) is confirmed.

Cloud runtime label (live-verified)

The sync daemon detects PicoClaw / NanoClaw installs (via each adapter's detect()) and ships a runtime label in the encrypted snapshot, both as runtimeInfo.items[] rows and a small top-level detectedRuntimes summary ({name, displayName, sessionCount, workspace}). The cloud Runtime panel renders these alongside OpenClaw with no cloud code change. This was verified by decrypting the live cloud snapshot of a real node, which showed PicoClaw: detected (1 session) and NanoClaw: detected (2 sessions). Pure detection only: no DuckDB access and no writer lock are involved.

Pointing ClawMetry at PicoClaw or NanoClaw

When a runtime's home directory exists, its adapter registers automatically and appears in the multi-agent view:

# PicoClaw: adapter auto-registers when ~/.picoclaw exists (or PICOCLAW_HOME set)
export PICOCLAW_HOME=~/.picoclaw      # only if you use a non-default home
clawmetry

# NanoClaw: adapter auto-registers when ~/.nanoclaw exists (or NANOCLAW_HOME set).
# NanoClaw resolves its data dir relative to where it was launched
# (process.cwd()/data), so if your install keeps data elsewhere, point at it:
export NANOCLAW_HOME=/path/to/nanoclaw   # expects <NANOCLAW_HOME>/data/v2-sessions
clawmetry

These adapters read their runtime's files strictly read-only (NanoClaw's SQLite is opened mode=ro&immutable=1), consistent with ClawMetry's read-only charter.

Adding a new runtime

  1. Capture a real session from the runtime and confirm its on-disk format (path, file type, wire shape). Do not assume it matches OpenClaw.
  2. If it writes OpenClaw v3 JSONL under agents/main/sessions/, it works already; add a fixture + a row here.
  3. If it uses its own format, add a reader adapter under clawmetry/adapters/ (subclass AgentAdapter, translate the native format into the unified Session/Event shapes), with fixture-backed tests, and register it in dashboard.py gated on the runtime's home directory.
  4. Be honest in capabilities() and in this matrix: only advertise what the on-disk data actually supports.

What "shared OpenClaw layout" means

A runtime works with zero adapter code only if it writes session files matching all of:

  • One JSONL per session, named <session_id>.jsonl
  • Located under <root>/agents/<agent_id>/sessions/
  • First line is a {"type": "session", "version": 3, ...} record
  • Assistant turns carry message.usage.totalTokens and (optionally) message.usage.cost.total
  • Model identity via model_change events and/or message.model

Runtimes that diverge from this (PicoClaw's flat JSONL, NanoClaw's SQLite) need the dedicated adapter described above.