@philotheephilix/piifilter
v0.1.1
Published
Detect and mask PII in text before sending to LLMs, then reconstruct original values from responses.
Downloads
217
Maintainers
Readme
@philotheephilix/piifilter
Detect and mask PII (Personally Identifiable Information) in text before sending to LLMs, then reconstruct original values from responses. Zero dependencies.
Installation
npm install @philotheephilix/piifilterHow It Works
User text → filter() → sanitized text + sessionId
↓
Send to LLM (placeholders preserved)
↓
LLM response → reconstruct(sessionId, response) → original PII restoredPlaceholders use the format [TYPE_N] — e.g. [PAN_1], [PHONE_2], [EMAIL_3].
Quick Start
JavaScript (CommonJS)
const { PIIFilter } = require("@philotheephilix/piifilter");
const pf = new PIIFilter();
const [sanitized, sessionId] = pf.filter(
"My PAN is ABCDE1234F, email [email protected]"
);
console.log(sanitized);
// "My PAN is [PAN_1], email [EMAIL_2]"
// After getting LLM response with placeholders intact:
const restored = pf.reconstruct(sessionId, sanitized);
console.log(restored);
// "My PAN is ABCDE1234F, email [email protected]"
pf.clearSession(sessionId);TypeScript (ESM)
import { PIIFilter } from "@philotheephilix/piifilter";
const pf = new PIIFilter();
const [sanitized, sessionId] = pf.filter(
"My PAN is ABCDE1234F, call +919876543210"
);
console.log(sanitized);
// "My PAN is [PAN_1], call [PHONE_2]"
const restored = pf.reconstruct(sessionId, sanitized);
console.log(restored);
// "My PAN is ABCDE1234F, call +919876543210"Built-in Detectors
| Detector | Label | Formats |
|---|---|---|
| Credit Card | CREDIT_CARD | Visa, Mastercard, Amex, Discover (13-19 digits, Luhn validated). Supports spaces and dashes. |
| Phone | PHONE | Indian: +91, 091, bare 10-digit starting 6-9. International: +CC followed by 7-14 digits. |
| Aadhaar | AADHAAR | 12-digit Indian Aadhaar (first digit 2-9). Supports 2345 6789 0123 and 2345-6789-0123. |
| PAN Card | PAN | Indian PAN format: ABCDE1234F (5 letters + 4 digits + 1 letter, uppercase). |
| Driving License | DL | Indian DL: state code + RTO + year (19xx/20xx) + serial. e.g. MH-12-2010-0123456. |
| Email | EMAIL | Standard [email protected]. Supports ., +, %, - in local part. |
Usage
Select Specific Detectors
Only enable the detectors you need:
const { PIIFilter } = require("@philotheephilix/piifilter");
const pf = new PIIFilter({ detectors: ["PAN", "EMAIL"] });
console.log(pf.activeDetectors); // ["PAN", "EMAIL"]
const [sanitized] = pf.filter(
"PAN ABCDE1234F email [email protected] phone 9876543210"
);
console.log(sanitized);
// "PAN [PAN_1] email [EMAIL_2] phone 9876543210"
// Phone is NOT masked because PHONE detector was not enabledAvailable labels: CREDIT_CARD, PHONE, AADHAAR, PAN, DL, EMAIL.
Custom Patterns
Add your own regex-based detectors:
const pf = new PIIFilter({ includeAll: false });
pf.addCustomPattern("PASSPORT", "[A-Z]\\d{7}");
const [sanitized] = pf.filter("Passport: A1234567");
console.log(sanitized);
// "Passport: [PASSPORT_1]"With a validator function:
pf.addCustomPattern(
"PASSPORT",
"[A-Z]\\d{7}",
(match) => match.length === 8
);Custom Detector Class (TypeScript)
import { PIIFilter, CustomRegexDetector } from "@philotheephilix/piifilter";
const pf = new PIIFilter({ includeAll: false });
const detector = new CustomRegexDetector(
"SSN",
/\d{3}-\d{2}-\d{4}/g,
(match) => !match.startsWith("000")
);
pf.addDetector(detector);
const [sanitized] = pf.filter("SSN: 123-45-6789");
console.log(sanitized);
// "SSN: [SSN_1]"Append LLM Instruction
Automatically append an instruction telling the LLM to preserve placeholders:
const [sanitized] = pf.filter("My PAN is ABCDE1234F", true);
console.log(sanitized);
// My PAN is [PAN_1]
//
// ---
// IMPORTANT: The text above contains placeholders in the format [TYPE_N]
// (e.g. [PAN_1], [PHONE_2], [EMAIL_3]). These placeholders represent sensitive
// personal information that has been redacted. You MUST preserve every placeholder
// exactly as-is in your response. ...
// ---Or retrieve the instruction text directly:
const { PIIFilter } = require("@philotheephilix/piifilter");
const instruction = PIIFilter.getPromptInstruction();Session Cleanup
pf.clearSession(sessionId); // remove one session
pf.clearAllSessions(); // remove all sessionsFull Example: Express + OpenAI
const { PIIFilter } = require("@philotheephilix/piifilter");
const OpenAI = require("openai");
const express = require("express");
const app = express();
app.use(express.json());
const openai = new OpenAI();
const pf = new PIIFilter();
app.post("/chat", async (req, res) => {
const { message } = req.body;
// 1. Filter PII before sending to LLM
const [sanitized, sessionId] = pf.filter(message, true);
// 2. Send sanitized text to LLM
const completion = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: sanitized }],
});
const llmResponse = completion.choices[0].message.content;
// 3. Reconstruct original PII in LLM response
const restored = pf.reconstruct(sessionId, llmResponse);
// 4. Cleanup
pf.clearSession(sessionId);
res.json({ response: restored });
});
app.listen(3000);API Reference
new PIIFilter(options?)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| detectors | string[] | undefined | List of detector labels to enable. If omitted, behaviour depends on includeAll. |
| includeAll | boolean | true | When detectors is omitted, enables all built-in detectors. Set false for an empty filter. |
pf.filter(text, appendInstruction?): [string, string]
Returns [sanitizedText, sessionId]. Pass true for appendInstruction to add LLM placeholder-preservation instructions.
pf.reconstruct(sessionId, llmResponse): string
Replaces all [TYPE_N] placeholders in llmResponse with the original PII values from the session.
pf.addCustomPattern(label, pattern, validator?): void
Add a custom regex detector. pattern is a regex string. Optional validator function receives the matched text and returns true to accept.
pf.addDetector(detector): void
Add a PIIDetector instance (e.g. CustomRegexDetector).
pf.activeDetectors: string[]
List of active detector labels.
pf.clearSession(sessionId): void
Remove a single session.
pf.clearAllSessions(): void
Remove all sessions.
PIIFilter.getPromptInstruction(): string
Returns the LLM instruction text for placeholder preservation.
License
MIT
