modelmri-record
Record what your agent actually did — LLM calls, tool calls, subagents, retrieval, errors — and look at it on a timeline instead of scrolling logs.
pip install modelmri-record
Stdlib only. No torch, no numpy, no SDK pins. Instrumenting an agent shouldn't cost you a 2.5 GB install.
Use
from modelmri_record import trace, step
with trace("fix-failing-tests"):
step("llm_call", name="plan", input=prompt, output=answer,
duration_ms=1200, tokens_in=900, tokens_out=200)
with step("subagent", name="test-runner"):
step("tool_call", name="pytest", input="-q", output="3 failed")
Nesting is automatic — a step used as a context manager becomes the parent of
everything recorded inside it, and its duration is measured for you.
The kinds
The first argument is the kind, and it is a closed list — a viewer refuses a
whole document containing a kind it does not know, so this is the one argument
worth checking against the page. modelmri_record.KINDS is the same list at
runtime.
| kind | what it is |
|---|---|
llm_call |
a call to a model |
tool_call |
a tool, a shell command, a function |
subagent |
a nested agent; use it as a context manager and everything inside becomes its children |
mcp_call |
a tool reached over MCP, kept apart from tool_call because the transport is the thing that fails |
user_turn |
a person said something |
error |
a failure worth its own step; also synthesised for you when an exception escapes the trace() block |
retrieval |
fetching candidate documents — a vector store, a search index, a grep |
embedding |
text to vector |
rerank |
reordering candidates against the query |
guardrail |
a policy check on the way in or out — not error, since a guardrail that fires did its job |
A kind this recorder does not recognise is still recorded, and it prints one line saying so. It does not raise, and it does not drop the step: your agent must not fall over because a step was named wrong, and a run you cannot see is still a run worth keeping.
Auto-instrument an SDK instead:
from modelmri_record import instrument_anthropic
instrument_anthropic() # every Messages.create is now an llm_call step
Where traces go
POSTed to a running ModelMRI viewer on http://127.0.0.1:5900. If nothing is
listening, they're written to ./modelmri-traces/*.json to import later — so
you can record on a box that has no viewer and look at it somewhere else.
To view them: pip install modelmri && modelmri serve.
Credentials are redacted by default
Agent prompts routinely contain the key the agent was handed. A recorder that writes those to disk verbatim is a liability dressed as an observability feature, so redaction is on unless you switch it off:
with trace("run"): # default scrubber
with trace("run", redact=my_function) # your own str -> str
with trace("run", redact=False) # verbatim, deliberately
Covered: sk-…, hf_…, pypi-…, ghp_…/github_pat_…, xoxb-…, Google
AIza…, AWS key ids, Bearer …, and whole PEM private-key blocks.
Patterns are deliberately narrow — known credential shapes, not "anything high-entropy". A redactor that eats hashes and UUIDs makes traces useless, and a useless trace gets the feature turned off, which protects nobody. Add your own shapes:
from modelmri_record.redact import make_redactor
red = make_redactor([r"ACME-[0-9]{6}"])
It will not take down your app
Recording is best-effort by contract. If the viewer is unreachable, the disk is read-only, or the payload won't serialise, it gives up quietly. A tracing library that can raise is one nobody leaves switched on.
Quietly is not the same as secretly. A viewer that answers and refuses the document — an unknown step kind, a malformed field, a version older than the recorder that wrote the run — is a different thing from one that was never running, and that one prints the refusal in the viewer's own words before the run goes to disk.
Traces still open when the process exits are flushed by an atexit hook —
a crash or a SIGTERM is exactly the run you most wanted to look at.
Licence
Apache-2.0. Part of ModelMRI, whose application is AGPL-3.0-only; this package is Apache-2.0 on purpose, so that instrumenting your agent carries no copyleft.
Metadata
Release files for modelmri-record 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| modelmri_record-0.2.0.tar.gz | 36.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| modelmri_record-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.3 kB
Release files / modelmri_record-0.2.0.tar.gz
| Download URL | modelmri_record-0.2.0.tar.gz |
|---|---|
| Size | 36.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9dbf9830c65ea75a866dd08ec9a2e977837fc0230db39e60bdcd0d521df70267
|
|
BLAKE2b-256 checksum How to use checksums |
801162fc17ebed0dd9d77e3353d55218cc44aa276580895107a3dff8087f337e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / modelmri_record-0.2.0-py3-none-any.whl
| Download URL | modelmri_record-0.2.0-py3-none-any.whl |
|---|---|
| Size | 31.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
73fd8763eb2091b4d5d2842f8cd5eba6fed2ee769689085407b9775ea9623210
|
|
BLAKE2b-256 checksum How to use checksums |
f5cf14f13ebfe09e49157cdac017fc0b1dc1e1ba18d040050c79516eaa7567ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.0 {"installer":{"name":"uv","version":"0.10.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|