checkrd

Vercel AI SDK

Add Checkrd policy enforcement to the Vercel AI SDK via LanguageModelV2Middleware.

Vercel AI SDK

Checkrd ships a LanguageModelV2Middleware that hooks into every generateText, streamText, generateObject, and streamObject call. The middleware policy-evaluates the call before the model runs and emits structured telemetry on completion (including streaming token counts).

Install

bash
npm install checkrd ai @ai-sdk/openai

Quickstart

typescript
import { initAsync, wrapAsync } from "checkrd";
import { checkrdMiddleware } from "checkrd/integrations/ai-sdk";
import { generateText, wrapLanguageModel } from "ai";
import { openai } from "@ai-sdk/openai";

const checkrd = await initAsync({
  policy: "policy.yaml",
  agentId: "research-agent",
});

const model = wrapLanguageModel({
  model: openai("gpt-4o"),
  middleware: checkrdMiddleware({
    engine: checkrd.engine,
    enforce: true,
    agentId: "research-agent",
    sink: checkrd.sink,
  }),
});

const result = await generateText({
  model,
  prompt: "Tell me a joke",
});

Streaming

The middleware wraps the model's stream with a TransformStream that accumulates token usage as chunks flow through. The completion telemetry event fires when the stream's flush runs:

typescript
const { textStream } = await streamText({
  model,
  prompt: "...",
});

for await (const chunk of textStream) {
  process.stdout.write(chunk);
}
// Telemetry event with input_tokens / output_tokens emits here.

What gets enforced

AI SDK callSynthetic URLOperation
generateTextai-sdk://{provider}/{modelId}generate
streamTextai-sdk://{provider}/{modelId}stream
generateObjectai-sdk://{provider}/{modelId}generate
streamObjectai-sdk://{provider}/{modelId}stream

Body fields exposed for matchers: messages, prompt, mode, temperature, topP, maxTokens.

yaml
agent: research-agent
default: allow

rules:
  - name: deny-gpt4-for-cheap-tier
    deny:
      url: "ai-sdk://openai/gpt-4*"
      headers:
        x-tenant-tier: "free"

  - name: limit-temperature
    deny:
      url: "ai-sdk://*/*"
      body:
        temperature: ">1.5"

Edge runtimes

The Vercel AI SDK runs in Edge Runtime, Cloudflare Workers, and Deno. Use initAsync (not init) so the WASM core loads via fetch + WebAssembly.compile instead of node:fs.readFileSync. The middleware itself is runtime-agnostic.

typescript
// Cloudflare Workers entry
import { initAsync } from "checkrd";
import { checkrdMiddleware } from "checkrd/integrations/ai-sdk";

export default {
  async fetch(req, env) {
    const checkrd = await initAsync({
      apiKey: env.CHECKRD_API_KEY,
      agentId: "edge-agent",
    });
    // ... use middleware ...
  },
};

Observation mode

Set enforce: false to log denies without aborting:

typescript
checkrdMiddleware({
  engine: checkrd.engine,
  enforce: false, // observation mode
  agentId: "research-agent",
  sink: checkrd.sink,
});

Caveats

  • The AI SDK passes streaming chunks through flush. Token counts are only available at end-of-stream — they're not in the gate event, only the completion event.
  • Only the v2 middleware shape is supported. AI SDK 4.x uses LanguageModelV2Middleware. The legacy v1 middleware shape is not supported.
  • Provider name detection. The middleware reads provider from the model spec. Custom providers (createOpenAICompatible) report their configured name.