Skip to content

Custom Guards

Create your own guard by implementing the Guard interface.

Guard Interface

typescript
import type { Guard, GuardContext, GuardResult } from 'open-guardrail-core';

const myGuard: Guard = {
  name: 'my-guard',
  version: '1.0.0',
  description: 'My custom guard',
  category: 'custom',
  supportedStages: ['input', 'output'],

  async check(text: string, ctx: GuardContext): Promise<GuardResult> {
    const start = performance.now();
    const hasProblem = text.includes('bad-word');

    return {
      guardName: 'my-guard',
      passed: !hasProblem,
      action: hasProblem ? 'block' : 'allow',
      message: hasProblem ? 'Found bad word' : undefined,
      latencyMs: Math.round(performance.now() - start),
    };
  },
};

Factory Pattern

Wrap your guard in a factory function for configurability:

typescript
interface MyGuardOptions {
  blockedWords: string[];
  action: 'block' | 'warn';
}

function myGuard(options: MyGuardOptions): Guard {
  return {
    name: 'my-guard',
    version: '1.0.0',
    description: 'Custom blocked word guard',
    category: 'custom',
    supportedStages: ['input', 'output'],

    async check(text, ctx) {
      const start = performance.now();
      const lower = text.toLowerCase();
      const found = options.blockedWords.find((w) => lower.includes(w));

      return {
        guardName: 'my-guard',
        passed: !found,
        action: found ? options.action : 'allow',
        message: found ? `Found: ${found}` : undefined,
        latencyMs: Math.round(performance.now() - start),
      };
    },
  };
}

Using Custom Guards

typescript
import { pipe, promptInjection } from 'open-guardrail';

const pipeline = pipe(
  promptInjection({ action: 'block' }),
  myGuard({ blockedWords: ['spam', 'scam'], action: 'block' }),
);

Streaming Support

Add checkChunk() for streaming pipeline compatibility:

typescript
const myStreamingGuard: Guard = {
  // ... base fields
  supportsStreaming: true,

  async checkChunk(chunk, accumulated, ctx) {
    // chunk: current chunk
    // accumulated: all text so far
    return { /* GuardResult */ };
  },
};

Released under the MIT License.