http.Handler with a single function call. It instruments finite JSON object and HTML responses, detects Flush calls and leaves streams completely untouched, and sends telemetry through a bounded background goroutine. It uses only the Go standard library — no external dependencies are required.
Installation
1
Add the module
2
Import the package
3
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.Creating the middleware
Callagentfeedback.New with an Options struct. The function validates your API key and starts the background telemetry worker immediately.
Options struct fields
Pass anagentfeedback.Options struct to agentfeedback.New. Only APIKey is required.
string
required
Your Agent Feedback product key. Must match the pattern
af_live_<keyId>_<secret>. Store this as an environment variable.string
Override the Agent Feedback API endpoint. Trailing slashes are trimmed automatically.
[]string
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: []string{"/search", "/docs/**"}.[]string
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.FeedbackMode
default:"FeedbackAuto"
Controls the feedback instruction sent to agents. Use the package constants:
agentfeedback.FeedbackAuto, agentfeedback.FeedbackAsk, or agentfeedback.FeedbackOff.func(*http.Request) string
Function that extracts an opaque customer identifier from the request. Used to group interactions by account in the dashboard.
func(*http.Request) string
Function that extracts a session identifier from the request. Links a sequence of interactions for session-level analytics.
func(*http.Request) string
Function that returns a hint about the agent runtime making the request. Used for runtime-level breakdown in the dashboard.
time.Duration
default:"500ms"
How often the background goroutine flushes telemetry events. The queue also flushes immediately when 50 events accumulate.
int
default:"1000"
Capacity of the telemetry channel. When the channel is full, the oldest event is discarded to make room for the newest.
*http.Client
Override the HTTP client used for telemetry delivery. Defaults to a client with a 3-second timeout.
func(context.Context, string, http.Header, []byte) error
Provide a custom telemetry sender for testing or proxying. When set,
HTTPClient is ignored.Stream detection
The middleware wrapshttp.ResponseWriter in a capture buffer. If the handler calls Flush() before finishing, the buffer is flushed directly to the underlying writer and the response is marked as streamed — instrumentation is skipped and no body buffering occurs. Streaming handlers are never blocked or modified.
Graceful shutdown
Callfeedback.Shutdown(ctx) at server shutdown to drain the telemetry queue. Pass a context with a deadline to set a maximum wait time.
Agent helper functions
ImportFeedbackFromResponse and SubmitProductOutcome from the same package to build a feedback-aware agent runtime that submits outcomes deterministically.
FeedbackFromResponse
Reads the *Envelope from an *http.Response and the response body bytes. Checks the JSON body for _agentFeedback, then the HTML body for <script id="agent-feedback">, then the Agent-Feedback response header.
SubmitProductOutcome
Submits a compact outcome review to the URL embedded in the envelope. Validates the contract and enforces the allowed-origin allow-list.
Pass a non-nil
allowedOrigins slice only when submitting to a self-hosted Agent Feedback endpoint. The default trusted origin is https://agent-feedback-api-production.up.railway.app.