CClawMetryDocs

Runtimes

Track any SDK agent#

The 27 supported runtimes all write sessions to disk. Your own production agent does not — a service built on the OpenAI Agents SDK, LangChain, the Vercel AI SDK, LlamaIndex, E2B or a plain httpx loop keeps its state in your application, not in a transcript directory.

The interceptor covers that case. It monkey-patches the HTTP client, captures every LLM call, and writes them where the daemon already looks.

Two lines#

python
import clawmetry.track                          # activate the interceptor
clawmetry.track.set_source("support-agent")     # name this product

That is the whole integration. From here every LLM call the process makes is recorded with its model, provider, token split, latency, cost and error status, attributed to support-agent.

Without touching the code#

bash
CLAWMETRY_TRACK=1 CLAWMETRY_SOURCE=billing-agent python my_agent.py

CLAWMETRY_TRACK=1 activates on import of the clawmetry package; CLAWMETRY_INTERCEPT=1 activates it when ClawMetry itself starts. Either works; the environment form is the one to use in a container where you would rather not patch an image to add an import.

What gets intercepted#

The interceptor patches httpx.Client.send and requests.Session.send — the transport both major Python SDK families use underneath — and matches on the request host:

ProviderHost
Anthropicapi.anthropic.com
OpenAIapi.openai.com
Googlegenerativelanguage.googleapis.com
OpenRouteropenrouter.ai

Non-LLM outbound calls are captured separately as external calls, which is how the dashboard can show you that your agent spent nine seconds waiting on a third-party API rather than on a model. Loopback and internal hosts are excluded by default, and CLAWMETRY_INTERCEPT_HOSTS_EXCLUDE takes a comma-separated list of additional substrings to skip.

If neither httpx nor requests is installed, the interceptor silently no-ops. It never raises into the host application — an observability tool that can crash the thing it observes is worse than no observability tool.

Naming sources#

set_source() is what makes this useful at more than one agent. Each named source becomes its own first-class line in the dashboard's out-loop sources card, with calls, providers, latency and error rate per agent.

python
import clawmetry.track

clawmetry.track.set_source("support-agent")
# ... later, from anywhere in the process:
stats = clawmetry.track.get_stats()   # {"calls": …, "input_tokens": …, "cost_usd": …}

Set it once, early. A process that never names itself still gets captured; it just lands under a default source, and telling three unlabelled agents apart afterwards is not fun.

Where it writes#

The interceptor appends JSONL to the workspace, and the daemon ingests it on its normal cycle — the same DuckDB store, the same rollups, the same end-to-end-encrypted cloud snapshot as every on-disk runtime. There is no separate pipeline to operate.

Turning it off#

VariableEffect
CLAWMETRY_NO_INTERCEPT=1Opt out even when clawmetry.track is explicitly imported
CLAWMETRY_INTERCEPT=0Do not auto-activate at ClawMetry startup

When to use the ingest API instead#

The interceptor sees LLM calls. If you want to record agent structure — runs, steps, tool invocations, a session boundary — push those explicitly:

python
# a run with structure, rather than a stream of model calls
POST /api/v1/runs
POST /api/v1/runs/<id>/events
POST /api/v1/runs/<id>/end

Custom runtime ingest

Nothing stops you doing both: the interceptor for cost truth, the ingest API for the shape of the run.

Overhead#

The patch adds a small amount of work per request — reading the response's usage block and appending a line. Measure it against your own workload rather than a tight loop of no-op calls, which is not a realistic shape and will make the relative overhead look far worse than it is in a real agent that spends most of its wall clock waiting on a model.

Cookie preferences