Prerequisites
Install and initialize the TypeScript SDK. The example uses that client asfw.
AI SDK 6
Install the AI SDK 6 and matching OpenAI provider packages. SetOPENAI_API_KEY in your service environment for the model provider.
error.hook is user_input for a blocked prompt and llm_output for blocked generated text. Pass scanOutput: false to check input only, and scanToolCalls: true to classify generated tool-call arguments.
TypeScript SDK versions before 0.10.0 leave scanOutput off by default, and their AI SDK 5 and 6 middleware does not read generated content. On those versions, pass scanOutput: false, classify response.text yourself, and stop on a blocking verdict before returning it. Direct classify() returns the verdict in every mode and does not throw:
AI SDK 7
TypeScript SDK 0.9.1 adds a separate AI SDK 7 adapter. AI SDK 7 requires Node.js 22 or later and uses its v4 middleware contract. Import the adapter explicitly;fw.asMiddleware() remains the AI SDK 5/6 path.
ai@7.0.166 and its internal
@ai-sdk/provider@4.0.37 contract. The public OpenAI package in the install
command is @ai-sdk/openai@4.0.111; its official package metadata depends on
that same internal provider contract.
scanOutput is on by default, so the
generated-text check applies without that option; scanToolCalls stays
opt-in. Reasoning parts pass through without classification. In possible
Block mode, streaming text and tool-input parts remain buffered in their
original interleaved order until each completed sequence has a verdict. The
buffer is bounded to 1 MiB and 10,000 parts by default; limits, aborts,
classification errors, and invalid stream identities fail without releasing
pending content. A byte-identical final tool call can reuse its streamed-input
verdict; any changed final input is classified again before emission.
Because output is checked by default, a Block-mode or mode-less stream delivers
each text block after its verdict instead of token by token. Set an explicit
Shadow or Warn mode, or pass scanOutput: false, to stream tokens as they are
generated.
Run the input check in parallel
From TypeScript SDK 0.10.0, passparallel: true to either middleware to start
the model call while its input is classified.
FirewallBlockedException, discards the
generation, and cancels a stream that had already started. Output checks are
unchanged. The Vercel middleware classifies inline in
every mode, including Shadow, and classification errors reach the caller.
Expected result
Allowed input reaches the model, and allowed output is returned only after classification. A blocked input or output throwsFirewallBlockedException. Handle it at your application boundary and return a safe response. Let API and network failures follow your error policy. See TypeScript errors.
Coverage
The middleware checks the latest user message or tool responses before each model call, and non-streamed generated text before it is returned. With AI SDK 5 and 6 streaming, output is classified after the stream has been delivered, so a block arrives as an error part following text the caller has already received. Use non-streaming generation or the AI SDK 7 adapter when blocked content must not reach the caller. SetscanToolCalls: true to classify generated tool-call arguments, and classify the arguments again before executing a tool your application runs itself.
Every protected call must use the wrapped model. For models routed through Vercel AI Gateway, use the gateway guide.
Vercel AI SDK documentation