Open-source observability SDK for AI agents — zero-instrumentation capture, OpenTelemetry-native
Project description
wardex-sdk
Open-source observability SDK for AI agents — zero-instrumentation capture, OpenTelemetry-native.
⚠️ Beta. PII masking is on by default (see below), but the SDK is still early: review the caveats below before sending sensitive data through it.
Install
pip install wardex-sdk
Quickstart
import wardex_sdk as wardex
from wardex_sdk import OtlpHttpTransport
wardex.init(
transport=OtlpHttpTransport(endpoint="https://<your-collector>/v1/traces"),
intercept=True, # zero-instrumentation capture of LLM calls
)
# your app code — OpenAI/Anthropic calls are captured automatically
wardex.close() # optional — spans auto-flush every 5s, on buffer threshold, and at exit
Status
Works today
- Zero-instrumentation capture of LLM HTTP calls (OpenAI, Anthropic) over
https, cleartexthttp, and h2c gen_aisemantics: model, tokens, parameters, finish reasons, input/output messages- Transport metrics (TCP/TLS timing, TTFT), gRPC (grpclib), WebSocket (
wss), MCP stdio - Export to any OpenTelemetry backend via
OtlpHttpTransport - Manual span decorators:
@workflow/@agent/@task/@tool/@span - PII masking on by default: emails, phone numbers, credit cards (Luhn-verified),
US SSNs, IP addresses, bank routing numbers, IBANs, and API-key/token secrets
are masked before anything leaves the process (
pii_mode=PIIMode.OFFto disable,pii_disabled_categories={PIICategory.IP_ADDRESS}for per-category opt-out) - Background batching: automatic flush every 5s / on buffer threshold /
at exit and on SIGINT/SIGTERM (chained; opt out with
flush_on_signals=False)
Not yet (see Roadmap)
- Framework adapters (LangGraph, Anthropic/OpenAI Agent SDKs)
- Node/TS and Java SDKs
Notes
- After
os.fork()the worker respawns lazily in the child on first capture; spans buffered before the fork may be sent by both processes (duplicates are possible; a fork landing mid-export can also strand the child's pre-fork buffer — re-init in the child for a clean slate). Under uWSGI enable threads (--enable-threads).
Distributed tracing
Trace context propagation is opt-in — a plain wardex.init(...) never
touches your outbound requests or headers. Turn it on with:
wardex.init(
transport=OtlpHttpTransport(endpoint="https://<your-collector>/v1/traces"),
intercept=True,
propagate_trace=True, # inject W3C headers on outbound calls
propagate_targets=["api.internal.example.com", "*.svc.cluster.local"], # optional glob allowlist; default None = all hosts
)
With propagate_trace=True, outbound calls made through httpx (sync + async),
requests, or aiohttp get a traceparent (and tracestate, if one was
received) header attached automatically, as long as an active trace context
exists and the request doesn't already carry a traceparent. If
propagate_targets is left unset, the trace ID is sent to every host you
call — including third-party LLM providers. Set it to an allowlist of glob
patterns to scope injection to your own services.
Joining an inbound trace
Drop the middleware in front of your app to join whatever trace the caller started:
# ASGI (FastAPI, Starlette, Django ASGI)
app.add_middleware(wardex.WardexMiddleware)
# WSGI (Flask, Django WSGI)
app.wsgi_app = wardex.WardexWSGIMiddleware(app.wsgi_app)
Both extract the incoming traceparent/tracestate and continue the trace
for the lifetime of the request; a missing or malformed header just starts a
fresh trace (never raises). One WSGI caveat: the joined context covers the
app callable only, so streaming responses (work done while iterating the
returned iterable) run outside it.
Manual propagation (the universal escape hatch)
The baton is just a string, so it travels over any channel that can carry
one — not just HTTP. get_traceparent() and get_trace_headers() are plain
functions that return the current trace headers; continue_trace(headers)
is a context manager — the remote parent is only installed inside the
with block, so it must be entered, not merely called. Use them directly
wherever the automatic client patches or ASGI/WSGI middleware don't reach:
# gRPC metadata
stub.Check(req, metadata=[("traceparent", wardex.get_traceparent())])
# WebSocket handshake
websockets.connect(uri, extra_headers=wardex.get_trace_headers())
# Celery: put get_trace_headers() on the task's headers when sending it,
# then inside the worker:
with wardex.continue_trace(task.request.headers):
... # task body
# Kafka: put get_trace_headers() on the message headers when producing,
# then inside the consumer:
with wardex.continue_trace(dict(msg.headers())):
... # process the message
with wardex.continue_from_otel(): is a one-line alternative to
continue_trace() for code that already runs under an active OpenTelemetry
span — it adopts that span as the remote parent for the duration of the
with block (no-op if opentelemetry isn't installed or there's no active
span). Like continue_trace(), it is a context manager and must be entered
with with.
Propagating into threads
asyncio tasks inherit the current trace context automatically; threads do
not. Wrap the target with wardex.run_in_context() at the point where you
still have the right context:
thread = threading.Thread(target=wardex.run_in_context(worker_fn), args=(...,))
thread.start()
capture_mode: what gets captured without an active span
capture_mode defaults to "agent": LLM-semantic traffic (recognized
gen_ai calls, MCP stdio) is always captured, but generic HTTP/gRPC/WS
traffic is only captured while it happens inside an active local wardex
span (a traceparent received from an upstream caller doesn't count on its
own — this keeps a service mesh stamping every request with a traceparent
from reviving the pre-Phase-4 "capture everything" noise).
This means a bare, unwrapped call to an LLM provider wardex doesn't
recognize (or a WS-based provider such as OpenAI Realtime, which carries no
parseable semantics) can be silently dropped if it isn't inside a local
span. Wrap it with @wardex.workflow (or any of the span decorators), or set
capture_mode=wardex.CaptureMode.ALL to restore the previous
capture-everything behavior:
wardex.init(..., capture_mode=wardex.CaptureMode.ALL)
Plaintext hosts you've explicitly named via intercept_hosts are always
captured regardless of capture_mode — a targeted allowlist entry is a
stronger opt-in than the default policy.
Roadmap
PII masking (pre-send safety)— shippedBatching & lifecycle (background worker, at-exit/periodic flush, concurrency)— shippedDistributed propagation (W3C)— shipped- Framework adapters
- Node/TS and Java SDKs
PII masking caveats:
before_sendsees pre-masking data (masking runs inside the encoder), the Console transport prints raw (local debugging only), and non-UTF-8 binary payloads pass through unmasked.
License
Apache-2.0. See LICENSE and NOTICE.
"Wardex" is a trademark of Wardex Labs.
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 Distributions
Built Distributions
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 wardex_sdk-0.1.0b5-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: wardex_sdk-0.1.0b5-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.4 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
375c196a7dfc0761280551f98bcd7c8871adda7331f876b81528dcbbb42eca7a
|
|
| MD5 |
7df510ab88ddd5c772503e643e1a91da
|
|
| BLAKE2b-256 |
d88ed57ed90a950972d4c455da8098aaf2a6601a146a8a4af1ed3b30386181fe
|
Provenance
The following attestation bundles were made for wardex_sdk-0.1.0b5-cp310-abi3-win_amd64.whl:
Publisher:
release-python.yml on wardex-labs/wardex-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wardex_sdk-0.1.0b5-cp310-abi3-win_amd64.whl -
Subject digest:
375c196a7dfc0761280551f98bcd7c8871adda7331f876b81528dcbbb42eca7a - Sigstore transparency entry: 2116125046
- Sigstore integration time:
-
Permalink:
wardex-labs/wardex-sdk@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Branch / Tag:
refs/tags/python-v0.1.0b5 - Owner: https://github.com/wardex-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.9 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c13bc067066b482dcec1a0854e277ec3b063e81ec806feed1df2123a2baeb600
|
|
| MD5 |
dd0fa71fa1ba44644a12a85bd5235cdc
|
|
| BLAKE2b-256 |
754d9917e7a6a2b6b2375d3459d03e08579d1966256ccb35747b5ca0c830f973
|
Provenance
The following attestation bundles were made for wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release-python.yml on wardex-labs/wardex-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
c13bc067066b482dcec1a0854e277ec3b063e81ec806feed1df2123a2baeb600 - Sigstore transparency entry: 2116124979
- Sigstore integration time:
-
Permalink:
wardex-labs/wardex-sdk@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Branch / Tag:
refs/tags/python-v0.1.0b5 - Owner: https://github.com/wardex-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.8 MB
- Tags: CPython 3.10+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2811cefb66614140370f0bff252ecbf5be60ac09c4ceba5cf783b08448d4e2be
|
|
| MD5 |
b041f3ab24b7c23aa0a78b33258a5f03
|
|
| BLAKE2b-256 |
0bce0dc461af343d6b384f9701067a241062c03a21b4320c9580c2b21771c1e6
|
Provenance
The following attestation bundles were made for wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release-python.yml on wardex-labs/wardex-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wardex_sdk-0.1.0b5-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
2811cefb66614140370f0bff252ecbf5be60ac09c4ceba5cf783b08448d4e2be - Sigstore transparency entry: 2116125142
- Sigstore integration time:
-
Permalink:
wardex-labs/wardex-sdk@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Branch / Tag:
refs/tags/python-v0.1.0b5 - Owner: https://github.com/wardex-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wardex_sdk-0.1.0b5-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: wardex_sdk-0.1.0b5-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.6 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7333dfd796cd9e6ae4bcd5f476bffb419f2003428bfbe2003d3baed821829d9
|
|
| MD5 |
36726f71f70e50e6f6f3290774078bbe
|
|
| BLAKE2b-256 |
37b1ce37b48cdb8d1da275025f3c938877de2e5976765d6ac35f7d25ccf9c693
|
Provenance
The following attestation bundles were made for wardex_sdk-0.1.0b5-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release-python.yml on wardex-labs/wardex-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wardex_sdk-0.1.0b5-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
a7333dfd796cd9e6ae4bcd5f476bffb419f2003428bfbe2003d3baed821829d9 - Sigstore transparency entry: 2116124907
- Sigstore integration time:
-
Permalink:
wardex-labs/wardex-sdk@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Branch / Tag:
refs/tags/python-v0.1.0b5 - Owner: https://github.com/wardex-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file wardex_sdk-0.1.0b5-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: wardex_sdk-0.1.0b5-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.7 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ab777bd4480f3ff102666aa93cdbf30c6ba19da0ba5d3a58cc629b498d2a9c4
|
|
| MD5 |
d46136674e7a956bac5f67b1b6ecf1df
|
|
| BLAKE2b-256 |
2bd6969d042ee90065e0815628ffb1bf71d028ef43676c0b510dcd180c9f4797
|
Provenance
The following attestation bundles were made for wardex_sdk-0.1.0b5-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
release-python.yml on wardex-labs/wardex-sdk
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
wardex_sdk-0.1.0b5-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
0ab777bd4480f3ff102666aa93cdbf30c6ba19da0ba5d3a58cc629b498d2a9c4 - Sigstore transparency entry: 2116125202
- Sigstore integration time:
-
Permalink:
wardex-labs/wardex-sdk@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Branch / Tag:
refs/tags/python-v0.1.0b5 - Owner: https://github.com/wardex-labs
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-python.yml@b9618709cbbf9b9aaf2c0a245ddf2ae6b06ad1e4 -
Trigger Event:
push
-
Statement type: