UNPKG

@ethicalzen/sdk

Version:

Official EthicalZen SDK for Node.js - AI safety guardrails made simple

170 lines (169 loc) 6.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EthicalZenMiddleware = EthicalZenMiddleware; exports.enforceRoute = enforceRoute; const client_1 = require("./client"); /** * Express middleware for automatic EthicalZen enforcement * * @param config - Middleware configuration * @returns Express middleware function * * @example * ```typescript * import { EthicalZenMiddleware } from '@ethicalzen/sdk'; * * app.use(EthicalZenMiddleware({ * apiKey: process.env.ETHICALZEN_API_KEY, * contractId: 'chatbot/general/us/v1.0', * enforceOn: 'response' * })); * * app.post('/chat', async (req, res) => { * const response = await generateAIResponse(req.body); * res.json({ message: response }); // Automatically validated! * }); * ``` */ function EthicalZenMiddleware(config) { const client = new client_1.EthicalZenClient({ apiKey: config.apiKey, tenantId: config.tenantId, baseURL: config.baseURL, timeout: config.timeout }); const enforceOn = config.enforceOn || 'response'; const failureMode = config.failureMode || 'block'; return async (req, res, next) => { // Enforce on request (validate input) if (enforceOn === 'request' || enforceOn === 'both') { try { const payload = config.extractPayload ? config.extractPayload(req, res) : { input: req.body }; const result = await client.enforce({ contractId: config.contractId, payload, metadata: { method: req.method, path: req.path, timestamp: new Date().toISOString() } }); if (!result.passed) { // Handle violation if (config.onViolation) { config.onViolation(result, req, res); return; } if (failureMode === 'block') { return res.status(400).json({ error: 'Safety violation detected', violations: result.violations, contractId: result.contractId }); } else if (failureMode === 'log') { console.warn('[EthicalZen] Request violations detected:', result.violations); // Continue to next middleware } } } catch (error) { console.error('[EthicalZen] Request enforcement error:', error); if (failureMode === 'block') { return res.status(500).json({ error: 'Safety check failed', message: 'Unable to validate request safety' }); } } } // Enforce on response (validate output) if (enforceOn === 'response' || enforceOn === 'both') { // Intercept res.json to validate AI output const originalJson = res.json.bind(res); res.json = function (body) { (async () => { try { const payload = config.extractPayload ? config.extractPayload(req, res) : { output: body }; const result = await client.enforce({ contractId: config.contractId, payload, metadata: { method: req.method, path: req.path, statusCode: res.statusCode, timestamp: new Date().toISOString() } }); if (!result.passed) { // Handle violation if (config.onViolation) { config.onViolation(result, req, res); return; } if (failureMode === 'block') { res.status(400); originalJson.call(res, { error: 'Safety violation detected', violations: result.violations, contractId: result.contractId }); return; } else if (failureMode === 'log') { console.warn('[EthicalZen] Response violations detected:', result.violations); // Return original response } } // No violations or failureMode=pass, return original response originalJson.call(res, body); } catch (error) { console.error('[EthicalZen] Response enforcement error:', error); if (failureMode === 'block') { res.status(500); originalJson.call(res, { error: 'Safety check failed', message: 'Unable to validate response safety' }); return; } // If log or pass mode, return original response originalJson.call(res, body); } })(); return res; }; } next(); }; } /** * Route-specific middleware for selective enforcement * * @param config - Middleware configuration * @returns Express middleware function * * @example * ```typescript * import { enforceRoute } from '@ethicalzen/sdk'; * * app.post('/chat', * enforceRoute({ * apiKey: process.env.ETHICALZEN_API_KEY, * contractId: 'chatbot/general/us/v1.0' * }), * async (req, res) => { * const response = await generateAIResponse(req.body); * res.json({ message: response }); * } * ); * ``` */ function enforceRoute(config) { return EthicalZenMiddleware(config); }