@vpdeva/blackwall-llm-shield-js 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,7 +32,7 @@ npm install @xenova/transformers
32
32
  ## Fast Start
33
33
 
34
34
  ```js
35
- const { BlackwallShield } = require('blackwall-llm-shield-js');
35
+ const { BlackwallShield } = require('@vpdeva/blackwall-llm-shield-js');
36
36
 
37
37
  const shield = new BlackwallShield({
38
38
  blockOnPromptInjection: true,
@@ -95,9 +95,9 @@ Use `createExpressMiddleware()`, `createLangChainCallbacks()`, or `createLlamaIn
95
95
 
96
96
  ### Subpath modules
97
97
 
98
- Use `require('blackwall-llm-shield-js/integrations')` for callback wrappers and `require('blackwall-llm-shield-js/semantic')` for optional local semantic scoring adapters.
98
+ Use `require('@vpdeva/blackwall-llm-shield-js/integrations')` for callback wrappers and `require('@vpdeva/blackwall-llm-shield-js/semantic')` for optional local semantic scoring adapters.
99
99
 
100
- Use `require('blackwall-llm-shield-js/providers')` for provider adapter factories.
100
+ Use `require('@vpdeva/blackwall-llm-shield-js/providers')` for provider adapter factories.
101
101
 
102
102
  ## Core Building Blocks
103
103
 
