--- title: OpenHands description: How ClawMetry observes OpenHands — where its data lives, the environment variables that move it, what cost data is real, and the traps in its store. eyebrow: Runtime reference --- # OpenHands OpenHands is the largest open-source autonomous software agent and the reference harness behind most published SWE-bench trajectory datasets. It stores a directory of immutable JSON events per conversation plus a header file that is rewritten in full on every mutation. | | | |---|---| | **Runtime id** | `openhands` | | **Category** | Autonomous software agent | | **Vendor** | OpenHands | | **Tier** | Paid tier (Starter and up) | | **Upstream** | [github.com/OpenHands/OpenHands](https://github.com/OpenHands/OpenHands) | ## Where the data comes from ClawMetry reads these locations, in order, and never writes to any of them. - `$OPENHANDS_PERSISTENCE_DIR/conversations//base_state.json (default ~/.openhands)` - `/conversations//events/event-NNNNN-.json` - `/conversations//subagents//…` — delegated children **Format.** A directory of JSON files — not JSONL, not a database. Each event is written once; `base_state.json` is rewritten in full. ## Environment variables | Variable | Effect | |---|---| | `OPENHANDS_PERSISTENCE_DIR` | OpenHands' own persistence root | | `CLAWMETRY_OPENHANDS_HOME` | ClawMetry-side override | See [Environment variables](/docs/config/environment/) for the variables that apply to every runtime. ## Tokens and cost **Tokens.** In `base_state.json` under `stats.usage_to_metrics`, keyed by an LLM usage id. **Cost.** Populated only when LiteLLM can price the model. ClawMetry derives from the token split when the reported figure is zero but the model is priceable. :::note Why this section exists Runtimes differ enormously in what they persist. Rather than showing a plausible number everywhere, ClawMetry reports what the store actually contains and marks the rest unknown. A cost of `$0.00` and a cost of *unknown* mean different things, and the dashboard keeps them different. ::: ## Sub-agents and delegation Delegated children live under a `subagents/` subtree and have their own metrics. ## Things worth knowing - `` is the conversation UUID with dashes stripped, while `base_state.json` stores the same id *with* dashes. Matching without normalising finds nothing. - `prompt_tokens` is the sum across calls, so it counts the re-read of context every turn. It is billing-shaped, not context-shaped, and must not be shown as 'context size'. - The `delegate:*` usage keys hold a copy of a child's metrics. Summing them into the parent *and* listing the child would count it twice, so they are excluded from the parent row. - `base_state.json` is ~430 KB even for a trivial session, ~99% of it the persisted agent blob. ClawMetry does a bounded tail read for listings and only parses fully on demand. ## Verify it is being read ```bash # Is this runtime detected, and would this install unlock it? clawmetry runtimes --json | jq '.runtimes[] | select(.id=="openhands")' # Why is it locked, if it is? clawmetry runtimes --why openhands # Any sessions ingested yet? curl -s 'http://localhost:8900/api/local/sessions?limit=5' \ | jq '.rows[] | {session_id, agent_id, events, cost_usd}' ``` If detection succeeds but no sessions appear, work through [Troubleshooting](/docs/ops/troubleshooting/) — the usual causes are a relocated data directory (set the override above), a session limit that is hiding older runs, or a runtime that simply has not written anything yet.