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,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Retry Middleware
|
|
4
|
+
*
|
|
5
|
+
* Retries failed requests with exponential backoff.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.createRetryMiddleware = createRetryMiddleware;
|
|
11
|
+
exports.isRateLimitError = isRateLimitError;
|
|
12
|
+
exports.isNetworkError = isNetworkError;
|
|
13
|
+
exports.isServerError = isServerError;
|
|
14
|
+
exports.createRetryPredicate = createRetryPredicate;
|
|
15
|
+
const ai_matey_errors_1 = require("ai.matey.errors");
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Retry Logic
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Default retry condition.
|
|
21
|
+
*
|
|
22
|
+
* Only retry transient errors (network issues, rate limits, server errors).
|
|
23
|
+
* Note: maxAttempts is enforced by the middleware loop, not this function.
|
|
24
|
+
*/
|
|
25
|
+
function defaultShouldRetry(error, _attempt) {
|
|
26
|
+
// Check if error has isRetryable property
|
|
27
|
+
if (error && typeof error === 'object' && 'isRetryable' in error) {
|
|
28
|
+
return error.isRetryable === true;
|
|
29
|
+
}
|
|
30
|
+
// For AdapterError, check isRetryable
|
|
31
|
+
if (error instanceof ai_matey_errors_1.AdapterError) {
|
|
32
|
+
return error.isRetryable;
|
|
33
|
+
}
|
|
34
|
+
// Default: don't retry unknown errors
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Calculate retry delay with exponential backoff.
|
|
39
|
+
*/
|
|
40
|
+
function calculateDelay(attempt, initialDelay, backoffMultiplier, maxDelay, useJitter) {
|
|
41
|
+
// Calculate exponential backoff
|
|
42
|
+
let delay = initialDelay * Math.pow(backoffMultiplier, attempt);
|
|
43
|
+
// Cap at max delay
|
|
44
|
+
delay = Math.min(delay, maxDelay);
|
|
45
|
+
// Add jitter if enabled (random value between 0 and delay)
|
|
46
|
+
if (useJitter) {
|
|
47
|
+
delay = Math.random() * delay;
|
|
48
|
+
}
|
|
49
|
+
return Math.floor(delay);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Sleep for specified duration.
|
|
53
|
+
*/
|
|
54
|
+
function sleep(ms) {
|
|
55
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
56
|
+
}
|
|
57
|
+
// ============================================================================
|
|
58
|
+
// Middleware Factory
|
|
59
|
+
// ============================================================================
|
|
60
|
+
/**
|
|
61
|
+
* Create retry middleware.
|
|
62
|
+
*
|
|
63
|
+
* Retries failed requests with exponential backoff.
|
|
64
|
+
*
|
|
65
|
+
* @param config Retry configuration
|
|
66
|
+
* @returns Retry middleware
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const retry = createRetryMiddleware({
|
|
71
|
+
* maxAttempts: 3,
|
|
72
|
+
* initialDelay: 1000,
|
|
73
|
+
* backoffMultiplier: 2,
|
|
74
|
+
* maxDelay: 30000
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* bridge.use(retry);
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
function createRetryMiddleware(config = {}) {
|
|
81
|
+
const { maxAttempts = 3, initialDelay = 1000, backoffMultiplier = 2, maxDelay = 30000, useJitter = true, shouldRetry = defaultShouldRetry, onRetry, } = config;
|
|
82
|
+
return async (context, next) => {
|
|
83
|
+
let lastError;
|
|
84
|
+
let attempt = 0;
|
|
85
|
+
while (attempt < maxAttempts) {
|
|
86
|
+
try {
|
|
87
|
+
// Call next middleware/handler
|
|
88
|
+
const response = await next();
|
|
89
|
+
// Success - add retry metadata if we retried
|
|
90
|
+
if (attempt > 0) {
|
|
91
|
+
return {
|
|
92
|
+
...response,
|
|
93
|
+
metadata: {
|
|
94
|
+
...response.metadata,
|
|
95
|
+
custom: {
|
|
96
|
+
...response.metadata.custom,
|
|
97
|
+
retryAttempts: attempt,
|
|
98
|
+
retrySuccess: true,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return response;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
lastError = error;
|
|
107
|
+
attempt++;
|
|
108
|
+
// Check if we should retry
|
|
109
|
+
const willRetry = attempt < maxAttempts && shouldRetry(error, attempt);
|
|
110
|
+
if (!willRetry) {
|
|
111
|
+
// No more retries - add metadata and throw
|
|
112
|
+
if (error instanceof ai_matey_errors_1.AdapterError) {
|
|
113
|
+
throw new ai_matey_errors_1.AdapterError({
|
|
114
|
+
...error,
|
|
115
|
+
details: {
|
|
116
|
+
...error.details,
|
|
117
|
+
retryAttempts: attempt,
|
|
118
|
+
retrySuccess: false,
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
// Calculate retry delay
|
|
125
|
+
const delay = calculateDelay(attempt - 1, // 0-indexed for delay calculation
|
|
126
|
+
initialDelay, backoffMultiplier, maxDelay, useJitter);
|
|
127
|
+
// Call retry callback if provided
|
|
128
|
+
if (onRetry) {
|
|
129
|
+
onRetry(error, attempt, delay);
|
|
130
|
+
}
|
|
131
|
+
// Check if request was aborted
|
|
132
|
+
if (context.signal?.aborted) {
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
// Wait before retrying
|
|
136
|
+
await sleep(delay);
|
|
137
|
+
// Check again if request was aborted during sleep
|
|
138
|
+
if (context.signal?.aborted) {
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Should never reach here, but just in case
|
|
144
|
+
throw lastError;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// ============================================================================
|
|
148
|
+
// Retry Utilities
|
|
149
|
+
// ============================================================================
|
|
150
|
+
/**
|
|
151
|
+
* Check if an error is a rate limit error.
|
|
152
|
+
*/
|
|
153
|
+
function isRateLimitError(error) {
|
|
154
|
+
if (error instanceof ai_matey_errors_1.AdapterError) {
|
|
155
|
+
return error.code === 'RATE_LIMIT_EXCEEDED';
|
|
156
|
+
}
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Check if an error is a network error.
|
|
161
|
+
*/
|
|
162
|
+
function isNetworkError(error) {
|
|
163
|
+
if (error instanceof ai_matey_errors_1.AdapterError) {
|
|
164
|
+
return error.code === 'NETWORK_ERROR';
|
|
165
|
+
}
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Check if an error is a server error (5xx).
|
|
170
|
+
*/
|
|
171
|
+
function isServerError(error) {
|
|
172
|
+
if (error instanceof ai_matey_errors_1.AdapterError) {
|
|
173
|
+
return error.code === 'PROVIDER_ERROR' || error.code === 'INTERNAL_ERROR';
|
|
174
|
+
}
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Create a retry predicate that only retries specific error types.
|
|
179
|
+
* Note: maxAttempts is enforced by the middleware loop, not this function.
|
|
180
|
+
*/
|
|
181
|
+
function createRetryPredicate(errorTypes) {
|
|
182
|
+
return (error, _attempt) => {
|
|
183
|
+
for (const type of errorTypes) {
|
|
184
|
+
switch (type) {
|
|
185
|
+
case 'rate_limit':
|
|
186
|
+
if (isRateLimitError(error)) {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
break;
|
|
190
|
+
case 'network':
|
|
191
|
+
if (isNetworkError(error)) {
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
break;
|
|
195
|
+
case 'server':
|
|
196
|
+
if (isServerError(error)) {
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Security Middleware
|
|
4
|
+
*
|
|
5
|
+
* Adds security headers and implements security best practices for HTTP responses.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DEFAULT_SECURITY_CONFIG = void 0;
|
|
11
|
+
exports.createSecurityMiddleware = createSecurityMiddleware;
|
|
12
|
+
exports.createProductionSecurityMiddleware = createProductionSecurityMiddleware;
|
|
13
|
+
exports.createDevelopmentSecurityMiddleware = createDevelopmentSecurityMiddleware;
|
|
14
|
+
/**
|
|
15
|
+
* Default security configuration
|
|
16
|
+
*/
|
|
17
|
+
exports.DEFAULT_SECURITY_CONFIG = {
|
|
18
|
+
contentSecurityPolicy: "default-src 'self'",
|
|
19
|
+
contentTypeOptions: 'nosniff',
|
|
20
|
+
frameOptions: 'DENY',
|
|
21
|
+
xssProtection: '1; mode=block',
|
|
22
|
+
hsts: 'max-age=31536000; includeSubDomains',
|
|
23
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
24
|
+
permissionsPolicy: 'geolocation=(), microphone=(), camera=()',
|
|
25
|
+
poweredBy: false,
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Create security headers middleware
|
|
29
|
+
*
|
|
30
|
+
* Adds security headers to responses to protect against common vulnerabilities.
|
|
31
|
+
*
|
|
32
|
+
* @param config - Security configuration
|
|
33
|
+
* @returns Middleware function
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { createSecurityMiddleware } from 'ai.matey';
|
|
38
|
+
*
|
|
39
|
+
* const security = createSecurityMiddleware({
|
|
40
|
+
* contentSecurityPolicy: "default-src 'self'",
|
|
41
|
+
* hsts: 'max-age=31536000',
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* bridge.use(security);
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Production Configuration
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const productionSecurity = createSecurityMiddleware({
|
|
50
|
+
* contentSecurityPolicy: "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'",
|
|
51
|
+
* frameOptions: 'DENY',
|
|
52
|
+
* hsts: 'max-age=31536000; includeSubDomains; preload',
|
|
53
|
+
* referrerPolicy: 'strict-origin-when-cross-origin',
|
|
54
|
+
* permissionsPolicy: 'geolocation=(), microphone=(), camera=(), payment=()',
|
|
55
|
+
* });
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
function createSecurityMiddleware(config = {}) {
|
|
59
|
+
const mergedConfig = {
|
|
60
|
+
...exports.DEFAULT_SECURITY_CONFIG,
|
|
61
|
+
...config,
|
|
62
|
+
};
|
|
63
|
+
return async (context, next) => {
|
|
64
|
+
// Add security headers to request metadata (will be passed through to response)
|
|
65
|
+
// Note: In ai.matey, security headers should ideally be added at the HTTP layer
|
|
66
|
+
// This middleware just marks that security headers should be added
|
|
67
|
+
const custom = context.request.metadata?.custom || {};
|
|
68
|
+
const securityHeaders = {};
|
|
69
|
+
const headers = securityHeaders;
|
|
70
|
+
// Content Security Policy
|
|
71
|
+
if (mergedConfig.contentSecurityPolicy !== false) {
|
|
72
|
+
headers['Content-Security-Policy'] = mergedConfig.contentSecurityPolicy;
|
|
73
|
+
}
|
|
74
|
+
// X-Content-Type-Options
|
|
75
|
+
if (mergedConfig.contentTypeOptions !== false) {
|
|
76
|
+
headers['X-Content-Type-Options'] = mergedConfig.contentTypeOptions;
|
|
77
|
+
}
|
|
78
|
+
// X-Frame-Options
|
|
79
|
+
if (mergedConfig.frameOptions !== false) {
|
|
80
|
+
headers['X-Frame-Options'] = mergedConfig.frameOptions;
|
|
81
|
+
}
|
|
82
|
+
// X-XSS-Protection
|
|
83
|
+
if (mergedConfig.xssProtection !== false) {
|
|
84
|
+
headers['X-XSS-Protection'] = mergedConfig.xssProtection;
|
|
85
|
+
}
|
|
86
|
+
// Strict-Transport-Security
|
|
87
|
+
if (mergedConfig.hsts !== false) {
|
|
88
|
+
headers['Strict-Transport-Security'] = mergedConfig.hsts;
|
|
89
|
+
}
|
|
90
|
+
// Referrer-Policy
|
|
91
|
+
if (mergedConfig.referrerPolicy !== false) {
|
|
92
|
+
headers['Referrer-Policy'] = mergedConfig.referrerPolicy;
|
|
93
|
+
}
|
|
94
|
+
// Permissions-Policy
|
|
95
|
+
if (mergedConfig.permissionsPolicy !== false) {
|
|
96
|
+
headers['Permissions-Policy'] = mergedConfig.permissionsPolicy;
|
|
97
|
+
}
|
|
98
|
+
// Remove X-Powered-By (or set custom value)
|
|
99
|
+
if (mergedConfig.poweredBy === false) {
|
|
100
|
+
// Mark for removal
|
|
101
|
+
headers['X-Powered-By'] = '';
|
|
102
|
+
}
|
|
103
|
+
else if (mergedConfig.poweredBy) {
|
|
104
|
+
headers['X-Powered-By'] = mergedConfig.poweredBy;
|
|
105
|
+
}
|
|
106
|
+
// Add custom headers
|
|
107
|
+
if (config.customHeaders) {
|
|
108
|
+
Object.assign(headers, config.customHeaders);
|
|
109
|
+
}
|
|
110
|
+
// Store headers in custom metadata (HTTP layer should apply these)
|
|
111
|
+
const newCustom = {
|
|
112
|
+
...custom,
|
|
113
|
+
securityHeaders,
|
|
114
|
+
};
|
|
115
|
+
// Update request with security headers metadata
|
|
116
|
+
context.request = {
|
|
117
|
+
...context.request,
|
|
118
|
+
metadata: {
|
|
119
|
+
...context.request.metadata,
|
|
120
|
+
custom: newCustom,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
// Execute next middleware/backend
|
|
124
|
+
return await next();
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Create production-ready security middleware with strict settings
|
|
129
|
+
*
|
|
130
|
+
* @returns Middleware with production security settings
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* import { createProductionSecurityMiddleware } from 'ai.matey';
|
|
135
|
+
*
|
|
136
|
+
* bridge.use(createProductionSecurityMiddleware());
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
function createProductionSecurityMiddleware() {
|
|
140
|
+
return createSecurityMiddleware({
|
|
141
|
+
contentSecurityPolicy: "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'",
|
|
142
|
+
frameOptions: 'DENY',
|
|
143
|
+
hsts: 'max-age=31536000; includeSubDomains; preload',
|
|
144
|
+
xssProtection: '1; mode=block',
|
|
145
|
+
contentTypeOptions: 'nosniff',
|
|
146
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
147
|
+
permissionsPolicy: 'geolocation=(), microphone=(), camera=(), payment=(), usb=()',
|
|
148
|
+
poweredBy: false,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Create development-friendly security middleware with relaxed settings
|
|
153
|
+
*
|
|
154
|
+
* @returns Middleware with development security settings
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* import { createDevelopmentSecurityMiddleware } from 'ai.matey';
|
|
159
|
+
*
|
|
160
|
+
* bridge.use(createDevelopmentSecurityMiddleware());
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
function createDevelopmentSecurityMiddleware() {
|
|
164
|
+
return createSecurityMiddleware({
|
|
165
|
+
contentSecurityPolicy: false, // Disable for easier development
|
|
166
|
+
frameOptions: 'SAMEORIGIN',
|
|
167
|
+
hsts: false, // Don't enforce HTTPS in development
|
|
168
|
+
xssProtection: '1; mode=block',
|
|
169
|
+
contentTypeOptions: 'nosniff',
|
|
170
|
+
referrerPolicy: 'strict-origin-when-cross-origin',
|
|
171
|
+
permissionsPolicy: false,
|
|
172
|
+
poweredBy: false,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Telemetry Middleware
|
|
4
|
+
*
|
|
5
|
+
* Tracks metrics, events, and performance data for requests and responses.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.InMemoryTelemetrySink = exports.ConsoleTelemetrySink = exports.EventNames = exports.MetricNames = void 0;
|
|
11
|
+
exports.createTelemetryMiddleware = createTelemetryMiddleware;
|
|
12
|
+
/**
|
|
13
|
+
* Metric names.
|
|
14
|
+
*/
|
|
15
|
+
exports.MetricNames = {
|
|
16
|
+
REQUEST_COUNT: 'ai.adapter.request.count',
|
|
17
|
+
REQUEST_DURATION: 'ai.adapter.request.duration',
|
|
18
|
+
REQUEST_ERROR: 'ai.adapter.request.error',
|
|
19
|
+
TOKEN_PROMPT: 'ai.adapter.tokens.prompt',
|
|
20
|
+
TOKEN_COMPLETION: 'ai.adapter.tokens.completion',
|
|
21
|
+
TOKEN_TOTAL: 'ai.adapter.tokens.total',
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Event names.
|
|
25
|
+
*/
|
|
26
|
+
exports.EventNames = {
|
|
27
|
+
REQUEST_START: 'ai.adapter.request.start',
|
|
28
|
+
REQUEST_COMPLETE: 'ai.adapter.request.complete',
|
|
29
|
+
REQUEST_ERROR: 'ai.adapter.request.error',
|
|
30
|
+
};
|
|
31
|
+
// ============================================================================
|
|
32
|
+
// Sampling
|
|
33
|
+
// ============================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Determine if this request should be sampled.
|
|
36
|
+
*/
|
|
37
|
+
function shouldSample(sampleRate) {
|
|
38
|
+
return Math.random() < sampleRate;
|
|
39
|
+
}
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// Middleware Factory
|
|
42
|
+
// ============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Create telemetry middleware.
|
|
45
|
+
*
|
|
46
|
+
* Tracks metrics and events for monitoring and observability.
|
|
47
|
+
*
|
|
48
|
+
* @param config Telemetry configuration
|
|
49
|
+
* @returns Telemetry middleware
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* const telemetry = createTelemetryMiddleware({
|
|
54
|
+
* sink: {
|
|
55
|
+
* recordMetric: (name, value, tags) => {
|
|
56
|
+
* console.log(`Metric: ${name} = ${value}`, tags);
|
|
57
|
+
* },
|
|
58
|
+
* recordEvent: (name, data) => {
|
|
59
|
+
* console.log(`Event: ${name}`, data);
|
|
60
|
+
* }
|
|
61
|
+
* },
|
|
62
|
+
* trackCounts: true,
|
|
63
|
+
* trackLatencies: true,
|
|
64
|
+
* trackTokens: true
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* bridge.use(telemetry);
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
function createTelemetryMiddleware(config) {
|
|
71
|
+
const { sink, trackCounts = true, trackLatencies = true, trackErrors = true, trackTokens = true, tags = {}, sampleRate = 1.0, } = config;
|
|
72
|
+
return async (context, next) => {
|
|
73
|
+
// Check if we should sample this request
|
|
74
|
+
const sampled = shouldSample(sampleRate);
|
|
75
|
+
const startTime = Date.now();
|
|
76
|
+
const requestId = context.request.metadata.requestId;
|
|
77
|
+
// Build base tags
|
|
78
|
+
const baseTags = {
|
|
79
|
+
...tags,
|
|
80
|
+
request_id: requestId,
|
|
81
|
+
model: context.request.parameters?.model ?? 'unknown',
|
|
82
|
+
stream: String(context.request.stream ?? false),
|
|
83
|
+
frontend: context.request.metadata.provenance?.frontend ?? 'unknown',
|
|
84
|
+
};
|
|
85
|
+
// Record request start event
|
|
86
|
+
if (sampled) {
|
|
87
|
+
sink.recordEvent(exports.EventNames.REQUEST_START, {
|
|
88
|
+
requestId,
|
|
89
|
+
model: context.request.parameters?.model,
|
|
90
|
+
messageCount: context.request.messages.length,
|
|
91
|
+
stream: context.request.stream,
|
|
92
|
+
timestamp: startTime,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
// Call next middleware/handler
|
|
97
|
+
const response = await next();
|
|
98
|
+
const duration = Date.now() - startTime;
|
|
99
|
+
// Add backend to tags
|
|
100
|
+
const responseTags = {
|
|
101
|
+
...baseTags,
|
|
102
|
+
backend: response.metadata.provenance?.backend ?? 'unknown',
|
|
103
|
+
finish_reason: response.finishReason,
|
|
104
|
+
};
|
|
105
|
+
// Record metrics
|
|
106
|
+
if (sampled) {
|
|
107
|
+
// Track request count
|
|
108
|
+
if (trackCounts) {
|
|
109
|
+
sink.recordMetric(exports.MetricNames.REQUEST_COUNT, 1, {
|
|
110
|
+
...responseTags,
|
|
111
|
+
status: 'success',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// Track latency
|
|
115
|
+
if (trackLatencies) {
|
|
116
|
+
sink.recordMetric(exports.MetricNames.REQUEST_DURATION, duration, responseTags);
|
|
117
|
+
}
|
|
118
|
+
// Track token usage
|
|
119
|
+
if (trackTokens && response.usage) {
|
|
120
|
+
if (response.usage.promptTokens) {
|
|
121
|
+
sink.recordMetric(exports.MetricNames.TOKEN_PROMPT, response.usage.promptTokens, responseTags);
|
|
122
|
+
}
|
|
123
|
+
if (response.usage.completionTokens) {
|
|
124
|
+
sink.recordMetric(exports.MetricNames.TOKEN_COMPLETION, response.usage.completionTokens, responseTags);
|
|
125
|
+
}
|
|
126
|
+
if (response.usage.totalTokens) {
|
|
127
|
+
sink.recordMetric(exports.MetricNames.TOKEN_TOTAL, response.usage.totalTokens, responseTags);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Record completion event
|
|
131
|
+
sink.recordEvent(exports.EventNames.REQUEST_COMPLETE, {
|
|
132
|
+
requestId,
|
|
133
|
+
duration,
|
|
134
|
+
backend: response.metadata.provenance?.backend,
|
|
135
|
+
finishReason: response.finishReason,
|
|
136
|
+
usage: response.usage,
|
|
137
|
+
timestamp: Date.now(),
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
const duration = Date.now() - startTime;
|
|
144
|
+
// Add error info to tags
|
|
145
|
+
const errorTags = {
|
|
146
|
+
...baseTags,
|
|
147
|
+
error_type: error instanceof Error ? error.name : 'unknown',
|
|
148
|
+
};
|
|
149
|
+
// Record error metrics
|
|
150
|
+
if (sampled) {
|
|
151
|
+
if (trackCounts) {
|
|
152
|
+
sink.recordMetric(exports.MetricNames.REQUEST_COUNT, 1, {
|
|
153
|
+
...errorTags,
|
|
154
|
+
status: 'error',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (trackLatencies) {
|
|
158
|
+
sink.recordMetric(exports.MetricNames.REQUEST_DURATION, duration, errorTags);
|
|
159
|
+
}
|
|
160
|
+
if (trackErrors) {
|
|
161
|
+
sink.recordMetric(exports.MetricNames.REQUEST_ERROR, 1, errorTags);
|
|
162
|
+
}
|
|
163
|
+
// Record error event
|
|
164
|
+
sink.recordEvent(exports.EventNames.REQUEST_ERROR, {
|
|
165
|
+
requestId,
|
|
166
|
+
duration,
|
|
167
|
+
error: error instanceof Error ? error.message : String(error),
|
|
168
|
+
errorType: error instanceof Error ? error.name : 'unknown',
|
|
169
|
+
timestamp: Date.now(),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// Re-throw error
|
|
173
|
+
throw error;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// Built-in Sinks
|
|
179
|
+
// ============================================================================
|
|
180
|
+
/**
|
|
181
|
+
* Console telemetry sink for development/debugging.
|
|
182
|
+
*/
|
|
183
|
+
class ConsoleTelemetrySink {
|
|
184
|
+
recordMetric(name, value, tags) {
|
|
185
|
+
console.warn('[Telemetry Metric]', { name, value, tags });
|
|
186
|
+
}
|
|
187
|
+
recordEvent(name, data) {
|
|
188
|
+
console.warn('[Telemetry Event]', { name, data });
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
exports.ConsoleTelemetrySink = ConsoleTelemetrySink;
|
|
192
|
+
/**
|
|
193
|
+
* In-memory telemetry sink for testing.
|
|
194
|
+
*/
|
|
195
|
+
class InMemoryTelemetrySink {
|
|
196
|
+
metrics = [];
|
|
197
|
+
events = [];
|
|
198
|
+
recordMetric(name, value, tags) {
|
|
199
|
+
this.metrics.push({ name, value, tags });
|
|
200
|
+
}
|
|
201
|
+
recordEvent(name, data) {
|
|
202
|
+
this.events.push({ name, data });
|
|
203
|
+
}
|
|
204
|
+
getMetrics() {
|
|
205
|
+
return [...this.metrics];
|
|
206
|
+
}
|
|
207
|
+
getEvents() {
|
|
208
|
+
return [...this.events];
|
|
209
|
+
}
|
|
210
|
+
clear() {
|
|
211
|
+
this.metrics = [];
|
|
212
|
+
this.events = [];
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
exports.InMemoryTelemetrySink = InMemoryTelemetrySink;
|
|
216
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/telemetry.ts"],"names":[],"mappings":"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"}
|