Drop-in runtime capture for AI agents. Two lines to install. Logs every LLM call (Anthropic, OpenAI, Google Gemini, Cohere, Mistral) to local JSONL. MIT.
Reason this release was yanked:
Deprecated
Project description
tessen
Drop-in runtime capture for AI agents. Two lines to install. Every LLM call your agent makes — full request, full response with thinking decoded, cache-token usage, call site, timing — written as JSONL to local disk.
import tessen
tessen.init(agent_name="my_agent")
That's the entire integration. Drop it before you construct your LLM client. Every call from every supported SDK is intercepted.
Install
pip install tessen
# or, if you want the optional log viewer
pip install "tessen[viewer]"
The core install has zero hard dependencies. Tessen only patches vendor SDKs that are already importable in your process — install whichever you actually use.
What gets captured
| SDK | what's intercepted |
|---|---|
Anthropic (anthropic) |
messages.create, messages.stream, async equivalents, batches API, and stream=True iterator returns (tee'd transparently) |
OpenAI (openai) |
chat.completions.create, responses.create, legacy completions.create, sync + async |
| Google Gemini | both google.generativeai (legacy) and google.genai (current), sync + async, streaming |
Cohere (cohere) |
chat, chat_stream, async |
Mistral (mistralai) |
chat.complete, chat.stream, async |
Streaming responses (both messages.stream(...) context managers and messages.create(..., stream=True) iterators) are tee'd transparently — your code does not change. The captured event records the assembled final message and chunk count.
What an event looks like
{
"event_id": "...",
"agent_name": "my_agent",
"ts": 1715630400.123,
"provider": "anthropic",
"surface": "create",
"duration_ms": 842.1,
"request": { "model": "claude-...", "system": "...", "messages": [...], "tools": [...] },
"response": { "content": [ {"type": "thinking", ...}, {"type": "tool_use", ...} ],
"stop_reason": "tool_use",
"usage": { "input_tokens": 512, "output_tokens": 128,
"cache_read_input_tokens": 256,
"cache_creation_input_tokens": 64 } },
"call_site": { "file": "/path/to/your/agent.py", "line": 84, "func": "step" },
"status": "ok"
}
Why
You cannot debug an agent you cannot see. Most observability tools capture the model call as a span on a metrics pipeline. Tessen captures the call as a forensic record — thinking deltas, tool blocks, stop reasons, cache hits, retries — at the depth needed to actually investigate why an agent failed.
- request: model, system, full
messages, fulltoolsschema,max_tokens,thinkingconfig, sampling params - response: every content block (
text,thinking,tool_use,tool_result),stop_reason,stop_sequence, messageid, model returned - usage:
input_tokens,output_tokens,cache_read_input_tokens,cache_creation_input_tokens— so you can see what the model actually paid for - call_site: file path + line number + function name of the caller, with
/tessen/and vendor-SDK frames skipped so you land on your code - timing:
duration_mswall-clock - errors: exception type, message, and full traceback if the call raised
- streaming:
streamed: true+chunks_captured+ assembled final message
Where logs live
~/.tessen/logs/{agent_name}/{YYYY-MM-DD}.jsonl. Override with tessen.init(log_dir=...). Files rotate at 100 MB.
python -m tessen.viewer ~/.tessen/logs/my_agent/2026-05-13.jsonl
Overhead
The wrapper is a thin function call around the original SDK method. The write goes through a thread-locked append + fsync(). Real-world overhead is well under 1 ms per call.
Frameworks
Tessen patches at the resource-class level (anthropic.resources.messages.Messages.create, etc.), so framework wrappers — LangChain ChatAnthropic, LangGraph nodes, deepagents, OpenAI Agents SDK with an Anthropic adapter — all flow through Tessen automatically.
Privacy
The SDK runs in your process. There is no network call from Tessen. You bring your own API keys; we never see them. Your code, your data, your machine.
License
MIT. Vendor it, ship it, modify it.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tessen-0.1.0.tar.gz.
File metadata
- Download URL: tessen-0.1.0.tar.gz
- Upload date:
- Size: 20.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4f0ec354c32a7922a38dcd7c69dcf3df4a345f8afb077d2773bb1ac5abc6825
|
|
| MD5 |
7f0c8f3ac3ce8dd6b4dd4de8789cf19e
|
|
| BLAKE2b-256 |
9cc510d724d590119d9a8c9f62ca9d3b065aab5d2705e26c9a7c3ba5110effc2
|
File details
Details for the file tessen-0.1.0-py3-none-any.whl.
File metadata
- Download URL: tessen-0.1.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3305d8dda4818cfc1136db1cc505cef95e10a600a41ebaf9a654484256d9ec0e
|
|
| MD5 |
1b586a5e63b9a0b8888656a8ea67f661
|
|
| BLAKE2b-256 |
ee0f7b1a02787896850c7efd397165a72c9a6dd5ee90d2dae1d1e5e709918dd4
|