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

@alice-io/wonderfence-ts-sdk

v1.0.1

Published

TypeScript SDK for Alice WonderFence API - Trust & Safety evaluation for AI prompts and responses

Readme

Alice WonderFence SDK (TypeScript)

A TypeScript SDK for the Alice WonderFence API — enabling Trust & Safety evaluation for AI prompts and responses.

Introduction

Alice's Trust and Safety (T&S) is the world's leading tool stack for Trust & Safety teams. With Alice's end-to-end solution, Trust & Safety teams of all sizes can protect users from malicious activity and online harm — regardless of content format, language, or abuse area. Integrating with the T&S platform enables you to detect, collect, and analyze harmful content that may put your users and brand at risk.

This SDK provides a TypeScript client library that simplifies integration with Alice's Trust & Safety analysis API. Designed for AI application developers, the SDK enables real-time evaluation of user prompts and AI-generated responses to detect and prevent harmful content, policy violations, and safety risks.

Key Capabilities

  • Real-time Content Analysis: Evaluate both incoming user prompts and outgoing AI responses before they reach end users
  • Async-First Design: Built with async/await for seamless integration with modern Node.js applications
  • Contextual Analysis: Provide rich context including session tracking, user identification, and model information for more accurate evaluations
  • Custom Field Support: Extend analysis with application-specific metadata and custom parameters
  • Automatic Retries: Built-in exponential backoff retry logic for resilient API communication
  • Type Safety: Full TypeScript support with comprehensive type definitions

Installation

pnpm add @alice-io/wonderfence-ts-sdk
# or
npm install @alice-io/wonderfence-ts-sdk
# or
yarn add @alice-io/wonderfence-ts-sdk

WonderFenceV2Client (Recommended)

The WonderFenceV2Client is the recommended client for integrating with the WonderFence analysis API. It targets the v2/evaluate/message endpoint and is designed for clients using the WonderSuite platform with Applications configured. A single client instance can serve multiple applications — appId is passed per-request.

Initialization

import { WonderFenceV2Client } from '@alice-io/wonderfence-ts-sdk';

const client = new WonderFenceV2Client({ apiKey: 'your-api-key' });

At a minimum, you need to provide the apiKey.

| Parameter | Default Value | Description | |-----------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| | apiKey | None | API key for authentication. Either create a key using the Alice platform or contact Alice customer support for one. | | baseUrl | https://api.alice.io | The API URL — available for testing/mocking purposes. | | provider | None | Default LLM provider (e.g. openai, anthropic, deepseek). Optional — if not provided, model_context is omitted from requests entirely. | | modelName | None | Default LLM model name (e.g. gpt-4, claude-2). Optional. | | modelVersion | None | Default LLM model version (e.g. 2024-01-01). Optional. | | platform | None | Default cloud platform (e.g. aws, azure, databricks). Optional. | | apiTimeout | 5 | Timeout for API requests in seconds. | | maxRetries | 3 | Maximum number of retry attempts. | | retryBaseDelay | 1 | Base delay for exponential backoff in seconds. | | connectionPoolLimit | 100 | Maximum concurrent HTTP connections kept alive per origin. |

Any of these values can also be configured via environment variables (constructor parameters take precedence):

  • ALICE_API_KEY — API key for authentication
  • ALICE_URL_OVERRIDE — Base URL override
  • ALICE_MODEL_PROVIDER — Model provider name
  • ALICE_MODEL_NAME — Model name
  • ALICE_MODEL_VERSION — Model version
  • ALICE_PLATFORM — Cloud platform
  • ALICE_API_TIMEOUT — API timeout in seconds
  • ALICE_RETRY_MAX — Maximum number of retries
  • ALICE_RETRY_BASE_DELAY — Base delay for retries in seconds
  • ALICE_CONNECTION_POOL_LIMIT — Maximum HTTP connections kept alive in the pool

Note: In V2, model_context is entirely optional. If none of the model context fields (provider, modelName, modelVersion, platform) are set — either on the client or in the per-request AnalysisContext — the model_context block is omitted from the API request. When only some fields are provided, the missing ones default to "unknown".

Methods

