Zero-config observability for AI agents
Project description
peekr
Zero-config observability for AI agents. Auto-instruments OpenAI and Anthropic SDKs — no code changes needed.
pip install peekr
Quickstart
import peekr
peekr.instrument()
# Your existing agent code — zero changes
import openai
openai.chat.completions.create(model="gpt-4o", messages=[...])
Every LLM call is automatically captured. View your traces:
peekr view traces.jsonl
Trace a3f2b1c0 1243ms 891tok
────────────────────────────────────────────────
agent.run 1243ms
└─ openai.chat.completions [gpt-4o] 821ms 312tok
└─ tool.search_web 12ms
└─ openai.chat.completions [gpt-4o] 410ms 579tok
Installation
# Base (no LLM SDK required)
pip install peekr
# With OpenAI
pip install "peekr[openai]"
# With Anthropic
pip install "peekr[anthropic]"
# Both
pip install "peekr[all]"
Usage
Auto-instrument LLM SDKs
import peekr
peekr.instrument()
# That's it. All OpenAI and Anthropic calls are now traced.
Options:
peekr.instrument(
console=True, # print spans as they happen (default: True)
jsonl_path="traces.jsonl", # write to file (default: traces.jsonl)
jsonl_path=None, # disable file output
)
Trace your own functions
from peekr import trace
@trace
def search_web(query: str) -> list[str]:
...
@trace(name="tool.calculator")
def calculate(expression: str) -> float:
...
# Async works too
@trace
async def fetch_data(url: str) -> dict:
...
Decorated functions automatically become child spans of whatever called them.
Capture or hide inputs/outputs
@trace # captures args and return value by default
def search_web(query): ...
@trace(capture_io=False) # opt out for sensitive data
def get_api_key(): ...
Manual spans
For cases where a decorator doesn't fit:
from peekr import start_span, end_span
span, token = start_span("my.operation")
span.attributes["custom_key"] = "custom_value"
try:
do_work()
span.status = "ok"
except Exception as e:
span.status = "error"
span.attributes["error"] = str(e)
raise
finally:
end_span(span, token)
Viewing traces
# Basic tree view
peekr view traces.jsonl
# Show inputs and outputs
peekr view --io traces.jsonl
What gets captured
| Field | Description |
|---|---|
name |
Span name (function name or custom) |
duration_ms |
Wall-clock time |
status |
ok or error |
model |
LLM model name (auto) |
tokens_input |
Prompt tokens (auto) |
tokens_output |
Completion tokens (auto) |
tokens_total |
Total tokens (auto) |
input |
Serialized function args (truncated) |
output |
Serialized return value (truncated) |
error |
Exception message if status is error |
Custom exporters
from peekr.exporters import add_exporter
class MyExporter:
def export(self, span):
# send to your backend
requests.post("https://my-backend.com/spans", json=span.to_dict())
peekr.instrument()
add_exporter(MyExporter())
How it works
instrument() monkey-patches the OpenAI and Anthropic SDK methods before your code runs. Python looks up function references at call time, so every subsequent call hits the wrapper instead of the original — with zero changes to your code.
Span context (parent/child relationships) is tracked via Python's contextvars.ContextVar, which propagates correctly across async/await without any manual passing.
Contributing
git clone https://github.com/ashwanijha04/peekr
cd peekr
pip install -e ".[dev]"
pytest
PRs welcome. Open an issue first for large changes.
License
MIT
Project details
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 peekr-0.1.0.tar.gz.
File metadata
- Download URL: peekr-0.1.0.tar.gz
- Upload date:
- Size: 10.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbd70608c88627bd03b1971b5748bd8bc3c1ddb1e3bf1c84d03efb38825261e6
|
|
| MD5 |
4cf07a34ac4431be2d4b95ac81ef4df2
|
|
| BLAKE2b-256 |
dd6039b7a1243c3b4a00e66c36b3741daec5a8ecf1ca50ee47b70725153f7e44
|
Provenance
The following attestation bundles were made for peekr-0.1.0.tar.gz:
Publisher:
publish.yml on ashwanijha04/peekr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peekr-0.1.0.tar.gz -
Subject digest:
cbd70608c88627bd03b1971b5748bd8bc3c1ddb1e3bf1c84d03efb38825261e6 - Sigstore transparency entry: 1486588519
- Sigstore integration time:
-
Permalink:
ashwanijha04/peekr@09cf418965361baff8cd8a3f23f6c81e9466ce1d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ashwanijha04
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@09cf418965361baff8cd8a3f23f6c81e9466ce1d -
Trigger Event:
push
-
Statement type:
File details
Details for the file peekr-0.1.0-py3-none-any.whl.
File metadata
- Download URL: peekr-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
882f43e6e25fb1042167638859d5491e3ba5b12baf99df100d0b4ca324cef018
|
|
| MD5 |
4ecb9cc04b49a56bb2c24e96349a2fb1
|
|
| BLAKE2b-256 |
a99a685840d74fdfc91c13e5668110594adffbb94cbc561ea76d57d088a5273a
|
Provenance
The following attestation bundles were made for peekr-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on ashwanijha04/peekr
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
peekr-0.1.0-py3-none-any.whl -
Subject digest:
882f43e6e25fb1042167638859d5491e3ba5b12baf99df100d0b4ca324cef018 - Sigstore transparency entry: 1486588600
- Sigstore integration time:
-
Permalink:
ashwanijha04/peekr@09cf418965361baff8cd8a3f23f6c81e9466ce1d -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/ashwanijha04
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@09cf418965361baff8cd8a3f23f6c81e9466ce1d -
Trigger Event:
push
-
Statement type: