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.
Files changed (69) hide show
  1. package/LICENSE +21 -0
  2. package/dist/cjs/caching.js +226 -0
  3. package/dist/cjs/caching.js.map +1 -0
  4. package/dist/cjs/conversation-history.js +213 -0
  5. package/dist/cjs/conversation-history.js.map +1 -0
  6. package/dist/cjs/cost-tracking.js +355 -0
  7. package/dist/cjs/cost-tracking.js.map +1 -0
  8. package/dist/cjs/index.js +37 -0
  9. package/dist/cjs/index.js.map +1 -0
  10. package/dist/cjs/logging.js +174 -0
  11. package/dist/cjs/logging.js.map +1 -0
  12. package/dist/cjs/opentelemetry.js +499 -0
  13. package/dist/cjs/opentelemetry.js.map +1 -0
  14. package/dist/cjs/retry.js +205 -0
  15. package/dist/cjs/retry.js.map +1 -0
  16. package/dist/cjs/security.js +175 -0
  17. package/dist/cjs/security.js.map +1 -0
  18. package/dist/cjs/telemetry.js +216 -0
  19. package/dist/cjs/telemetry.js.map +1 -0
  20. package/dist/cjs/transform.js +284 -0
  21. package/dist/cjs/transform.js.map +1 -0
  22. package/dist/cjs/validation.js +506 -0
  23. package/dist/cjs/validation.js.map +1 -0
  24. package/dist/esm/caching.js +221 -0
  25. package/dist/esm/caching.js.map +1 -0
  26. package/dist/esm/conversation-history.js +207 -0
  27. package/dist/esm/conversation-history.js.map +1 -0
  28. package/dist/esm/cost-tracking.js +347 -0
  29. package/dist/esm/cost-tracking.js.map +1 -0
  30. package/dist/esm/index.js +21 -0
  31. package/dist/esm/index.js.map +1 -0
  32. package/dist/esm/logging.js +171 -0
  33. package/dist/esm/logging.js.map +1 -0
  34. package/dist/esm/opentelemetry.js +458 -0
  35. package/dist/esm/opentelemetry.js.map +1 -0
  36. package/dist/esm/retry.js +198 -0
  37. package/dist/esm/retry.js.map +1 -0
  38. package/dist/esm/security.js +169 -0
  39. package/dist/esm/security.js.map +1 -0
  40. package/dist/esm/telemetry.js +210 -0
  41. package/dist/esm/telemetry.js.map +1 -0
  42. package/dist/esm/transform.js +272 -0
  43. package/dist/esm/transform.js.map +1 -0
  44. package/dist/esm/validation.js +494 -0
  45. package/dist/esm/validation.js.map +1 -0
  46. package/dist/types/caching.d.ts +98 -0
  47. package/dist/types/caching.d.ts.map +1 -0
  48. package/dist/types/conversation-history.d.ts +188 -0
  49. package/dist/types/conversation-history.d.ts.map +1 -0
  50. package/dist/types/cost-tracking.d.ts +262 -0
  51. package/dist/types/cost-tracking.d.ts.map +1 -0
  52. package/dist/types/index.d.ts +20 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/logging.d.ts +82 -0
  55. package/dist/types/logging.d.ts.map +1 -0
  56. package/dist/types/opentelemetry.d.ts +219 -0
  57. package/dist/types/opentelemetry.d.ts.map +1 -0
  58. package/dist/types/retry.d.ts +86 -0
  59. package/dist/types/retry.d.ts.map +1 -0
  60. package/dist/types/security.d.ts +120 -0
  61. package/dist/types/security.d.ts.map +1 -0
  62. package/dist/types/telemetry.d.ts +120 -0
  63. package/dist/types/telemetry.d.ts.map +1 -0
  64. package/dist/types/transform.d.ts +184 -0
  65. package/dist/types/transform.d.ts.map +1 -0
  66. package/dist/types/validation.d.ts +356 -0
  67. package/dist/types/validation.d.ts.map +1 -0
  68. package/package.json +203 -0
  69. package/readme.md +103 -0
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Caching Middleware
3
+ *
4
+ * Caches responses with TTL-based expiration and LRU eviction.
5
+ *
6
+ * @module
7
+ */
8
+ import { createHash } from 'crypto';
9
+ // ============================================================================
10
+ // Default Key Generator
11
+ // ============================================================================
12
+ /**
13
+ * Default cache key generator.
14
+ *
15
+ * Generates cache key from model, messages, and parameters.
16
+ * Excludes metadata and streaming flag.
17
+ */
18
+ function defaultKeyGenerator(request) {
19
+ // Create a stable cache key from request
20
+ const cacheableData = {
21
+ model: request.parameters?.model,
22
+ messages: request.messages,
23
+ temperature: request.parameters?.temperature,
24
+ maxTokens: request.parameters?.maxTokens,
25
+ topP: request.parameters?.topP,
26
+ topK: request.parameters?.topK,
27
+ stopSequences: request.parameters?.stopSequences,
28
+ tools: request.tools,
29
+ toolChoice: request.toolChoice,
30
+ };
31
+ // Generate hash
32
+ const json = JSON.stringify(cacheableData);
33
+ return createHash('sha256').update(json).digest('hex');
34
+ }
35
+ /**
36
+ * In-memory cache storage with LRU eviction.
37
+ */
38
+ export class InMemoryCacheStorage {
39
+ cache = new Map();
40
+ accessOrder = [];
41
+ maxSize;
42
+ constructor(maxSize = 1000) {
43
+ this.maxSize = maxSize;
44
+ }
45
+ get(key) {
46
+ const entry = this.cache.get(key);
47
+ if (!entry) {
48
+ return Promise.resolve(undefined);
49
+ }
50
+ // Check if expired
51
+ if (Date.now() > entry.expiresAt) {
52
+ this.cache.delete(key);
53
+ this.removeFromAccessOrder(key);
54
+ return Promise.resolve(undefined);
55
+ }
56
+ // Update access order (LRU)
57
+ this.updateAccessOrder(key);
58
+ return Promise.resolve(entry.value);
59
+ }
60
+ set(key, value, ttl = 3600000) {
61
+ // Evict if at max size
62
+ if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
63
+ this.evictLRU();
64
+ }
65
+ // Store entry
66
+ this.cache.set(key, {
67
+ value,
68
+ expiresAt: Date.now() + ttl,
69
+ });
70
+ // Update access order
71
+ this.updateAccessOrder(key);
72
+ return Promise.resolve();
73
+ }
74
+ has(key) {
75
+ const entry = this.cache.get(key);
76
+ if (!entry) {
77
+ return Promise.resolve(false);
78
+ }
79
+ // Check if expired
80
+ if (Date.now() > entry.expiresAt) {
81
+ this.cache.delete(key);
82
+ this.removeFromAccessOrder(key);
83
+ return Promise.resolve(false);
84
+ }
85
+ return Promise.resolve(true);
86
+ }
87
+ delete(key) {
88
+ this.removeFromAccessOrder(key);
89
+ return Promise.resolve(this.cache.delete(key));
90
+ }
91
+ clear() {
92
+ this.cache.clear();
93
+ this.accessOrder = [];
94
+ return Promise.resolve();
95
+ }
96
+ /**
97
+ * Get cache statistics.
98
+ */
99
+ getStats() {
100
+ return {
101
+ size: this.cache.size,
102
+ maxSize: this.maxSize,
103
+ };
104
+ }
105
+ /**
106
+ * Update LRU access order.
107
+ */
108
+ updateAccessOrder(key) {
109
+ // Remove from current position
110
+ this.removeFromAccessOrder(key);
111
+ // Add to end (most recently used)
112
+ this.accessOrder.push(key);
113
+ }
114
+ /**
115
+ * Remove key from access order.
116
+ */
117
+ removeFromAccessOrder(key) {
118
+ const index = this.accessOrder.indexOf(key);
119
+ if (index !== -1) {
120
+ this.accessOrder.splice(index, 1);
121
+ }
122
+ }
123
+ /**
124
+ * Evict least recently used entry.
125
+ */
126
+ evictLRU() {
127
+ if (this.accessOrder.length === 0) {
128
+ return;
129
+ }
130
+ // Get least recently used key (first in array)
131
+ const lruKey = this.accessOrder[0];
132
+ if (lruKey) {
133
+ this.cache.delete(lruKey);
134
+ this.accessOrder.shift();
135
+ }
136
+ }
137
+ /**
138
+ * Clean up expired entries.
139
+ */
140
+ cleanup() {
141
+ const now = Date.now();
142
+ const expiredKeys = [];
143
+ // Use Array.from to avoid iteration issues
144
+ for (const [key, entry] of Array.from(this.cache.entries())) {
145
+ if (now > entry.expiresAt) {
146
+ expiredKeys.push(key);
147
+ }
148
+ }
149
+ for (const key of expiredKeys) {
150
+ this.cache.delete(key);
151
+ this.removeFromAccessOrder(key);
152
+ }
153
+ }
154
+ }
155
+ // ============================================================================
156
+ // Middleware Factory
157
+ // ============================================================================
158
+ /**
159
+ * Create caching middleware.
160
+ *
161
+ * Caches responses with TTL-based expiration and LRU eviction.
162
+ *
163
+ * @param config Caching configuration
164
+ * @returns Caching middleware
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * const caching = createCachingMiddleware({
169
+ * ttl: 3600000, // 1 hour
170
+ * maxSize: 1000,
171
+ * cacheStreaming: false
172
+ * });
173
+ *
174
+ * bridge.use(caching);
175
+ * ```
176
+ */
177
+ export function createCachingMiddleware(config = {}) {
178
+ const { keyGenerator = defaultKeyGenerator, ttl = 3600000, // 1 hour
179
+ maxSize = 1000, storage = new InMemoryCacheStorage(maxSize), cacheStreaming = false, } = config;
180
+ return async (context, next) => {
181
+ // Skip caching for streaming requests unless explicitly enabled
182
+ if (context.request.stream && !cacheStreaming) {
183
+ return next();
184
+ }
185
+ // Generate cache key
186
+ const cacheKey = keyGenerator(context.request);
187
+ // Check cache
188
+ const cachedResponse = await storage.get(cacheKey);
189
+ if (cachedResponse) {
190
+ // Cache hit - add cache metadata
191
+ return {
192
+ ...cachedResponse,
193
+ metadata: {
194
+ ...cachedResponse.metadata,
195
+ custom: {
196
+ ...cachedResponse.metadata.custom,
197
+ cacheHit: true,
198
+ cacheKey,
199
+ },
200
+ },
201
+ };
202
+ }
203
+ // Cache miss - call next middleware/handler
204
+ const response = await next();
205
+ // Store in cache
206
+ await storage.set(cacheKey, response, ttl);
207
+ // Add cache metadata
208
+ return {
209
+ ...response,
210
+ metadata: {
211
+ ...response.metadata,
212
+ custom: {
213
+ ...response.metadata.custom,
214
+ cacheHit: false,
215
+ cacheKey,
216
+ },
217
+ },
218
+ };
219
+ };
220
+ }
221
+ //# sourceMappingURL=caching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caching.js","sourceRoot":"","sources":["../../src/caching.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ /**
2
+ * Conversation History Middleware
3
+ *
4
+ * Manages conversation history across requests with configurable trimming strategies.
5
+ * Maintains a global conversation history that can be accessed and modified by requests.
6
+ *
7
+ * @module
8
+ */
9
+ import { trimHistory, shouldTrimHistory } from 'ai.matey.utils';
10
+ // ============================================================================
11
+ // Middleware Factory
12
+ // ============================================================================
13
+ /**
14
+ * Create conversation history middleware.
15
+ *
16
+ * Maintains a global conversation history across requests. Automatically prepends
17
+ * history to requests and appends responses to history after completion.
18
+ *
19
+ * @param config Conversation history configuration
20
+ * @returns Conversation history middleware and manager
21
+ *
22
+ * @example Basic Usage
23
+ * ```typescript
24
+ * const { middleware, manager } = createConversationHistoryMiddleware({
25
+ * maxHistorySize: 10,
26
+ * strategy: 'smart'
27
+ * });
28
+ *
29
+ * bridge.use(middleware);
30
+ *
31
+ * // Access history
32
+ * console.log('Pairs:', manager.getPairCount());
33
+ * console.log('History:', manager.getHistory());
34
+ *
35
+ * // Clear history when needed
36
+ * manager.clear();
37
+ * ```
38
+ *
39
+ * @example With Initial System Message
40
+ * ```typescript
41
+ * const { middleware } = createConversationHistoryMiddleware({
42
+ * initialHistory: [
43
+ * { role: 'system', content: 'You are a helpful assistant.' }
44
+ * ],
45
+ * maxHistorySize: 5,
46
+ * strategy: 'smart' // Preserves system message
47
+ * });
48
+ * ```
49
+ *
50
+ * @example Stateless Mode (No History)
51
+ * ```typescript
52
+ * const { middleware } = createConversationHistoryMiddleware({
53
+ * maxHistorySize: 0 // No history tracking
54
+ * });
55
+ * ```
56
+ *
57
+ * @example Custom Message Filtering
58
+ * ```typescript
59
+ * const { middleware } = createConversationHistoryMiddleware({
60
+ * maxHistorySize: 10,
61
+ * // Only track user and assistant messages, ignore system
62
+ * messageFilter: (msg) => msg.role !== 'system'
63
+ * });
64
+ * ```
65
+ */
66
+ export function createConversationHistoryMiddleware(config = {}) {
67
+ const { maxHistorySize = -1, strategy = 'smart', prependHistory = true, trackResponses = true, initialHistory = [], messageFilter = () => true, } = config;
68
+ // Internal conversation history state
69
+ let history = [...initialHistory];
70
+ // Create manager for external access
71
+ const manager = {
72
+ getHistory: () => [...history],
73
+ addMessage: (message) => {
74
+ if (messageFilter(message)) {
75
+ history.push(message);
76
+ manager.trim();
77
+ }
78
+ },
79
+ addMessages: (messages) => {
80
+ for (const message of messages) {
81
+ if (messageFilter(message)) {
82
+ history.push(message);
83
+ }
84
+ }
85
+ manager.trim();
86
+ },
87
+ clear: () => {
88
+ history = [];
89
+ },
90
+ setHistory: (newHistory) => {
91
+ history = [...newHistory];
92
+ manager.trim();
93
+ },
94
+ getPairCount: () => {
95
+ const nonSystemMessages = history.filter((m) => m.role !== 'system');
96
+ return Math.floor(nonSystemMessages.length / 2);
97
+ },
98
+ trim: () => {
99
+ if (shouldTrimHistory(history, maxHistorySize, strategy)) {
100
+ history = trimHistory(history, maxHistorySize, strategy);
101
+ }
102
+ },
103
+ };
104
+ // Create middleware
105
+ const middleware = async (context, next) => {
106
+ let request = context.request;
107
+ // Prepend history to request if enabled
108
+ if (prependHistory && maxHistorySize !== 0) {
109
+ const currentHistory = manager.getHistory();
110
+ // Merge history with request messages
111
+ // Filter out duplicate system messages from request if history already has them
112
+ const requestMessages = request.messages.filter((msg) => {
113
+ // Keep all non-system messages
114
+ if (msg.role !== 'system') {
115
+ return true;
116
+ }
117
+ // For system messages, only keep if not already in history
118
+ const existingSystemMessage = currentHistory.find((h) => h.role === 'system' && h.content === msg.content);
119
+ return !existingSystemMessage;
120
+ });
121
+ request = {
122
+ ...request,
123
+ messages: [...currentHistory, ...requestMessages],
124
+ };
125
+ context.request = request;
126
+ }
127
+ // Call next middleware/handler
128
+ const response = await next();
129
+ // Track response in history if enabled
130
+ if (trackResponses && maxHistorySize !== 0) {
131
+ // Add the new user message(s) from this request to history
132
+ const newUserMessages = context.request.messages.filter((msg) => msg.role === 'user' || msg.role === 'assistant');
133
+ // Find messages that aren't already in history
134
+ for (const msg of newUserMessages) {
135
+ const alreadyInHistory = history.some((h) => h.role === msg.role &&
136
+ h.content === msg.content &&
137
+ h.timestamp === msg.timestamp);
138
+ if (!alreadyInHistory) {
139
+ manager.addMessage(msg);
140
+ }
141
+ }
142
+ // Add assistant response to history
143
+ if (response.message) {
144
+ manager.addMessage(response.message);
145
+ }
146
+ }
147
+ return response;
148
+ };
149
+ return { middleware, manager };
150
+ }
151
+ // ============================================================================
152
+ // Helper Functions
153
+ // ============================================================================
154
+ /**
155
+ * Create a simple conversation history middleware with minimal config.
156
+ *
157
+ * @param maxHistorySize Maximum number of message pairs to keep
158
+ * @returns Conversation history middleware
159
+ *
160
+ * @example
161
+ * ```typescript
162
+ * // Keep last 5 message pairs
163
+ * bridge.use(simpleConversationHistory(5));
164
+ * ```
165
+ */
166
+ export function simpleConversationHistory(maxHistorySize = 10) {
167
+ const { middleware } = createConversationHistoryMiddleware({ maxHistorySize });
168
+ return middleware;
169
+ }
170
+ /**
171
+ * Create a stateless conversation history middleware.
172
+ * Useful for explicitly disabling history in a pipeline.
173
+ *
174
+ * @returns Stateless middleware
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * // Explicitly disable history
179
+ * bridge.use(statelessConversation());
180
+ * ```
181
+ */
182
+ export function statelessConversation() {
183
+ const { middleware } = createConversationHistoryMiddleware({ maxHistorySize: 0 });
184
+ return middleware;
185
+ }
186
+ /**
187
+ * Create a conversation history middleware that only tracks user/assistant pairs.
188
+ * System messages from requests are passed through but not tracked.
189
+ *
190
+ * @param maxHistorySize Maximum number of message pairs
191
+ * @returns Conversation history middleware
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * // Track conversation but not system messages
196
+ * bridge.use(conversationOnlyHistory(10));
197
+ * ```
198
+ */
199
+ export function conversationOnlyHistory(maxHistorySize = 10) {
200
+ const { middleware } = createConversationHistoryMiddleware({
201
+ maxHistorySize,
202
+ strategy: 'fifo',
203
+ messageFilter: (msg) => msg.role !== 'system',
204
+ });
205
+ return middleware;
206
+ }
207
+ //# sourceMappingURL=conversation-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-history.js","sourceRoot":"","sources":["../../src/conversation-history.ts"],"names":[],"mappings":"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"}