ai.matey.middleware 0.2.0
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/LICENSE +21 -0
- package/dist/cjs/caching.js +226 -0
- package/dist/cjs/caching.js.map +1 -0
- package/dist/cjs/conversation-history.js +213 -0
- package/dist/cjs/conversation-history.js.map +1 -0
- package/dist/cjs/cost-tracking.js +355 -0
- package/dist/cjs/cost-tracking.js.map +1 -0
- package/dist/cjs/index.js +37 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/logging.js +174 -0
- package/dist/cjs/logging.js.map +1 -0
- package/dist/cjs/opentelemetry.js +499 -0
- package/dist/cjs/opentelemetry.js.map +1 -0
- package/dist/cjs/retry.js +205 -0
- package/dist/cjs/retry.js.map +1 -0
- package/dist/cjs/security.js +175 -0
- package/dist/cjs/security.js.map +1 -0
- package/dist/cjs/telemetry.js +216 -0
- package/dist/cjs/telemetry.js.map +1 -0
- package/dist/cjs/transform.js +284 -0
- package/dist/cjs/transform.js.map +1 -0
- package/dist/cjs/validation.js +506 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/caching.js +221 -0
- package/dist/esm/caching.js.map +1 -0
- package/dist/esm/conversation-history.js +207 -0
- package/dist/esm/conversation-history.js.map +1 -0
- package/dist/esm/cost-tracking.js +347 -0
- package/dist/esm/cost-tracking.js.map +1 -0
- package/dist/esm/index.js +21 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logging.js +171 -0
- package/dist/esm/logging.js.map +1 -0
- package/dist/esm/opentelemetry.js +458 -0
- package/dist/esm/opentelemetry.js.map +1 -0
- package/dist/esm/retry.js +198 -0
- package/dist/esm/retry.js.map +1 -0
- package/dist/esm/security.js +169 -0
- package/dist/esm/security.js.map +1 -0
- package/dist/esm/telemetry.js +210 -0
- package/dist/esm/telemetry.js.map +1 -0
- package/dist/esm/transform.js +272 -0
- package/dist/esm/transform.js.map +1 -0
- package/dist/esm/validation.js +494 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/types/caching.d.ts +98 -0
- package/dist/types/caching.d.ts.map +1 -0
- package/dist/types/conversation-history.d.ts +188 -0
- package/dist/types/conversation-history.d.ts.map +1 -0
- package/dist/types/cost-tracking.d.ts +262 -0
- package/dist/types/cost-tracking.d.ts.map +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/logging.d.ts +82 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/opentelemetry.d.ts +219 -0
- package/dist/types/opentelemetry.d.ts.map +1 -0
- package/dist/types/retry.d.ts +86 -0
- package/dist/types/retry.d.ts.map +1 -0
- package/dist/types/security.d.ts +120 -0
- package/dist/types/security.d.ts.map +1 -0
- package/dist/types/telemetry.d.ts +120 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/transform.d.ts +184 -0
- package/dist/types/transform.d.ts.map +1 -0
- package/dist/types/validation.d.ts +356 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/package.json +203 -0
- package/readme.md +103 -0
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input Validation & Sanitization Middleware
|
|
3
|
+
*
|
|
4
|
+
* Validates and sanitizes requests to prevent security issues and ensure data quality.
|
|
5
|
+
*
|
|
6
|
+
* ## Separation of Concerns
|
|
7
|
+
*
|
|
8
|
+
* This middleware focuses on **SECURITY validation**:
|
|
9
|
+
* - PII detection and redaction
|
|
10
|
+
* - Prompt injection prevention
|
|
11
|
+
* - Content moderation
|
|
12
|
+
* - Message length/token limits
|
|
13
|
+
* - Sanitization
|
|
14
|
+
*
|
|
15
|
+
* For **IR format validation** (structural correctness), use ai.matey.utils/validation.ts:
|
|
16
|
+
* - Message structure and content validation
|
|
17
|
+
* - Parameter type and range validation
|
|
18
|
+
* - Request format validation
|
|
19
|
+
*
|
|
20
|
+
* @module
|
|
21
|
+
*/
|
|
22
|
+
import { ValidationError, ErrorCode } from 'ai.matey.errors';
|
|
23
|
+
import { validateIRChatRequest, validateTemperature } from 'ai.matey.utils';
|
|
24
|
+
/**
|
|
25
|
+
* Helper to create a structured validation error from simple field/value/message
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
function createValidationError(message, field, value, provenance) {
|
|
29
|
+
return new ValidationError({
|
|
30
|
+
code: ErrorCode.INVALID_REQUEST,
|
|
31
|
+
message,
|
|
32
|
+
validationDetails: [
|
|
33
|
+
{
|
|
34
|
+
field,
|
|
35
|
+
value,
|
|
36
|
+
reason: message,
|
|
37
|
+
expected: 'Valid value',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
provenance,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Default PII patterns
|
|
45
|
+
*/
|
|
46
|
+
export const DEFAULT_PII_PATTERNS = {
|
|
47
|
+
// Email addresses
|
|
48
|
+
email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
49
|
+
// US Social Security Numbers
|
|
50
|
+
ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
51
|
+
// Credit card numbers (basic pattern)
|
|
52
|
+
creditCard: /\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b/g,
|
|
53
|
+
// US Phone numbers
|
|
54
|
+
phone: /\b(\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g,
|
|
55
|
+
// IP addresses
|
|
56
|
+
ipAddress: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
|
|
57
|
+
// API keys (common patterns)
|
|
58
|
+
apiKey: /\b[A-Za-z0-9]{32,}\b/g,
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Default prompt injection patterns
|
|
62
|
+
*/
|
|
63
|
+
export const DEFAULT_INJECTION_PATTERNS = [
|
|
64
|
+
// Ignore previous instructions
|
|
65
|
+
/ignore\s+(previous|above|all)\s+(instructions|prompts?|commands?)/i,
|
|
66
|
+
// System prompt manipulation
|
|
67
|
+
/system\s*:\s*new\s+(instruction|prompt|role)/i,
|
|
68
|
+
// Jailbreak attempts
|
|
69
|
+
/\b(jailbreak|DAN|developer\s+mode)\b/i,
|
|
70
|
+
// Role manipulation
|
|
71
|
+
/(you\s+are\s+now|act\s+as\s+if\s+you\s+are)\s+a\s+/i,
|
|
72
|
+
// Instruction override
|
|
73
|
+
/disregard\s+(all|any|previous|above)/i,
|
|
74
|
+
];
|
|
75
|
+
/**
|
|
76
|
+
* Detect PII in text
|
|
77
|
+
*/
|
|
78
|
+
export function detectPII(text, patterns = DEFAULT_PII_PATTERNS) {
|
|
79
|
+
const matches = [];
|
|
80
|
+
const types = [];
|
|
81
|
+
for (const [type, pattern] of Object.entries(patterns)) {
|
|
82
|
+
const found = text.match(pattern);
|
|
83
|
+
if (found && found.length > 0) {
|
|
84
|
+
types.push(type);
|
|
85
|
+
for (const value of found) {
|
|
86
|
+
matches.push({ type, value });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
detected: matches.length > 0,
|
|
92
|
+
types: Array.from(new Set(types)),
|
|
93
|
+
matches,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Redact PII from text
|
|
98
|
+
*/
|
|
99
|
+
export function redactPII(text, patterns = DEFAULT_PII_PATTERNS) {
|
|
100
|
+
let redacted = text;
|
|
101
|
+
for (const [type, pattern] of Object.entries(patterns)) {
|
|
102
|
+
redacted = redacted.replace(pattern, `[REDACTED_${type.toUpperCase()}]`);
|
|
103
|
+
}
|
|
104
|
+
return redacted;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detect prompt injection attempts
|
|
108
|
+
*/
|
|
109
|
+
export function detectPromptInjection(text, patterns = DEFAULT_INJECTION_PATTERNS) {
|
|
110
|
+
return patterns.some((pattern) => pattern.test(text));
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Sanitize text content
|
|
114
|
+
*/
|
|
115
|
+
export function sanitizeText(text) {
|
|
116
|
+
// Remove null bytes
|
|
117
|
+
let sanitized = text.replace(/\0/g, '');
|
|
118
|
+
// Normalize whitespace (but preserve intentional formatting)
|
|
119
|
+
sanitized = sanitized.replace(/\r\n/g, '\n');
|
|
120
|
+
// Remove invisible characters (zero-width, etc.)
|
|
121
|
+
sanitized = sanitized.replace(/[\u200B-\u200D\uFEFF]/g, '');
|
|
122
|
+
return sanitized;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Estimate token count (rough approximation)
|
|
126
|
+
*/
|
|
127
|
+
function estimateTokens(text) {
|
|
128
|
+
// Rough estimate: ~4 characters per token
|
|
129
|
+
return Math.ceil(text.length / 4);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract text from message content
|
|
133
|
+
*/
|
|
134
|
+
function extractText(content) {
|
|
135
|
+
if (typeof content === 'string') {
|
|
136
|
+
return content;
|
|
137
|
+
}
|
|
138
|
+
return content
|
|
139
|
+
.filter((c) => c.type === 'text')
|
|
140
|
+
.map((c) => c.text)
|
|
141
|
+
.join('\n');
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Validate request
|
|
145
|
+
*/
|
|
146
|
+
export async function validateRequest(request, config) {
|
|
147
|
+
const errors = [];
|
|
148
|
+
const warnings = [];
|
|
149
|
+
// Perform IR format validation first if enabled
|
|
150
|
+
if (config.validateIRFormat) {
|
|
151
|
+
try {
|
|
152
|
+
validateIRChatRequest(request);
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
if (error instanceof ValidationError) {
|
|
156
|
+
errors.push(error);
|
|
157
|
+
// If format validation fails, return early as security checks may not make sense
|
|
158
|
+
return { valid: false, errors, warnings };
|
|
159
|
+
}
|
|
160
|
+
throw error;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Validate message count
|
|
164
|
+
if (config.maxMessages && request.messages.length > config.maxMessages) {
|
|
165
|
+
errors.push(createValidationError(`Too many messages: ${request.messages.length} > ${config.maxMessages}`, 'messages', request.messages.length));
|
|
166
|
+
}
|
|
167
|
+
// Validate messages
|
|
168
|
+
let totalTokens = 0;
|
|
169
|
+
const messagesArray = Array.from(request.messages);
|
|
170
|
+
for (let i = 0; i < messagesArray.length; i++) {
|
|
171
|
+
const message = messagesArray[i];
|
|
172
|
+
if (!message) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
// Check allowed roles
|
|
176
|
+
if (config.allowedRoles &&
|
|
177
|
+
!config.allowedRoles.includes(message.role)) {
|
|
178
|
+
errors.push(createValidationError(`Invalid message role: ${message.role}`, `messages[${i}].role`, message.role));
|
|
179
|
+
}
|
|
180
|
+
// Extract text
|
|
181
|
+
const text = extractText(message.content);
|
|
182
|
+
// Check empty messages
|
|
183
|
+
if (config.blockEmptyMessages !== false && text.trim().length === 0) {
|
|
184
|
+
errors.push(createValidationError(`Empty message at index ${i}`, `messages[${i}].content`, text));
|
|
185
|
+
}
|
|
186
|
+
// Check message length
|
|
187
|
+
if (config.maxMessageLength && text.length > config.maxMessageLength) {
|
|
188
|
+
errors.push(createValidationError(`Message too long: ${text.length} > ${config.maxMessageLength}`, `messages[${i}].content`, text.length));
|
|
189
|
+
}
|
|
190
|
+
// Estimate tokens
|
|
191
|
+
const tokens = estimateTokens(text);
|
|
192
|
+
totalTokens += tokens;
|
|
193
|
+
// Check tokens per message
|
|
194
|
+
if (config.maxTokensPerMessage && tokens > config.maxTokensPerMessage) {
|
|
195
|
+
errors.push(createValidationError(`Message tokens exceed limit: ${tokens} > ${config.maxTokensPerMessage}`, `messages[${i}].content`, tokens));
|
|
196
|
+
}
|
|
197
|
+
// Detect PII
|
|
198
|
+
if (config.detectPII) {
|
|
199
|
+
const piiResult = config.piiDetector
|
|
200
|
+
? await config.piiDetector(text)
|
|
201
|
+
: detectPII(text, config.piiPatterns);
|
|
202
|
+
if (piiResult.detected) {
|
|
203
|
+
const message = `PII detected in message ${i}: ${piiResult.types.join(', ')}`;
|
|
204
|
+
if (config.piiAction === 'block') {
|
|
205
|
+
errors.push(createValidationError(message, `messages[${i}].content`, piiResult));
|
|
206
|
+
}
|
|
207
|
+
else if (config.piiAction === 'warn' || config.piiAction === 'log') {
|
|
208
|
+
warnings.push(message);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Detect prompt injection
|
|
213
|
+
if (config.preventPromptInjection !== false) {
|
|
214
|
+
const hasInjection = detectPromptInjection(text, config.injectionPatterns);
|
|
215
|
+
if (hasInjection) {
|
|
216
|
+
errors.push(createValidationError(`Potential prompt injection detected in message ${i}`, `messages[${i}].content`, text));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Content moderation
|
|
220
|
+
if (config.moderationCallback) {
|
|
221
|
+
const modResult = await config.moderationCallback(text);
|
|
222
|
+
if (modResult.flagged) {
|
|
223
|
+
const message = `Content flagged by moderation in message ${i}: ${modResult.categories.join(', ')}`;
|
|
224
|
+
if (config.blockFlaggedContent) {
|
|
225
|
+
errors.push(createValidationError(message, `messages[${i}].content`, modResult));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
warnings.push(message);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
// Check total tokens
|
|
234
|
+
if (config.maxTotalTokens && totalTokens > config.maxTotalTokens) {
|
|
235
|
+
errors.push(createValidationError(`Total tokens exceed limit: ${totalTokens} > ${config.maxTotalTokens}`, 'messages', totalTokens));
|
|
236
|
+
}
|
|
237
|
+
// Validate model
|
|
238
|
+
if (config.validateModel && request.parameters?.model) {
|
|
239
|
+
if (config.allowedModels && !config.allowedModels.includes(request.parameters.model)) {
|
|
240
|
+
errors.push(createValidationError(`Model not allowed: ${request.parameters.model}`, 'parameters.model', request.parameters.model));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Validate temperature (deprecated - use validateIRFormat instead)
|
|
244
|
+
if (config.validateTemperature && request.parameters?.temperature !== undefined) {
|
|
245
|
+
try {
|
|
246
|
+
validateTemperature(request.parameters.temperature);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
if (error instanceof ValidationError) {
|
|
250
|
+
errors.push(error);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// Custom validation
|
|
258
|
+
if (config.customValidator) {
|
|
259
|
+
const customErrors = await config.customValidator(request);
|
|
260
|
+
errors.push(...customErrors);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
valid: errors.length === 0,
|
|
264
|
+
errors,
|
|
265
|
+
warnings,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Sanitize request
|
|
270
|
+
*/
|
|
271
|
+
export function sanitizeRequest(request, config) {
|
|
272
|
+
if (config.sanitizeMessages === false) {
|
|
273
|
+
return request;
|
|
274
|
+
}
|
|
275
|
+
const sanitizer = config.sanitizer || sanitizeText;
|
|
276
|
+
// Sanitize messages
|
|
277
|
+
const sanitizedMessages = request.messages.map((message) => {
|
|
278
|
+
if (typeof message.content === 'string') {
|
|
279
|
+
return {
|
|
280
|
+
...message,
|
|
281
|
+
content: sanitizer(message.content),
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
...message,
|
|
286
|
+
content: message.content.map((content) => {
|
|
287
|
+
if (content.type === 'text') {
|
|
288
|
+
return {
|
|
289
|
+
...content,
|
|
290
|
+
text: sanitizer(content.text),
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
return content;
|
|
294
|
+
}),
|
|
295
|
+
};
|
|
296
|
+
});
|
|
297
|
+
// Redact PII if configured
|
|
298
|
+
if (config.detectPII && config.piiAction === 'redact') {
|
|
299
|
+
const patterns = config.piiPatterns || DEFAULT_PII_PATTERNS;
|
|
300
|
+
return {
|
|
301
|
+
...request,
|
|
302
|
+
messages: sanitizedMessages.map((message) => {
|
|
303
|
+
if (typeof message.content === 'string') {
|
|
304
|
+
return {
|
|
305
|
+
...message,
|
|
306
|
+
content: redactPII(message.content, patterns),
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
...message,
|
|
311
|
+
content: message.content.map((content) => {
|
|
312
|
+
if (content.type === 'text') {
|
|
313
|
+
return {
|
|
314
|
+
...content,
|
|
315
|
+
text: redactPII(content.text, patterns),
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
return content;
|
|
319
|
+
}),
|
|
320
|
+
};
|
|
321
|
+
}),
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
...request,
|
|
326
|
+
messages: sanitizedMessages,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Create input validation middleware
|
|
331
|
+
*
|
|
332
|
+
* Validates and sanitizes requests to prevent security issues and ensure data quality.
|
|
333
|
+
*
|
|
334
|
+
* @param config - Validation configuration
|
|
335
|
+
* @returns Middleware function
|
|
336
|
+
*
|
|
337
|
+
* @example Basic Usage
|
|
338
|
+
* ```typescript
|
|
339
|
+
* import { createValidationMiddleware } from 'ai.matey';
|
|
340
|
+
*
|
|
341
|
+
* const validation = createValidationMiddleware({
|
|
342
|
+
* maxMessages: 100,
|
|
343
|
+
* maxTotalTokens: 128000,
|
|
344
|
+
* preventPromptInjection: true,
|
|
345
|
+
* });
|
|
346
|
+
*
|
|
347
|
+
* bridge.use(validation);
|
|
348
|
+
* ```
|
|
349
|
+
*
|
|
350
|
+
* @example PII Detection & Redaction
|
|
351
|
+
* ```typescript
|
|
352
|
+
* const validation = createValidationMiddleware({
|
|
353
|
+
* detectPII: true,
|
|
354
|
+
* piiAction: 'redact', // or 'block', 'warn', 'log'
|
|
355
|
+
* piiPatterns: {
|
|
356
|
+
* email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
|
|
357
|
+
* ssn: /\b\d{3}-\d{2}-\d{4}\b/g,
|
|
358
|
+
* },
|
|
359
|
+
* });
|
|
360
|
+
* ```
|
|
361
|
+
*
|
|
362
|
+
* @example Content Moderation
|
|
363
|
+
* ```typescript
|
|
364
|
+
* const validation = createValidationMiddleware({
|
|
365
|
+
* moderationCallback: async (content) => {
|
|
366
|
+
* // Call external moderation API
|
|
367
|
+
* const result = await moderationAPI.check(content);
|
|
368
|
+
* return {
|
|
369
|
+
* flagged: result.flagged,
|
|
370
|
+
* categories: result.categories,
|
|
371
|
+
* scores: result.scores,
|
|
372
|
+
* };
|
|
373
|
+
* },
|
|
374
|
+
* blockFlaggedContent: true,
|
|
375
|
+
* });
|
|
376
|
+
* ```
|
|
377
|
+
*
|
|
378
|
+
* @example Custom Validation
|
|
379
|
+
* ```typescript
|
|
380
|
+
* const validation = createValidationMiddleware({
|
|
381
|
+
* customValidator: async (request) => {
|
|
382
|
+
* const errors: ValidationError[] = [];
|
|
383
|
+
*
|
|
384
|
+
* // Custom business logic
|
|
385
|
+
* if (request.messages.some(m => m.content.includes('forbidden'))) {
|
|
386
|
+
* errors.push(new ValidationError(
|
|
387
|
+
* 'Forbidden content detected',
|
|
388
|
+
* 'messages',
|
|
389
|
+
* 'forbidden'
|
|
390
|
+
* ));
|
|
391
|
+
* }
|
|
392
|
+
*
|
|
393
|
+
* return errors;
|
|
394
|
+
* },
|
|
395
|
+
* });
|
|
396
|
+
* ```
|
|
397
|
+
*
|
|
398
|
+
* @example Production Configuration
|
|
399
|
+
* ```typescript
|
|
400
|
+
* const validation = createValidationMiddleware({
|
|
401
|
+
* maxMessages: 100,
|
|
402
|
+
* maxTotalTokens: 128000,
|
|
403
|
+
* maxTokensPerMessage: 32000,
|
|
404
|
+
* maxMessageLength: 100000,
|
|
405
|
+
* blockEmptyMessages: true,
|
|
406
|
+
* detectPII: true,
|
|
407
|
+
* piiAction: 'redact',
|
|
408
|
+
* preventPromptInjection: true,
|
|
409
|
+
* sanitizeMessages: true,
|
|
410
|
+
* validateModel: true,
|
|
411
|
+
* allowedModels: ['gpt-4', 'claude-3-sonnet', 'gemini-pro'],
|
|
412
|
+
* validateTemperature: true,
|
|
413
|
+
* temperatureRange: [0, 2],
|
|
414
|
+
* throwOnError: true,
|
|
415
|
+
* logWarnings: true,
|
|
416
|
+
* });
|
|
417
|
+
* ```
|
|
418
|
+
*/
|
|
419
|
+
export function createValidationMiddleware(config = {}) {
|
|
420
|
+
return async (context, next) => {
|
|
421
|
+
// Validate request
|
|
422
|
+
const validationResult = await validateRequest(context.request, config);
|
|
423
|
+
// Log warnings
|
|
424
|
+
if (config.logWarnings !== false && validationResult.warnings.length > 0) {
|
|
425
|
+
for (const warning of validationResult.warnings) {
|
|
426
|
+
console.warn(`[Validation] ${warning}`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
// Handle validation errors
|
|
430
|
+
if (!validationResult.valid) {
|
|
431
|
+
const errorMessage = validationResult.errors.map((e) => e.message).join('; ');
|
|
432
|
+
if (config.throwOnError !== false) {
|
|
433
|
+
throw createValidationError(`Validation failed: ${errorMessage}`, 'request', validationResult.errors);
|
|
434
|
+
}
|
|
435
|
+
// Log errors but continue
|
|
436
|
+
console.error(`[Validation] Errors: ${errorMessage}`);
|
|
437
|
+
}
|
|
438
|
+
// Sanitize request
|
|
439
|
+
context.request = sanitizeRequest(context.request, config);
|
|
440
|
+
// Continue to next middleware
|
|
441
|
+
return await next();
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Create production-ready validation middleware with strict settings
|
|
446
|
+
*
|
|
447
|
+
* @returns Middleware with production validation settings
|
|
448
|
+
*
|
|
449
|
+
* @example
|
|
450
|
+
* ```typescript
|
|
451
|
+
* import { createProductionValidationMiddleware } from 'ai.matey';
|
|
452
|
+
*
|
|
453
|
+
* bridge.use(createProductionValidationMiddleware());
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
export function createProductionValidationMiddleware() {
|
|
457
|
+
return createValidationMiddleware({
|
|
458
|
+
maxMessages: 100,
|
|
459
|
+
maxTotalTokens: 128000,
|
|
460
|
+
maxTokensPerMessage: 32000,
|
|
461
|
+
maxMessageLength: 100000,
|
|
462
|
+
blockEmptyMessages: true,
|
|
463
|
+
detectPII: true,
|
|
464
|
+
piiAction: 'redact',
|
|
465
|
+
preventPromptInjection: true,
|
|
466
|
+
sanitizeMessages: true,
|
|
467
|
+
throwOnError: true,
|
|
468
|
+
logWarnings: true,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Create development-friendly validation middleware with relaxed settings
|
|
473
|
+
*
|
|
474
|
+
* @returns Middleware with development validation settings
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* import { createDevelopmentValidationMiddleware } from 'ai.matey';
|
|
479
|
+
*
|
|
480
|
+
* bridge.use(createDevelopmentValidationMiddleware());
|
|
481
|
+
* ```
|
|
482
|
+
*/
|
|
483
|
+
export function createDevelopmentValidationMiddleware() {
|
|
484
|
+
return createValidationMiddleware({
|
|
485
|
+
maxMessages: 1000,
|
|
486
|
+
blockEmptyMessages: false,
|
|
487
|
+
detectPII: false,
|
|
488
|
+
preventPromptInjection: false,
|
|
489
|
+
sanitizeMessages: true,
|
|
490
|
+
throwOnError: false,
|
|
491
|
+
logWarnings: true,
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Caching Middleware
|
|
3
|
+
*
|
|
4
|
+
* Caches responses with TTL-based expiration and LRU eviction.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
import type { Middleware, CacheStorage } from 'ai.matey.types';
|
|
9
|
+
import type { IRChatRequest, IRChatResponse } from 'ai.matey.types';
|
|
10
|
+
/**
|
|
11
|
+
* Configuration for caching middleware.
|
|
12
|
+
*/
|
|
13
|
+
export interface CachingConfig {
|
|
14
|
+
/**
|
|
15
|
+
* Cache key generator function.
|
|
16
|
+
* @default Default implementation based on request hash
|
|
17
|
+
*/
|
|
18
|
+
keyGenerator?: (request: IRChatRequest) => string;
|
|
19
|
+
/**
|
|
20
|
+
* Cache TTL in milliseconds.
|
|
21
|
+
* @default 3600000 (1 hour)
|
|
22
|
+
*/
|
|
23
|
+
ttl?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Maximum cache size (number of entries).
|
|
26
|
+
* @default 1000
|
|
27
|
+
*/
|
|
28
|
+
maxSize?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Cache storage implementation.
|
|
31
|
+
* @default InMemoryCacheStorage
|
|
32
|
+
*/
|
|
33
|
+
storage?: CacheStorage;
|
|
34
|
+
/**
|
|
35
|
+
* Whether to cache streaming responses.
|
|
36
|
+
* @default false
|
|
37
|
+
*/
|
|
38
|
+
cacheStreaming?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* In-memory cache storage with LRU eviction.
|
|
42
|
+
*/
|
|
43
|
+
export declare class InMemoryCacheStorage implements CacheStorage {
|
|
44
|
+
private cache;
|
|
45
|
+
private accessOrder;
|
|
46
|
+
private maxSize;
|
|
47
|
+
constructor(maxSize?: number);
|
|
48
|
+
get(key: string): Promise<IRChatResponse | undefined>;
|
|
49
|
+
set(key: string, value: IRChatResponse, ttl?: number): Promise<void>;
|
|
50
|
+
has(key: string): Promise<boolean>;
|
|
51
|
+
delete(key: string): Promise<boolean>;
|
|
52
|
+
clear(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Get cache statistics.
|
|
55
|
+
*/
|
|
56
|
+
getStats(): {
|
|
57
|
+
size: number;
|
|
58
|
+
maxSize: number;
|
|
59
|
+
hitRate?: number;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Update LRU access order.
|
|
63
|
+
*/
|
|
64
|
+
private updateAccessOrder;
|
|
65
|
+
/**
|
|
66
|
+
* Remove key from access order.
|
|
67
|
+
*/
|
|
68
|
+
private removeFromAccessOrder;
|
|
69
|
+
/**
|
|
70
|
+
* Evict least recently used entry.
|
|
71
|
+
*/
|
|
72
|
+
private evictLRU;
|
|
73
|
+
/**
|
|
74
|
+
* Clean up expired entries.
|
|
75
|
+
*/
|
|
76
|
+
cleanup(): void;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create caching middleware.
|
|
80
|
+
*
|
|
81
|
+
* Caches responses with TTL-based expiration and LRU eviction.
|
|
82
|
+
*
|
|
83
|
+
* @param config Caching configuration
|
|
84
|
+
* @returns Caching middleware
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const caching = createCachingMiddleware({
|
|
89
|
+
* ttl: 3600000, // 1 hour
|
|
90
|
+
* maxSize: 1000,
|
|
91
|
+
* cacheStreaming: false
|
|
92
|
+
* });
|
|
93
|
+
*
|
|
94
|
+
* bridge.use(caching);
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
export declare function createCachingMiddleware(config?: CachingConfig): Middleware;
|
|
98
|
+
//# sourceMappingURL=caching.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caching.d.ts","sourceRoot":"","sources":["../../src/caching.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAqC,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAClG,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAOpE;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,MAAM,CAAC;IAElD;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAwCD;;GAEG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,GAAE,MAAa;IAIlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAoBrD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,GAAE,MAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBlC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtB;;OAEG;IACH,QAAQ,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE;IAO/D;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,QAAQ;IAchB;;OAEG;IACH,OAAO,IAAI,IAAI;CAgBhB;AAMD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,GAAE,aAAkB,GAAG,UAAU,CAuD9E"}
|