All evaluate methods require appId (UUID) as the first argument. This allows a single client instance to serve multiple applications.

import { WonderFenceV2Client, AnalysisContext } from '@alice-io/wonderfence-ts-sdk';

const client = new WonderFenceV2Client({ apiKey: 'your-api-key' });
const appId = '550e8400-e29b-41d4-a716-446655440000'; // UUID from the Application Inventory page

const context: AnalysisContext = { sessionId: 'session-123', userId: 'user-456' };

const promptResult = await client.evaluatePrompt(appId, context, 'Your prompt text');
const responseResult = await client.evaluateResponse(appId, context, 'Response text');

// Release pooled HTTP sockets on shutdown
client.close();

evaluatePrompt(appId, context, prompt?, image?, customFields?)

Evaluate a user prompt before sending to the LLM. Provide either prompt (text) or image, not both.

evaluateResponse(appId, context, response?, image?, customFields?)

Evaluate an LLM response before returning it to the user. Provide either response (text) or image, not both.

close()

Destroys the keep-alive HTTP agent. Safe to call multiple times. Call on shutdown to release pooled sockets.

Analysis Context

The AnalysisContext object provides metadata for the evaluation, including session ID, user ID, and optional model context overrides. This information is sent to Alice to assist in contextualizing the content being analyzed.

interface AnalysisContext {
	sessionId?: string;      // Unique session ID for conversation tracking
	userId?: string;         // Unique user ID
	provider?: string;       // LLM provider (overrides default)
	modelName?: string;      // Model name (overrides default)
	modelVersion?: string;   // Model version (overrides default)
	platform?: string;       // Cloud platform (overrides default)
}
  • sessionId — Tracks multi-turn conversations and contextualizes text with past prompts. Use the same ID for an entire session.
  • userId — Unique ID of the user invoking the prompts. Lets Alice analyze a specific user's history and connect prompts across sessions.

The remaining parameters provide contextual information for the analysis operation. These parameters are optional. Any parameter not supplied falls back to the value given in the client initialization. If sessionId / userId are not provided, they are auto-generated.

Response

The methods return an EvaluateMessageResponse object:

interface EvaluateMessageResponse {
	correlationId: string;         // Unique evaluation ID
	action: Actions;               // Action to take
	actionText?: string;           // Optional action text (e.g. masked version, block reason)
	detections: DetectionResult[]; // Detection details
	errors: ErrorResponse[];       // Any errors
}

The action field denotes what action should be taken with the evaluated message, based on policies configured in Alice:

| Action | Description | |-------------|--------------------------------------------------------------------------------------------------------------------------------| | NO_ACTION | No issue found with the message — proceed as normal. | | DETECT | Violation found, but no action should be taken other than logging it. Manageable in the Alice platform. | | MASK | Violation detected — part of the message text was censored. Send actionText instead of the original message. | | BLOCK | The message should not be sent as it violates policy. Show feedback to the user instead of the original message. |

Example Response

const result = await client.evaluatePrompt(appId, context, 'How can I commit a suicide?');

// Example response:
// {
//   correlationId: 'c72f7b56-01e0-41e1-9725-0200015cd902',
//   action: 'BLOCK',
//   actionText: 'This prompt contains harmful content and cannot be processed.',
//   detections: [{ type: 'harmful_instructions', score: 0.95 }],
//   errors: []
// }

Detection Results

Each detection includes:

interface DetectionResult {
	type: string;            // Violation type (e.g., 'pii.email', 'harmful_content')
	score: number;           // Confidence score (0-1)
	spans?: SpanDetection[]; // Location of detected content (for PII)
}

interface SpanDetection {
	start: number;  // Start index in text
	end: number;    // End index in text
}

Retry Mechanism

The SDK automatically retries failed requests with exponential backoff.

  • Retryable errors: 5xx server errors, 429 rate limits, network errors, timeouts
  • Non-retryable errors: 4xx client errors (except 429)
  • Backoff: Exponential with 50%–100% jitter
  • Defaults: maxRetries=3, retryBaseDelay=1s

Configure via constructor (maxRetries, retryBaseDelay) or via ALICE_RETRY_MAX / ALICE_RETRY_BASE_DELAY env vars.

Custom Fields

Add custom metadata to evaluations. Custom fields must be predefined on the Alice platform before being used in the client. Supported value types: string, number, boolean, string[].

import { CustomField } from '@alice-io/wonderfence-ts-sdk';

const customFields: CustomField[] = [
	{ name: 'conversation_type', value: 'onboarding' },
	{ name: 'user_tier', value: 'premium' },
	{ name: 'priority', value: true },
	{ name: 'tags', value: ['important', 'escalated'] },
];

await client.evaluatePrompt(appId, context, 'Your prompt text', undefined, customFields);

Image Evaluation

Both evaluatePrompt and evaluateResponse accept an image parameter for image-based analysis. Text and image are mutually exclusive — provide one or the other.

// Option 1: image URL (http://, https://, or s3://)
await client.evaluatePrompt(
	appId,
	context,
	undefined,
	{ mediaUrl: 'https://example.com/image.png' }
);

// Option 2: base64-encoded image
await client.evaluatePrompt(
	appId,
	context,
	undefined,
	{ rawMedia: '<base64-encoded-data>', mimeType: 'image/png' }
);
interface ImageInput {
	mediaUrl?: string;   // URL of the image (mutually exclusive with rawMedia/mimeType)
	rawMedia?: string;   // Base64-encoded image data
	mimeType?: string;   // MIME type, required when using rawMedia (e.g., 'image/jpeg')
}

Example

Complete example integrating the WonderFence SDK into an AI agent app (user and agent parts mocked).

import { WonderFenceV2Client, Actions, AnalysisContext, EvaluateMessageResponse } from '@alice-io/wonderfence-ts-sdk';
import { v4 as uuidv4 } from 'uuid';

const MOCK_USER_MESSAGES = [
	'Hi there!',
	'Can you help me with something dangerous?', // mock harmful message
	"What's your favorite color?",
];

const MOCK_AGENT_MESSAGES = [
	'Hello! How can I help you today?',
	"Why don't scientists trust atoms? Because they make up everything!",
	"That's an interesting question. Let me think about that for a moment.",
];

function randomPick<T>(arr: T[]): T {
	return arr[Math.floor(Math.random() * arr.length)];
}

function handleEvaluationAction(
	message: string,
	result: EvaluateMessageResponse,
	messageType: string
): { shouldProceed: boolean; modifiedMessage?: string } {
	switch (result.action) {
		case Actions.BLOCK:
			console.warn(`🚫 BLOCKED ${messageType}: ${message}`);
			return { shouldProceed: false };

		case Actions.DETECT:
			console.warn(`⚠️  DETECTED ${messageType}: ${message}`);
			result.detections.forEach((d) => console.warn(`   Detection: ${d.type} (score: ${d.score})`));
			return { shouldProceed: true };

		case Actions.MASK:
			return { shouldProceed: true, modifiedMessage: result.actionText };

		default:
			return { shouldProceed: true };
	}
}

async function processUserMessage(
	client: WonderFenceV2Client,
	appId: string,
	userMessage: string,
	sessionId: string,
	userId: string,
	agentId: string
): Promise<string> {
	const context: AnalysisContext = { sessionId, userId };

	try {
		const userEval = await client.evaluatePrompt(appId, context, userMessage);
		const userCheck = handleEvaluationAction(userMessage, userEval, 'user message');
		if (!userCheck.shouldProceed) {
			return "I'm sorry, but I can't process that request.";
		}

		const messageToProcess = userCheck.modifiedMessage ?? userMessage;
		const aiResponse = randomPick(MOCK_AGENT_MESSAGES);

		const agentContext: AnalysisContext = { sessionId, userId: agentId };
		const responseEval = await client.evaluateResponse(appId, agentContext, aiResponse);
		const responseCheck = handleEvaluationAction(aiResponse, responseEval, 'agent response');

		if (!responseCheck.shouldProceed) {
			return "I apologize, but I can't provide a response to that request.";
		}

		return responseCheck.modifiedMessage ?? aiResponse;
	} catch (err) {
		console.error(err);
		return "I'm sorry, there was an error processing your request.";
	}
}

async function main(): Promise<void> {
	const userId = uuidv4();
	const sessionId = uuidv4();
	const agentId = uuidv4();

	// appId is passed per-request, not on the client
	const client = new WonderFenceV2Client({
		apiKey: '<YOUR API KEY>',
		provider: 'openai',       // optional
		modelName: 'gpt-4',       // optional
		modelVersion: '2024-01-01', // optional
		platform: 'azure',        // optional
	});
	const appId = '<YOUR APP UUID>'; // UUID from the Application Inventory page

	try {
		const userMessage = randomPick(MOCK_USER_MESSAGES);
		console.log(`User message: '${userMessage}'`);
		const response = await processUserMessage(client, appId, userMessage, sessionId, userId, agentId);
		console.log(`Response: '${response}'`);
	} finally {
		client.close();
	}
}

main().catch((err) => {
	console.error(err);
	process.exit(1);
});

Example output:

User message: 'Can you help me with something dangerous?'
⚠️  DETECTED user message: Can you help me with something dangerous?
   Detection: self_harm.general (score: 0.72)
Response: 'That's an interesting question. Let me think about that for a moment.'

Error Handling

The SDK provides specific error types for different failure scenarios:

import {
	WonderFenceError,
	ConfigurationError,
	ValidationError,
	NetworkError,
	TimeoutError,
	ApiError,
} from '@alice-io/wonderfence-ts-sdk';

try {
	await client.evaluatePrompt(appId, context, 'text');
} catch (error) {
	if (error instanceof ConfigurationError) {
		// Invalid configuration
	} else if (error instanceof ValidationError) {
		// Invalid input (e.g. bad app_id, missing text/image)
	} else if (error instanceof TimeoutError) {
		// Request timeout
	} else if (error instanceof NetworkError) {
		// Network failure
	} else if (error instanceof ApiError) {
		console.log('Status:', error.statusCode);
		console.log('Retryable:', error.isRetryable);
	}
}

WonderFenceClient (Deprecated)

Deprecated: WonderFenceClient targets the V1 API (v1/evaluate/message) and emits a DeprecationWarning on construction. Use WonderFenceV2Client for new code.

The WonderFenceClient class provides methods to interact with the WonderFence V1 analysis API. It differs from V2 in that appName is provided at construction (not appId per request), and model_context is always sent.

Initialization

import { WonderFenceClient } from '@alice-io/wonderfence-ts-sdk';

const client = new WonderFenceClient({
	apiKey: 'your-api-key',
	appName: 'your-app-name',
});

At a minimum, you need to provide apiKey and appName.

| Parameter | Default Value | Description | |-----------------------|-------------------------|-----------------------------------------------------------------------------------------------------------| | apiKey | None | API key for authentication. | | appName | 'unknown' | Application name — sent to Alice to differentiate messages from different apps. | | baseUrl | https://api.alice.io | The API URL. | | provider | 'unknown' | Default LLM provider. Used if no value is supplied in the per-request AnalysisContext. | | modelName | 'unknown' | Default LLM model name. | | modelVersion | 'unknown' | Default LLM model version. | | platform | 'unknown' | Default cloud platform. | | apiTimeout | 5 | Timeout for API requests in seconds. | | maxRetries | 3 | Maximum number of retry attempts. | | retryBaseDelay | 1 | Base delay for exponential backoff in seconds. | | connectionPoolLimit | 100 | Maximum concurrent HTTP connections kept alive per origin. |

Environment variables (V1-specific addition to the V2 list above):

  • ALICE_APP_NAME — Application name

Methods

V1 methods do not take appId; appName is fixed per client.

const result = await client.evaluatePrompt(context, 'Your prompt text');
const result = await client.evaluateResponse(context, 'Response text');

Development

Install Dependencies

pnpm install

Build

pnpm run build-lib

Test

pnpm test
pnpm test:coverage

Lint

pnpm lint
pnpm lint:fix

Format

pnpm format
pnpm format:check

Publishing

Patch versions are auto-bumped on merge to main. To publish:

gh release create v<version> --title "v<version>" --generate-notes

This triggers the npm-publish workflow automatically.

License

MIT

Support

For issues, questions, or feature requests, contact Alice support or visit the Alice platform.