Copy this into your coding agent
Paste into Cursor, Codex, Claude Code, or another coding agent in your project.Beta release. All four languages support tracing, real app tests and scripted simulations.
Install
Package on PyPI · Source and examplesRecord one interaction
Choose Python on the SDK setup page and copy the coding-agent prompt. Bench fills in your account setup key automatically. Python 3.10 or later is required.Wrap your application
Usewith bench.trace(...) around a Deep Agents, LangGraph, LangChain or custom
application call. It also works around await agent.ainvoke(...). Wrap tools
inside the same request with kind="TOOL"; nested async tasks inherit their
parent trace. Keep streaming spans open until the stream finishes.
Inputs and outputs are omitted by default. With content capture enabled, pass
input=... and call span.set_output(result). Built-in filtering runs before
delivery. Add a redact(value) callback for your application’s extra fields.
See privacy and redaction.
Call bench.flush() at request boundaries, or await bench.aflush() in async
code. Call shutdown() after active requests finish. Delivery retries once;
bench.stats shows queued and dropped spans. A delivery failure does not change
your application’s result or exception.
Set component_id to a real prompt component from Bench to connect the event to
its saved criteria. Production checks require recorded
content and a key with evaluation allowance.
Automatic framework adapters are coming soon. Use explicit wrappers with your current framework.
Test your application
await bench.evaluate_system(...) calls your application’s request handler with
pinned cases. It captures the real nested tool/model traces, compares the final
output and independently observed state, and returns a redacted report locally.
Use a test database and test service credentials.
run(input, context) and observe(context) may be synchronous or asynchronous.
When a case has expected_state, supply observe to read the authoritative test
state. Context provides case_id, cancelled, signal, deadline and
raise_if_cancelled(). Inputs are JSON snapshots; changes inside the application
do not change the case’s assertions.
await bench.simulate_system(...) accepts the same revisions and cases, plus
create_session(initial_state, context). Cases use
input={"initial_state": {...}, "turns": [...]} and require expected_state.
Return an object with turn(message, context), observe() and close() methods.
A fresh session receives 1 to 20 scripted customer turns. Bench snapshots observed
state before closing the session. context.turn_index identifies the turn.
Both helpers use a 30-second timeout per case, configurable with timeout up to
300 seconds. Pass a threading.Event as cancel_event to stop the suite. Missing
assertions, missing state, unfinished traces and timeouts remain incomplete.
Callbacks must honor cancellation; Python cannot forcibly stop a synchronous
thread. Await all child work and isolate external side effects. These helpers
are local execution, not a process sandbox or a hosted verification claim.
Tests record redacted content even when production capture is metadata-only, so
use synthetic inputs. Reports are not uploaded and paid checks are not started
unless you take a separate explicit action. Automatic framework adapters are
coming soon.
Run the complete refund simulation example. It sends two refund requests, checks the number of refunds written, and demonstrates the failing implementation and its fix.

