Skip to main content

Wire-level prompt introspection for LLM SDK calls. See exactly what was sent, with credentials redacted by default. Anthropic, OpenAI, any httpx-based client.

Project description

agenttap

Wire-level prompt introspection for LLM SDK calls. See exactly what was sent. Credentials redacted by default. Works with any httpx-based SDK (Anthropic, OpenAI, etc).

pip install agenttap

Why

Five years into the SDK era, "what was actually sent to the model?" remains a hard question. SDK debug logging is verbose, leaks API keys, and reformats payloads. Callbacks scatter across vendor-specific abstractions. agenttap taps the wire at the httpx transport layer so you see the exact request body the provider received — with Authorization, x-api-key, and known key patterns scrubbed automatically.

Quick start

Anthropic

import httpx
import anthropic
from agenttap import Tap

tap = Tap()
client = anthropic.Anthropic(http_client=httpx.Client(transport=tap.transport()))

client.messages.create(
    model="claude-sonnet-4-20250514",
    max_tokens=200,
    messages=[{"role": "user", "content": "Hello"}],
)

print(tap.last.url)                  # https://api.anthropic.com/v1/messages
print(tap.last.pretty_request())     # exact JSON sent
print(tap.last.response_status)      # 200

OpenAI

import httpx
import openai
from agenttap import Tap

tap = Tap()
client = openai.OpenAI(http_client=httpx.Client(transport=tap.transport()))

client.chat.completions.create(
    model="gpt-4o", messages=[{"role": "user", "content": "Hi"}]
)

print(tap.last.request_body)

Diff two requests

from agenttap import diff

# After two calls
print(diff(tap.all[0], tap.all[1]))
# - "system": "v1: be helpful"
# + "system": "v2: be concise"

What's redacted by default

  • Headers: Authorization, x-api-key, api-key, cookie, anthropic-api-key, openai-organization, x-amz-security-token, x-google-api-key
  • Body string values matching: OpenAI/Anthropic sk-…, AWS AKIA…, Google AIza…, Slack xox[baprs]-…

Override with a custom Redactor:

from agenttap import Tap, Redactor

tap = Tap(redactor=Redactor.none())   # no scrubbing
tap = Tap(redactor=Redactor(placeholder="<hidden>"))

API

Tap(redactor=None, history_size=1000)

tap.transport(parent=None)         # for httpx.Client(transport=...)
tap.async_transport(parent=None)   # for httpx.AsyncClient(transport=...)

tap.last                           # most recent TappedCall
tap.all                            # list[TappedCall]
tap.reset()
with tap.session() as sub: ...     # scoped sub-tap, results merged on exit

TappedCall.method, .url
TappedCall.request_headers, .request_body
TappedCall.response_status, .response_headers, .response_body
TappedCall.elapsed_ms
TappedCall.pretty_request()

diff(a, b)                         # unified diff of request bodies

What it doesn't do

  • Not a proxy. Not a server. No UI. No persistence (write tap.all to JSON yourself).
  • Not full observability — for traces, ship the recorded calls into Phoenix/Langfuse/OTel.
  • Doesn't normalize across providers. The whole point is to show what each provider actually received.

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

agenttap-0.1.0.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agenttap-0.1.0-py3-none-any.whl (6.4 kB view details)

Uploaded Python 3

File details

Details for the file agenttap-0.1.0.tar.gz.

File metadata

  • Download URL: agenttap-0.1.0.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for agenttap-0.1.0.tar.gz
Algorithm Hash digest
SHA256 29dfc88b4a7096a0362bd7330542634ea959236fe071c2edb88de037a3b1bf1a
MD5 e38b9491e574d8cbd3fa43189681a0f3
BLAKE2b-256 8d8cba15b8080b26b42d0687f2f67c51ffa95582487f66f0c960615608948153

See more details on using hashes here.

File details

Details for the file agenttap-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: agenttap-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for agenttap-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 afc5ada524394d8f21946e13fdee0c790b69b2c52ab865b4f79367d262c7433c
MD5 3c97a7204b8ed3cf4736e32e36811152
BLAKE2b-256 a92e153797a5efc12270972035664337a56e99b1ee581187f6cf1dcd344f4f90

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page