npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@nulab/datadog-ai-guard-middleware-ai-v3

v0.1.1

Published

Datadog AI Guard middleware for [Vercel AI SDK](https://sdk.vercel.ai/) v6 (`@ai-sdk/provider@^3`).

Readme

@nulab/datadog-ai-guard-middleware-ai-v3

Datadog AI Guard middleware for Vercel AI SDK v6 (@ai-sdk/provider@^3).

Using AI SDK v5? See @nulab/datadog-ai-guard-middleware-ai-v2 instead.

Installation

npm install @nulab/datadog-ai-guard-middleware-ai-v3

Peer Dependencies

  • @ai-sdk/provider ^3.0.0

Usage

Initializing dd-trace

Initialize dd-trace with AI Guard enabled and pass ddtracer.aiguard (the AIGuardEvaluator) to the middleware.

import ddtracer from "dd-trace";

ddtracer.init({
  experimental: {
    aiguard: { enabled: true },
  },
});

Authentication follows dd-trace environment variables (DD_API_KEY, DD_APP_KEY, etc.). The AI Guard endpoint is resolved by dd-trace from DD_SITE (e.g., ap1.datadoghq.com -> https://app.ap1.datadoghq.com/api/v2/ai-guard).

Creating a Guarded Model

Use wrapLanguageModel to create a middleware-applied model that can be reused with both generateText and streamText.

import { wrapLanguageModel } from "ai";

const guardedModel = wrapLanguageModel({
  model: yourModel,
  middleware: [
    new AIGuardMiddleware({
      evaluator: ddtracer.aiguard,
    }),
  ],
});

Non-Streaming

import { generateText } from "ai";
import {
  AIGuardMiddleware,
  AIGuardMiddlewareAbortError,
} from "@nulab/datadog-ai-guard-middleware-ai-v3";

try {
  const result = await generateText({
    model: guardedModel,
    prompt: "Hello",
  });
  console.log(result.text);
} catch (err) {
  if (err instanceof AIGuardMiddlewareAbortError) {
    // Blocked by AI Guard security policy
  } else {
    throw err;
  }
}
  • The prompt is evaluated before being sent to the LLM. If Datadog's blocking policy is active and the prompt violates it, an AIGuardMiddlewareAbortError is thrown.
  • After the LLM responds, the entire assistant turn is evaluated once. If Datadog returns DENY / ABORT without a blocking policy, only a warning is logged.

Streaming

import { streamText } from "ai";

const { stream } = await streamText({
  model: guardedModel,
  prompt: "Hello",
});

for await (const part of stream) {
  if (part.type === "text-delta") process.stdout.write(part.text);
  if (part.type === "error") {
    // AIGuardStreamTripWire error: tool call blocked by AI Guard
    console.error("blocked:", String(part.error?.message));
  }
}
  • In streaming mode, text-only assistant output is not sent to AI Guard. AI Guard evaluates only prompts and tool-call chunks.
  • When evaluating a tool-call, preceding sibling tool calls from the same turn are included in the same evaluation request.

Options

interface AIGuardMiddlewareOptions {
  evaluator: AIGuardEvaluator;
  allowOnFailure?: boolean;
  createAbortError?: (kind: AIGuardKind, message: string) => Error;
  logger?: AIGuardLogger;
}

| Option | Type | Default | Description | |--------|------|---------|-------------| | evaluator | AIGuardEvaluator | (required) | Object with an evaluate(messages, opts) method. Pass ddtracer.aiguard when using dd-trace. Any object satisfying the AIGuardEvaluator interface works. | | allowOnFailure | boolean | true | true: fail-open (continue on evaluation errors). false: throw AIGuardMiddlewareClientError when evaluation is unavailable. Covers both API failures and message normalization/conversion errors. | | createAbortError | (kind, message) => Error | — | Factory to create a custom error when AI Guard blocks a request. markAsNonRetryable() is automatically applied. Useful for framework integration (e.g., injecting Mastra's TripWire). | | logger | AIGuardLogger | console | Logger with info, warn, error methods. Defaults to console so security events are always visible. Pass a no-op logger ({ info() {}, warn() {}, error() {} }) to suppress output. |

When Datadog returns DENY / ABORT without a blocking policy, the middleware logs a warning and continues regardless of allowOnFailure.

API

Classes

| Export | Description | |--------|-------------| | AIGuardMiddleware | Main middleware class. Pass to wrapLanguageModel for use. | | AIGuardMiddlewareAbortError | Thrown when Datadog AI Guard's blocking policy blocks a request (default when createAbortError is not specified). Use instanceof to identify policy blocks. | | AIGuardMiddlewareClientError | Thrown when AI Guard evaluation cannot be performed (allowOnFailure: false). Distinguishes service failures from policy blocks (AIGuardMiddlewareAbortError). | | AIGuardStreamTripWire | Error used in streaming error chunks ({ type: "error" }). Identifies AI Guard-specific errors on the stream consumer side. |

Types

| Export | Description | |--------|-------------| | AIGuardMiddlewareOptions | Constructor argument type for AIGuardMiddleware. | | AIGuardEvaluator | Interface with an evaluate(messages, opts) method. ddtracer.aiguard satisfies this interface. | | AIGuardLogger | Interface with info, warn, error methods. | | AIGuardKind | "Prompt" \| "Assistant response" \| "Tool call" union type. | | AIGuardMessage | Message type sent to AI Guard. Argument type for AIGuardEvaluator.evaluate(). |

Error Classes

| Class | Code | Condition | |-------|------|-----------| | AIGuardMiddlewareAbortError | AI_GUARD_MIDDLEWARE_ABORT | Datadog AI Guard blocked the request via blocking policy | | AIGuardMiddlewareClientError | AI_GUARD_MIDDLEWARE_CLIENT_ERROR | AI Guard evaluation unavailable + allowOnFailure=false | | AIGuardStreamTripWire | — | Streaming error chunk: policy block or fail-close evaluation failure |

Security: These errors intentionally hide details from the original AI Guard SDK error (reason, tags, etc.).

Evaluation Scope

  • Prompt: Evaluated once before sending to the LLM
  • Assistant response (non-streaming): Evaluated once per assistant turn after doGenerate
  • Tool calls (streaming): Evaluated on each tool-call chunk with accumulated sibling tool calls
  • Tool execution results: Automatically evaluated as part of the next turn's prompt in agent loops

Blocking decisions are made by Datadog AI Guard's blocking policy. The middleware sends block: true but only blocks when Datadog returns AIGuardAbortError.

Known Limitations

  • dd-trace AI Guard experimental feature must be enabled (use a compatible version).
  • Blocking requires a Datadog-side blocking policy. Without one, DENY / ABORT only produces warnings.
  • Streaming text-only output is not protected by AI Guard. Use non-streaming for strict blocking of all assistant output.
  • Multimodal evaluation supports images (image/*) only. Non-image files (e.g., PDF) are not sent to AI Guard.
  • Evaluation API calls increase per assistant turn (non-streaming) or per tool-call chunk (streaming).

Requirements

  • Node.js >= 22
  • @ai-sdk/provider ^3.0.0
  • dd-trace >= 5 with AI Guard enabled

License

Apache-2.0