Skip to content

Repository files navigation

AI SDK Privacy Filter Middleware

A Vercel AI SDK middleware that automatically redacts personally identifiable information (PII) from chat messages using OpenAI's privacy-filter model — running entirely locally via Transformers.js.

No API calls. No cloud. The 1.5B param model runs in your browser or on your server.

Install

npm install ai-sdk-privacy-filter-middleware

With your preferred AI SDK provider (OpenAI, OpenRouter, etc):

npm install @ai-sdk/openai
# or
npm install @openrouter/ai-sdk-provider

Quick Start

OpenAI

import { wrapLanguageModel } from 'ai';
import { openai } from '@ai-sdk/openai';
import { privacyFilterMiddleware } from 'ai-sdk-privacy-filter-middleware';

const model = wrapLanguageModel({
  model: openai('gpt-4o'),
  middleware: privacyFilterMiddleware(),
});

OpenRouter

import { wrapLanguageModel } from 'ai';
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
import { privacyFilterMiddleware } from 'ai-sdk-privacy-filter-middleware';

const openrouter = createOpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });

const model = wrapLanguageModel({
  model: openrouter('anthropic/claude-3.5-sonnet'),
  middleware: privacyFilterMiddleware(),
});

That's it. Any generateText or streamText call using model will now automatically:

  1. Detect PII in user/system messages (names, emails, phones, addresses, etc.)
  2. Replace them with typed placeholders ([PERSON_1], [EMAIL_1])
  3. Restore the original values in the LLM's response
// User sends: "I'm Alice, my email is alice@corp.com"
// LLM sees:   "I'm [PERSON_1], my email is [EMAIL_1]"
// LLM replies: "Hello [PERSON_1], I'll contact [EMAIL_1]"
// User sees:  "Hello Alice, I'll contact alice@corp.com"

Configuration

const model = wrapLanguageModel({
  model: openai('gpt-4o'),
  middleware: privacyFilterMiddleware({
    // Only redact specific entity types (default: auto-detect all)
    entityTypes: ['private_person', 'private_email', 'private_phone'],

    // Minimum confidence score (default: 0.8)
    minScore: 0.9,

    // Whether to unredact LLM responses (default: true)
    redactResponses: true,

    // Custom placeholder format
    placeholderFormat: (type, n) => `<<${type}_${n}>>`,

    // Device override ('wasm' | 'webgpu')
    device: 'webgpu',

    // Model loading progress callback
    onProgress: ({ status, progress }) => {
      console.log(status, progress);
    },
  }),
});

Eager Initialization

The model loads lazily on first use (first request will be slower). To pre-load:

import { createPrivacyFilter } from 'ai-sdk-privacy-filter-middleware';

const middleware = await createPrivacyFilter({ device: 'webgpu' });

const model = wrapLanguageModel({
  model: openai('gpt-4o'), // or openrouter('anthropic/claude-3.5-sonnet')
  middleware,
});

Detected Entity Types

The model auto-detects 8 categories of PII:

Type Placeholder Example
private_person [PERSON_N] Alice Smith
private_email [EMAIL_N] alice@example.com
private_phone [PHONE_N] +1-555-0123
private_address [ADDRESS_N] 123 Main St
private_date [DATE_N] 1990-01-15
private_url [URL_N] https://example.com
account_number [ACCOUNT_N] 1234-5678-9012
secret [SECRET_N] API keys, passwords

How It Works

User message ──► transformParams (detect + redact PII)
                        │
                        ▼
               LLM sees redacted text
                        │
                        ▼
               LLM response (with placeholders)
                        │
                        ▼
         wrapGenerate/wrapStream (unredact placeholders)
                        │
                        ▼
               User sees original PII restored

The detection model runs locally via Transformers.js (WASM or WebGPU). Only user and system messages are redacted — assistant and tool messages pass through untouched. Response unredaction uses regex replacement on the known placeholders — no ML inference needed on the response side.

Runtime Support

Runtime Device Status
Node.js WASM Supported
Browser WebGPU Supported
Browser WASM Supported (fallback)

The middleware auto-detects the best available device. WebGPU is used when available, falling back to WASM.

Requirements

  • ai >= 4.0.0 (peer dependency)
  • @huggingface/transformers >= 4.2.0 (bundled)

License

MIT

About

AI SDK Privacy Filter Middlware using OpenAI Privacy-Filter

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages