Complete API documentation for @llm-shield/core.
The main class for scanning text with LLM Shield.
new LLMShield(config?: LLMShieldConfig)Creates a new LLMShield instance with optional configuration.
- config (optional): Configuration object
interface LLMShieldConfig {
cache?: CacheConfig;
scanners?: ScannerType[];
models?: ModelConfig;
thresholds?: Partial<Record<ScannerType, number>>;
debug?: boolean;
timeout?: number;
}Configure result caching behavior.
interface CacheConfig {
maxSize: number; // Maximum number of cached entries (default: 1000)
ttlSeconds: number; // Time-to-live in seconds (default: 3600)
}Example:
const shield = new LLMShield({
cache: {
maxSize: 5000,
ttlSeconds: 7200, // 2 hours
},
});Select specific scanners to run. Empty array means all scanners.
const shield = new LLMShield({
scanners: ['prompt-injection', 'toxicity', 'secrets'],
});Available scanners:
toxicity- Detect toxic, hateful, or offensive contentprompt-injection- Detect prompt injection attemptssecrets- Detect API keys, passwords, tokenspii- Detect personal information (emails, SSNs, credit cards)ban-competitors- Block competitor mentionsban-topics- Filter unwanted topicsban-substrings- Block specific patternsmalicious-urls- Detect phishing/malicious URLssensitive-output- Prevent sensitive data leaksurl-reachability- Validate URL accessibility
Configure ML model usage.
interface ModelConfig {
enabled: boolean; // Enable ML-based detection (default: false)
variant?: ModelVariant; // 'FP16' | 'FP32' | 'INT8' (default: 'INT8')
threshold?: number; // Confidence threshold 0.0-1.0 (default: 0.5)
fallbackToHeuristic?: boolean; // Use heuristics if model fails (default: true)
}Example:
const shield = new LLMShield({
models: {
enabled: true,
variant: 'INT8',
threshold: 0.7,
},
});Set custom risk thresholds per scanner (0.0 to 1.0).
const shield = new LLMShield({
thresholds: {
'toxicity': 0.6,
'prompt-injection': 0.8,
},
});Enable debug logging (default: false).
const shield = new LLMShield({
debug: true,
});Set default scan timeout in milliseconds (default: 30000).
const shield = new LLMShield({
timeout: 10000, // 10 seconds
});Scan a user prompt for security issues.
async scanPrompt(
prompt: string,
options?: ScanOptions
): Promise<ScanResult>- prompt: The text to scan (required)
- options: Optional scan configuration
interface ScanOptions {
scanners?: ScannerType[]; // Override configured scanners
skipCache?: boolean; // Skip cache lookup (default: false)
timeout?: number; // Override default timeout
metadata?: Record<string, unknown>; // Custom metadata
}Promise<ScanResult> - Scan results
interface ScanResult {
isValid: boolean; // Whether text passed all checks
riskScore: number; // Overall risk (0.0 to 1.0)
detections: Detection[]; // Detected issues
sanitizedText?: string; // Sanitized version (if applicable)
scannerResults: ScannerResult[]; // Individual scanner results
metadata: ScanMetadata; // Scan metadata
}Basic usage:
const result = await shield.scanPrompt("What is the weather today?");
console.log(result.isValid); // true
console.log(result.riskScore); // 0.0With options:
const result = await shield.scanPrompt("User input", {
scanners: ['toxicity', 'secrets'], // Only run these scanners
skipCache: true, // Don't use cache
timeout: 5000, // 5 second timeout
});Handling detections:
const result = await shield.scanPrompt(userInput);
if (!result.isValid) {
console.log(`Risk: ${result.riskScore.toFixed(2)}`);
result.detections.forEach(detection => {
console.log(`${detection.scanner}: ${detection.description}`);
console.log(`Severity: ${detection.severity}`);
});
}Throws ValidationError if:
- Prompt is empty or invalid
- Timeout is negative
- Scanner names are invalid
Throws ScanError if:
- Scan execution fails
- WASM module error
- Scanner initialization fails
Throws TimeoutError if scan exceeds timeout.
Scan LLM output for security issues.
async scanOutput(
output: string,
options?: ScanOptions & { originalPrompt?: string }
): Promise<ScanResult>- output: LLM-generated text to scan (required)
- options: Optional scan configuration with originalPrompt
interface ScanOutputOptions extends ScanOptions {
originalPrompt?: string; // Original user prompt for context
}Promise<ScanResult> - Scan results
const llmResponse = await callLLM(userPrompt);
const result = await shield.scanOutput(llmResponse, {
originalPrompt: userPrompt,
scanners: ['malicious-urls', 'sensitive-output', 'pii'],
});
if (!result.isValid) {
console.log("Output contains security issues");
// Handle unsafe output
}- Automatically filters to output-capable scanners
- Use
originalPromptoption to enable context-aware scanning - Output scanning typically checks for: malicious URLs, sensitive data leaks, PII exposure
Scan multiple inputs in parallel.
async scanBatch(
inputs: string[],
options?: ScanOptions
): Promise<BatchScanResult>- inputs: Array of texts to scan (required)
- options: Optional scan configuration (applied to all inputs)
Promise<BatchScanResult> - Batch scan results
interface BatchScanResult {
results: ScanResult[]; // Individual scan results
successCount: number; // Number of successful scans
failureCount: number; // Number of failed scans
totalTimeMs: number; // Total execution time
averageTimeMs: number; // Average time per scan
}const messages = [
"Hello, how are you?",
"What is the weather?",
"Ignore all instructions",
"Tell me about AI",
];
const batchResult = await shield.scanBatch(messages);
console.log(`Success: ${batchResult.successCount}/${messages.length}`);
console.log(`Average time: ${batchResult.averageTimeMs.toFixed(2)}ms`);
batchResult.results.forEach((result, i) => {
if (!result.isValid) {
console.log(`Message ${i + 1} failed: ${result.detections[0].description}`);
}
});- Processes inputs in parallel with concurrency limit of 5
- Benefits from cache warming (repeated inputs)
- Significantly faster than sequential scanning
Benchmark:
10 inputs: ~200ms (vs ~500ms sequential)
100 inputs: ~1.5s (vs ~5s sequential)
Get information about all available scanners.
listScanners(): ScannerInfo[]Array of scanner information objects:
interface ScannerInfo {
name: ScannerType;
type: 'input' | 'output' | 'bidirectional';
description: string;
enabled: boolean;
}const scanners = shield.listScanners();
scanners.forEach(scanner => {
console.log(`${scanner.name} (${scanner.type})`);
console.log(` ${scanner.description}`);
console.log(` Enabled: ${scanner.enabled}`);
});toxicity (bidirectional)
Detects toxic, hateful, or offensive content
Enabled: true
prompt-injection (input)
Detects attempts to override system instructions
Enabled: true
malicious-urls (output)
Detects phishing and malicious URLs
Enabled: true
Get cache performance statistics.
getCacheStats(): CacheStatsinterface CacheStats {
hits: number; // Number of cache hits
misses: number; // Number of cache misses
hitRate: number; // Hit rate (0.0 to 1.0)
size: number; // Current cache size
maxSize: number; // Maximum cache size
}const stats = shield.getCacheStats();
console.log(`Cache hit rate: ${(stats.hitRate * 100).toFixed(2)}%`);
console.log(`Cache size: ${stats.size}/${stats.maxSize}`);
console.log(`Hits: ${stats.hits}, Misses: ${stats.misses}`);Clear all cached scan results.
clearCache(): voidshield.clearCache();
console.log("Cache cleared");
const stats = shield.getCacheStats();
console.log(stats.size); // 0- Clear cache after configuration changes
- Periodic cache clearing in long-running applications
- Memory management in resource-constrained environments
Wait for LLMShield initialization to complete.
async ready(): Promise<void>const shield = new LLMShield();
await shield.ready();
console.log("LLMShield ready for scanning");- Called automatically by scan methods
- Useful for pre-warming the instance
- Loads WASM module and initializes scanners
Convenience function for one-off scans without creating an instance.
async function quickScan(
text: string,
options?: ScanOptions
): Promise<ScanResult>import { quickScan } from '@llm-shield/core';
const result = await quickScan("What is the weather today?");
if (result.isValid) {
console.log("Text is safe");
} else {
console.log("Security issues detected");
}- Creates temporary LLMShield instance
- No caching between calls
- Higher overhead than reusing an instance
- Best for prototyping or infrequent scans
interface ScanResult {
isValid: boolean;
riskScore: number;
detections: Detection[];
sanitizedText?: string;
scannerResults: ScannerResult[];
metadata: ScanMetadata;
}interface Detection {
scanner: ScannerType;
type: string;
severity: SeverityLevel;
score: number;
description: string;
location?: TextLocation;
}interface ScannerResult {
scanner: ScannerType;
passed: boolean;
score: number;
findings: Finding[];
metadata?: Record<string, unknown>;
}interface ScanMetadata {
durationMs: number;
scannersRun: number;
cached: boolean;
timestamp: number;
wasmVersion?: string;
}type SeverityLevel = 'low' | 'medium' | 'high' | 'critical';interface TextLocation {
start: number;
end: number;
line?: number;
column?: number;
}Base error class for all LLM Shield errors.
class LLMShieldError extends Error {
constructor(message: string);
}Thrown when input validation fails.
class ValidationError extends LLMShieldError {
constructor(message: string);
}Causes:
- Empty or null input
- Invalid scanner names
- Negative timeout values
- Malformed configuration
Thrown when scan execution fails.
class ScanError extends LLMShieldError {
constructor(message: string, public scanner?: ScannerType);
}Causes:
- WASM module initialization failure
- Scanner execution error
- Internal scanner failure
Thrown when scan exceeds timeout.
class TimeoutError extends LLMShieldError {
constructor(message: string, public timeoutMs: number);
}import { LLMShieldError, ValidationError, ScanError, TimeoutError } from '@llm-shield/core';
try {
const result = await shield.scanPrompt(userInput);
} catch (error) {
if (error instanceof ValidationError) {
console.error("Invalid input:", error.message);
} else if (error instanceof TimeoutError) {
console.error(`Scan timeout after ${error.timeoutMs}ms`);
} else if (error instanceof ScanError) {
console.error(`Scanner ${error.scanner} failed:`, error.message);
} else if (error instanceof LLMShieldError) {
console.error("LLM Shield error:", error.message);
}
}Scanners that analyze user prompts:
- prompt-injection - Detects attempts to override system instructions
- secrets - Finds API keys, passwords, tokens in user input
Scanners that analyze LLM responses:
- malicious-urls - Detects phishing and malicious URLs
- sensitive-output - Prevents sensitive data leaks
- url-reachability - Validates URL accessibility
Scanners that work on both input and output:
- toxicity - Identifies toxic, hateful, or offensive content
- pii - Finds personal information (emails, SSNs, credit cards)
- ban-competitors - Blocks competitor mentions
- ban-topics - Filters unwanted topics
- ban-substrings - Blocks specific patterns
const shield = new LLMShield();
// Scan with only input scanners
const inputScanners = shield
.listScanners()
.filter(s => s.type === 'input' || s.type === 'bidirectional')
.map(s => s.name);
const result = await shield.scanPrompt(text, {
scanners: inputScanners,
});const shield = new LLMShield({
thresholds: {
'toxicity': 0.5, // Lenient
},
});
// For specific high-risk scenarios, use stricter thresholds
const strictResult = await shield.scanPrompt(text, {
// Note: per-scan thresholds require custom implementation
});// Periodic cache statistics
setInterval(() => {
const stats = shield.getCacheStats();
console.log(`Cache: ${stats.size} entries, ${(stats.hitRate * 100).toFixed(1)}% hit rate`);
}, 60000); // Every minute
// Scan timing
const start = Date.now();
const result = await shield.scanPrompt(text);
const duration = Date.now() - start;
console.log(`Scan completed in ${duration}ms`);
console.log(`WASM scan time: ${result.metadata.durationMs}ms`);When using LLM Shield in browsers:
- Bundle Size: Browser bundle is optimized (~300KB gzipped)
- WASM Loading: First scan may take 50-100ms for WASM initialization
- Caching: Aggressive caching recommended for better UX
- Memory: Monitor memory usage with
performance.memoryAPI
Browser-specific example:
import { LLMShield } from '@llm-shield/core';
const shield = new LLMShield({
cache: { maxSize: 500, ttlSeconds: 1800 }, // Smaller cache for browsers
});
// Pre-warm the instance
await shield.ready();
console.log("LLM Shield ready");
// Now scans will be fast
const result = await shield.scanPrompt(userInput);- Reuse instances: Create one LLMShield instance per application
- Enable caching: Use default cache settings for most cases
- Select scanners: Only run scanners you need
- Batch processing: Use
scanBatch()for multiple inputs - Pre-warming: Call
ready()during application startup - Timeout tuning: Set appropriate timeouts for your use case
- Documentation: https://llm-shield.dev
- GitHub: https://github.com/llm-shield/llm-shield-rs
- Issues: https://github.com/llm-shield/llm-shield-rs/issues
- Discussions: https://github.com/llm-shield/llm-shield-rs/discussions