Skip to main content
The agent-feedback Python package is a dependency-free middleware that works with any ASGI or WSGI framework. A single constructor call wraps your existing application object, and Agent Feedback instruments eligible responses without touching your handlers, adding third-party packages, or blocking the product response path.

Installation

1

Install the package

2

Create a product key

Open the Agent Feedback dashboard, create a product, and copy the API key. Store it as AGENT_FEEDBACK_KEY in your environment — never hard-code it.
agent-feedback has no third-party runtime dependencies. It uses only the Python standard library (urllib.request, threading, hmac, hashlib, and queue).

ASGI middleware

Wrap your ASGI application with AgentFeedbackASGI. This works with FastAPI, Starlette, Quart, Django (ASGI mode), and any other framework that exposes a standard ASGI callable. JSON object responses gain an _agentFeedback field, and HTML responses receive an injected <script id="agent-feedback"> tag.

With customer context


WSGI middleware

Wrap your WSGI application’s wsgi_app attribute with AgentFeedbackWSGI. This works with Flask, Django (WSGI mode), Bottle, Pyramid, and any other WSGI framework.

ASGI vs WSGI: what gets instrumented

The two middleware classes use different strategies based on what each protocol allows. Both middleware classes read the response body for application/json and text/html responses and inject the feedback contract directly. WSGI instrumentation is limited to finite responses that declare a Content-Length — streaming and chunked responses are forwarded without modification. Both add Cache-Control: private, no-store to instrumented responses.
The WSGI adapter cannot inject feedback into streaming or chunked responses. If your product streams data, consider switching to ASGI or using the feedback_from_response agent helper on the client side.

Configuration options

Both AgentFeedbackASGI and AgentFeedbackWSGI accept the same options after app. All fields except api_key are optional.
str
required
Your Agent Feedback product key. Must match the pattern af_live_<keyId>_<secret>. Store this in an environment variable.
tuple[str, ...]
default:"()"
Glob-style path patterns that opt routes in. When empty, all routes are instrumented (subject to exclude). Supports * (any path segment) and ** (any path). Example: ("/search", "/docs/*").
tuple[str, ...]
default:"()"
Glob-style patterns to skip. The default exclusion list (/health, /healthz, /metrics, /favicon.ico, /robots.txt, /_agent-feedback/*, /api/v2/outcomes) is always applied. Patterns you add here extend that list.
Callable[[Any], str | None] | None
Callback that receives the ASGI scope object (or WSGI environ) and returns an opaque customer identifier. Used for grouping interactions by account in the dashboard.
Callable[[Any], str | None] | None
Callback that returns a session identifier. Links a sequence of interactions for session-level analytics.
"auto" | "ask" | "off"
default:"\"auto\""
Controls the instruction sent to agents inside the feedback envelope.
  • "auto" — instructs the agent to submit a review autonomously.
  • "ask" — instructs the agent to submit only when the outcome is clear.
  • "off" — disables instrumentation entirely.
Callable[[Any], str | None] | None
Callback that receives the ASGI scope object (or WSGI environ) and returns a hint about the agent runtime making the request (e.g. "claude", "gpt-4o"). Used for runtime-level breakdown in the dashboard.
float
default:"0.5"
How often the background thread flushes telemetry events, in seconds. The queue also flushes when it reaches 50 events.
int
default:"1000"
Maximum number of telemetry events held in memory. When the queue is full, the oldest event is dropped to make room for the newest.

Agent helper functions

Import feedback_from_response and submit_product_outcome from agent_feedback to build a feedback-aware agent runtime that submits outcomes deterministically.

feedback_from_response

Extracts the FeedbackEnvelope dictionary from a response. Checks the parsed body first (JSON _agentFeedback field or HTML <script id="agent-feedback"> tag), then falls back to the Agent-Feedback response header.

submit_product_outcome

Submits a compact outcome review to the URL embedded in the envelope. Validates the envelope, enforces the allowed-origin allow-list, and raises ValueError on invalid input.
Pass allowed_submit_origins=("https://your-staging-endpoint.example.com",) when testing against a non-production Agent Feedback instance. By default only the hosted service is trusted.