@@ -151,7 +151,7 @@ if (!guarded.allowed) {
151
151
  ### Wrap a provider call end to end
152
152
 
153
153
  ```js
154
- const { BlackwallShield, createOpenAIAdapter } = require('blackwall-llm-shield-js');
154
+ const { BlackwallShield, createOpenAIAdapter } = require('@vpdeva/blackwall-llm-shield-js');
155
155
 
156
156
  const shield = new BlackwallShield({
157
157
  preset: 'shadowFirst',
@@ -234,15 +234,20 @@ const toolFirewall = new ToolPermissionFirewall({
234
234
  ### Operational telemetry summaries
235
235
 
236
236
  ```js
237
+ const { summarizeOperationalTelemetry } = require('@vpdeva/blackwall-llm-shield-js');
237
238
  const summary = summarizeOperationalTelemetry(events);
238
239
  console.log(summary.byRoute);
239
240
  console.log(summary.highestSeverity);
240
241
  ```
241
242
 
243
+ ### TypeScript
244
+
245
+ The package now ships first-class declaration files for the main entry point plus `integrations`, `providers`, and `semantic` subpaths, so local declaration shims should no longer be necessary in TypeScript apps.
246
+
242
247
  ### Inspect model output
243
248
 
244
249
  ```js
245
- const { OutputFirewall } = require('blackwall-llm-shield-js');
250
+ const { OutputFirewall } = require('@vpdeva/blackwall-llm-shield-js');
246
251
 
247
252
  const firewall = new OutputFirewall({
248
253
  riskThreshold: 'high',
@@ -259,7 +264,7 @@ console.log(review.allowed);
259
264
  ### Gate tool execution
260
265
 
261
266
  ```js
262
- const { ToolPermissionFirewall } = require('blackwall-llm-shield-js');
267
+ const { ToolPermissionFirewall } = require('@vpdeva/blackwall-llm-shield-js');
263
268
 
264
269
  const tools = new ToolPermissionFirewall({
265
270
  allowedTools: ['search', 'lookupCustomer'],
@@ -274,6 +279,8 @@ console.log(tools.inspectCall({ tool: 'lookupCustomer', args: { id: 'cus_123' }
274
279
  - [`examples/nextjs-app-router/app/api/chat/route.js`](/Users/vishnu/Documents/blackwall-llm-shield/blackwall-llm-shield-js/examples/nextjs-app-router/app/api/chat/route.js) shows guarded request handling in a Next.js route
275
280
  - [`examples/admin-dashboard/index.html`](/Users/vishnu/Documents/blackwall-llm-shield/blackwall-llm-shield-js/examples/admin-dashboard/index.html) shows a polished security command center demo
276
281
 
282
+ For Next.js, the most production-real patterns are App Router route handlers, server actions for trusted internal mutations, and streaming endpoints that apply output review to assembled or final chunks instead of raw intermediate tokens.
283
+
277
284
  ## Release Commands
278
285
 
279
286
  - `npm run release:check` runs the JS test suite before release
package/index.d.ts ADDED
@@ -0,0 +1,92 @@
1
+ export type RiskLevel = 'low' | 'medium' | 'high' | 'critical';
2
+
3
+ export interface MessagePart {
4
+ type: string;
5
+ text?: string;
6
+ image_url?: string;
7
+ file_id?: string;
8
+ [key: string]: unknown;
9
+ }
10
+
11
+ export interface ShieldMessage {
12
+ role: 'system' | 'user' | 'assistant';
13
+ content: string | MessagePart[] | Record<string, unknown>;
14
+ trusted?: boolean;
15
+ contentParts?: MessagePart[];
16
+ }
17
+
18
+ export interface GuardResult {
19
+ allowed: boolean;
20
+ blocked: boolean;
21
+ reason: string | null;
22
+ messages: Array<ShieldMessage & { content: string; contentParts?: MessagePart[] }>;
23
+ report: Record<string, unknown>;
24
+ vault: Record<string, string>;
25
+ }
26
+
27
+ export interface ReviewResult {
28
+ allowed: boolean;
29
+ severity: RiskLevel;
30
+ findings: Array<Record<string, unknown>>;
31
+ report: Record<string, unknown>;
32
+ [key: string]: unknown;
33
+ }
34
+
35
+ export interface ProviderAdapter {
36
+ provider: string;
37
+ invoke(payload: { messages: ShieldMessage[]; metadata?: Record<string, unknown>; guard?: GuardResult }): Promise<unknown> | unknown;
38
+ extractOutput?(response: unknown, request?: GuardResult): unknown;
39
+ }
40
+
41
+ export interface ShieldOptions {
42
+ preset?: string | null;
43
+ policyPack?: string | null;
44
+ shadowMode?: boolean;
45
+ routePolicies?: Array<{ route: string | RegExp | ((route: string, metadata: Record<string, unknown>) => boolean); options: Record<string, unknown> }>;
46
+ customPromptDetectors?: Array<(payload: Record<string, unknown>) => Record<string, unknown> | Array<Record<string, unknown>> | null>;
47
+ onTelemetry?: (event: Record<string, unknown>) => void | Promise<void>;
48
+ [key: string]: unknown;
49
+ }
50
+
51
+ export class BlackwallShield {
52
+ constructor(options?: ShieldOptions);
53
+ inspectText(text: unknown): Record<string, unknown>;
54
+ guardModelRequest(input?: { messages?: ShieldMessage[]; metadata?: Record<string, unknown>; allowSystemMessages?: boolean; comparePolicyPacks?: string[] }): Promise<GuardResult>;
55
+ reviewModelResponse(input?: { output: unknown; metadata?: Record<string, unknown>; outputFirewall?: OutputFirewall | null; firewallOptions?: Record<string, unknown> }): Promise<ReviewResult>;
56
+ protectModelCall(input: Record<string, unknown>): Promise<Record<string, unknown>>;
57
+ protectWithAdapter(input: { adapter: ProviderAdapter; messages?: ShieldMessage[]; metadata?: Record<string, unknown>; allowSystemMessages?: boolean; comparePolicyPacks?: string[]; outputFirewall?: OutputFirewall | null; firewallOptions?: Record<string, unknown> }): Promise<Record<string, unknown>>;
58
+ }
59
+
60
+ export class OutputFirewall {
61
+ constructor(options?: Record<string, unknown>);
62
+ inspect(output: unknown, options?: Record<string, unknown>): ReviewResult;
63
+ }
64
+
65
+ export class ToolPermissionFirewall {
66
+ constructor(options?: Record<string, unknown>);
67
+ inspectCall(input: Record<string, unknown>): Record<string, unknown>;
68
+ inspectCallAsync?(input: Record<string, unknown>): Promise<Record<string, unknown>>;
69
+ }
70
+
71
+ export class RetrievalSanitizer {
72
+ constructor(options?: Record<string, unknown>);
73
+ sanitizeDocuments(documents: Array<Record<string, unknown>>): Array<Record<string, unknown>>;
74
+ }
75
+
76
+ export class AuditTrail {
77
+ constructor(options?: Record<string, unknown>);
78
+ record(event?: Record<string, unknown>): Record<string, unknown>;
79
+ summarize(): Record<string, unknown>;
80
+ }
81
+
82
+ export const SHIELD_PRESETS: Record<string, Record<string, unknown>>;
83
+ export const CORE_INTERFACES: Record<string, string>;
84
+ export const POLICY_PACKS: Record<string, Record<string, unknown>>;
85
+
86
+ export function buildShieldOptions(options?: Record<string, unknown>): Record<string, unknown>;
87
+ export function summarizeOperationalTelemetry(events?: Array<Record<string, unknown>>): Record<string, unknown>;
88
+
89
+ export function createOpenAIAdapter(input: Record<string, unknown>): ProviderAdapter;
90
+ export function createAnthropicAdapter(input: Record<string, unknown>): ProviderAdapter;
91
+ export function createGeminiAdapter(input: Record<string, unknown>): ProviderAdapter;
92
+ export function createOpenRouterAdapter(input: Record<string, unknown>): ProviderAdapter;
@@ -0,0 +1,18 @@
1
+ export { BlackwallShield, OutputFirewall, type ProviderAdapter } from './index';
2
+
3
+ export class BlackwallLangChainCallback {
4
+ constructor(options?: Record<string, unknown>);
5
+ handleLLMStart(llm: unknown, prompts?: string[]): Promise<unknown>;
6
+ guardMessages(messages: unknown, metadata?: Record<string, unknown>): Promise<unknown>;
7
+ handleLLMEnd(output: unknown): Promise<unknown>;
8
+ }
9
+
10
+ export class BlackwallLlamaIndexCallback {
11
+ constructor(options?: Record<string, unknown>);
12
+ onEventStart(event: unknown): Promise<unknown>;
13
+ onEventEnd(event: unknown): Promise<unknown>;
14
+ }
15
+
16
+ export function createExpressMiddleware(options?: Record<string, unknown>): (req: unknown, res: unknown, next: () => void) => Promise<void>;
17
+ export function createLangChainCallbacks(options?: Record<string, unknown>): Record<string, unknown>;
18
+ export function createLlamaIndexCallback(options?: Record<string, unknown>): Record<string, unknown>;
package/package.json CHANGED
@@ -1,16 +1,29 @@
1
1
  {
2
2
  "name": "@vpdeva/blackwall-llm-shield-js",
3
- "version": "0.1.5",
3
+ "version": "0.1.6",
4
4
  "description": "Open-source JavaScript enterprise LLM protection toolkit for Node.js and Next.js",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Vish <hello@vish.au> (https://vish.au)",
7
7
  "type": "commonjs",
8
8
  "main": "src/index.js",
9
+ "types": "./index.d.ts",
9
10
  "exports": {
10
- ".": "./src/index.js",
11
- "./integrations": "./src/integrations.js",
12
- "./providers": "./src/providers.js",
13
- "./semantic": "./src/semantic.js"
11
+ ".": {
12
+ "types": "./index.d.ts",
13
+ "default": "./src/index.js"
14
+ },
15
+ "./integrations": {
16
+ "types": "./integrations.d.ts",
17
+ "default": "./src/integrations.js"
18
+ },
19
+ "./providers": {
20
+ "types": "./providers.d.ts",
21
+ "default": "./src/providers.js"
22
+ },
23
+ "./semantic": {
24
+ "types": "./semantic.d.ts",
25
+ "default": "./src/semantic.js"
26
+ }
14
27
  },
15
28
  "bin": {
16
29
  "blackwall-scorecard": "src/scorecard.js"
@@ -26,6 +39,10 @@
26
39
  },
27
40
  "files": [
28
41
  "src",
42
+ "index.d.ts",
43
+ "integrations.d.ts",
44
+ "providers.d.ts",
45
+ "semantic.d.ts",
29
46
  "README.md",
30
47
  "LICENSE",
31
48
  "NOTICE"
package/providers.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export type { ProviderAdapter } from './index';
2
+
3
+ export function createOpenAIAdapter(input: Record<string, unknown>): import('./index').ProviderAdapter;
4
+ export function createAnthropicAdapter(input: Record<string, unknown>): import('./index').ProviderAdapter;
5
+ export function createGeminiAdapter(input: Record<string, unknown>): import('./index').ProviderAdapter;
6
+ export function createOpenRouterAdapter(input: Record<string, unknown>): import('./index').ProviderAdapter;
package/semantic.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export class LightweightIntentScorer {
2
+ constructor(options?: Record<string, unknown>);
3
+ score(text: unknown, options?: Record<string, unknown>): Record<string, unknown>;
4
+ }
package/src/index.js CHANGED
@@ -350,21 +350,46 @@ function summarizeOperationalTelemetry(events = []) {
350
350
  shadowModeEvents: 0,
351
351
  byType: {},
352
352
  byRoute: {},
353
+ byTenant: {},
354
+ byModel: {},
355
+ byPolicyOutcome: {
356
+ blocked: 0,
357
+ shadowBlocked: 0,
358
+ allowed: 0,
359
+ },
360
+ topRules: {},
353
361
  highestSeverity: 'low',
354
362
  };
355
363
  for (const event of Array.isArray(events) ? events : []) {
356
364
  const type = event && event.type ? event.type : 'unknown';
357
- const route = event && event.metadata && (event.metadata.route || event.metadata.path) ? (event.metadata.route || event.metadata.path) : 'unknown';
365
+ const metadata = event && event.metadata ? event.metadata : {};
366
+ const route = metadata.route || metadata.path || 'unknown';
367
+ const tenant = metadata.tenantId || metadata.tenant_id || 'unknown';
368
+ const model = metadata.model || metadata.modelName || 'unknown';
358
369
  const severity = event && event.report && event.report.outputReview
359
370
  ? event.report.outputReview.severity
360
371
  : (event && event.report && event.report.promptInjection ? event.report.promptInjection.level : 'low');
361
372
  summary.totalEvents += 1;
362
373
  summary.byType[type] = (summary.byType[type] || 0) + 1;
363
374
  summary.byRoute[route] = (summary.byRoute[route] || 0) + 1;
375
+ summary.byTenant[tenant] = (summary.byTenant[tenant] || 0) + 1;
376
+ summary.byModel[model] = (summary.byModel[model] || 0) + 1;
364
377
  if (event && event.blocked) summary.blockedEvents += 1;
365
378
  if (event && event.shadowMode) summary.shadowModeEvents += 1;
379
+ if (event && event.blocked) summary.byPolicyOutcome.blocked += 1;
380
+ else if (event && event.shadowMode) summary.byPolicyOutcome.shadowBlocked += 1;
381
+ else summary.byPolicyOutcome.allowed += 1;
382
+ const rules = event && event.report && event.report.promptInjection && Array.isArray(event.report.promptInjection.matches)
383
+ ? event.report.promptInjection.matches.map((item) => item.id).filter(Boolean)
384
+ : [];
385
+ rules.forEach((rule) => {
386
+ summary.topRules[rule] = (summary.topRules[rule] || 0) + 1;
387
+ });
366
388
  if (severityWeight(severity) > severityWeight(summary.highestSeverity)) summary.highestSeverity = severity;
367
389
  }
390
+ summary.topRules = Object.fromEntries(
391
+ Object.entries(summary.topRules).sort((a, b) => b[1] - a[1]).slice(0, 10)
392
+ );
368
393
  return summary;
369
394
  }
370
395