@lov3kaizen/agentsea-cache 0.5.1

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.
@@ -0,0 +1,103 @@
1
+ import { S as SemanticCache } from '../../SemanticCache-vysguwUQ.js';
2
+ import { C as CacheMessage, W as WrapOptions, c as CacheStats } from '../../cache.types-DMuyQseO.js';
3
+ import 'eventemitter3';
4
+ import '../../store.types-BQy5Yyz9.js';
5
+ import '../../BaseMatchStrategy-1E1SHaUt.js';
6
+ import '../../SimilarityEngine-Cwv_mF9a.js';
7
+ import '../../analytics/index.js';
8
+
9
+ interface MiddlewareRequest {
10
+ model: string;
11
+ messages: CacheMessage[];
12
+ temperature?: number;
13
+ maxTokens?: number;
14
+ tools?: unknown[];
15
+ [key: string]: unknown;
16
+ }
17
+ interface MiddlewareResponse {
18
+ content: string;
19
+ model: string;
20
+ finishReason?: string;
21
+ usage?: {
22
+ promptTokens: number;
23
+ completionTokens: number;
24
+ totalTokens: number;
25
+ };
26
+ toolCalls?: unknown[];
27
+ [key: string]: unknown;
28
+ }
29
+ type MiddlewareNext = (request: MiddlewareRequest) => Promise<MiddlewareResponse>;
30
+ interface CacheMiddlewareConfig {
31
+ cache: SemanticCache;
32
+ skipModels?: string[];
33
+ skipToolRequests?: boolean;
34
+ defaultTTL?: number;
35
+ tagPrefix?: string;
36
+ getUserId?: (request: MiddlewareRequest) => string | undefined;
37
+ getAgentId?: (request: MiddlewareRequest) => string | undefined;
38
+ keyGenerator?: (request: MiddlewareRequest) => string;
39
+ }
40
+ declare class CacheMiddleware {
41
+ private config;
42
+ constructor(config: CacheMiddlewareConfig);
43
+ handle(request: MiddlewareRequest, next: MiddlewareNext): Promise<MiddlewareResponse>;
44
+ middleware(): (request: MiddlewareRequest, next: MiddlewareNext) => Promise<MiddlewareResponse>;
45
+ configure(config: Partial<CacheMiddlewareConfig>): void;
46
+ getCache(): SemanticCache;
47
+ private shouldSkip;
48
+ private buildOptions;
49
+ }
50
+ declare function createCacheMiddleware(config: CacheMiddlewareConfig): CacheMiddleware;
51
+
52
+ interface LLMProvider {
53
+ complete(request: CompletionRequest): Promise<CompletionResponse>;
54
+ stream?(request: CompletionRequest): AsyncGenerator<StreamChunk>;
55
+ }
56
+ interface CompletionRequest {
57
+ model: string;
58
+ messages: CacheMessage[];
59
+ temperature?: number;
60
+ maxTokens?: number;
61
+ tools?: unknown[];
62
+ stream?: boolean;
63
+ [key: string]: unknown;
64
+ }
65
+ interface CompletionResponse {
66
+ content: string;
67
+ model: string;
68
+ finishReason: string;
69
+ usage?: {
70
+ promptTokens: number;
71
+ completionTokens: number;
72
+ totalTokens: number;
73
+ };
74
+ toolCalls?: unknown[];
75
+ }
76
+ interface StreamChunk {
77
+ content?: string;
78
+ finishReason?: string;
79
+ toolCall?: unknown;
80
+ }
81
+ interface CachedProviderConfig {
82
+ provider: LLMProvider;
83
+ cache: SemanticCache;
84
+ skipModels?: string[];
85
+ defaultOptions?: WrapOptions;
86
+ enableStreamingCache?: boolean;
87
+ }
88
+ declare class CachedProvider implements LLMProvider {
89
+ private provider;
90
+ private cache;
91
+ private config;
92
+ constructor(config: CachedProviderConfig);
93
+ complete(request: CompletionRequest): Promise<CompletionResponse>;
94
+ stream(request: CompletionRequest): AsyncGenerator<StreamChunk>;
95
+ getProvider(): LLMProvider;
96
+ getCache(): SemanticCache;
97
+ clearCache(): Promise<void>;
98
+ getCacheStats(): CacheStats;
99
+ }
100
+ declare function createCachedProvider(config: CachedProviderConfig): CachedProvider;
101
+ declare function withCache(provider: LLMProvider, cache: SemanticCache, options?: Partial<CachedProviderConfig>): CachedProvider;
102
+
103
+ export { CacheMiddleware, type CacheMiddlewareConfig, CachedProvider, type CachedProviderConfig, type CompletionRequest, type CompletionResponse, type LLMProvider, type MiddlewareNext, type MiddlewareRequest, type MiddlewareResponse, type StreamChunk, createCacheMiddleware, createCachedProvider, withCache };
@@ -0,0 +1,201 @@
1
+ // src/integrations/agentsea/CacheMiddleware.ts
2
+ var CacheMiddleware = class {
3
+ config;
4
+ constructor(config) {
5
+ this.config = config;
6
+ }
7
+ /**
8
+ * Handle a request with caching
9
+ */
10
+ async handle(request, next) {
11
+ if (this.shouldSkip(request)) {
12
+ return next(request);
13
+ }
14
+ const options = this.buildOptions(request);
15
+ return this.config.cache.wrap(
16
+ {
17
+ model: request.model,
18
+ messages: request.messages,
19
+ temperature: request.temperature,
20
+ maxTokens: request.maxTokens
21
+ },
22
+ async () => {
23
+ const response = await next(request);
24
+ return {
25
+ content: response.content,
26
+ model: response.model,
27
+ finishReason: response.finishReason ?? "stop",
28
+ usage: response.usage
29
+ };
30
+ },
31
+ options
32
+ );
33
+ }
34
+ /**
35
+ * Create express-style middleware function
36
+ */
37
+ middleware() {
38
+ return (request, next) => this.handle(request, next);
39
+ }
40
+ /**
41
+ * Update configuration
42
+ */
43
+ configure(config) {
44
+ this.config = { ...this.config, ...config };
45
+ }
46
+ /**
47
+ * Get the underlying cache instance
48
+ */
49
+ getCache() {
50
+ return this.config.cache;
51
+ }
52
+ shouldSkip(request) {
53
+ if (this.config.skipModels?.includes(request.model)) {
54
+ return true;
55
+ }
56
+ if (this.config.skipToolRequests && request.tools?.length) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ buildOptions(request) {
62
+ const options = {};
63
+ if (this.config.defaultTTL !== void 0) {
64
+ options.ttl = this.config.defaultTTL;
65
+ }
66
+ if (this.config.tagPrefix) {
67
+ options.tags = [`${this.config.tagPrefix}:${request.model}`];
68
+ }
69
+ if (this.config.getUserId) {
70
+ options.userId = this.config.getUserId(request);
71
+ }
72
+ if (this.config.getAgentId) {
73
+ options.agentId = this.config.getAgentId(request);
74
+ }
75
+ return options;
76
+ }
77
+ };
78
+ function createCacheMiddleware(config) {
79
+ return new CacheMiddleware(config);
80
+ }
81
+
82
+ // src/integrations/agentsea/CachedProvider.ts
83
+ var CachedProvider = class {
84
+ provider;
85
+ cache;
86
+ config;
87
+ constructor(config) {
88
+ this.provider = config.provider;
89
+ this.cache = config.cache;
90
+ this.config = config;
91
+ }
92
+ /**
93
+ * Generate a completion with caching
94
+ */
95
+ async complete(request) {
96
+ if (this.config.skipModels?.includes(request.model)) {
97
+ return this.provider.complete(request);
98
+ }
99
+ const options = {
100
+ ...this.config.defaultOptions
101
+ };
102
+ return this.cache.wrap(
103
+ {
104
+ model: request.model,
105
+ messages: request.messages,
106
+ temperature: request.temperature,
107
+ maxTokens: request.maxTokens
108
+ },
109
+ async () => {
110
+ const response = await this.provider.complete(request);
111
+ return {
112
+ content: response.content,
113
+ model: response.model,
114
+ finishReason: response.finishReason,
115
+ usage: response.usage
116
+ };
117
+ },
118
+ options
119
+ );
120
+ }
121
+ /**
122
+ * Generate a streaming completion
123
+ *
124
+ * Note: Streaming responses are passed through without caching by default.
125
+ * Set enableStreamingCache to true for experimental streaming cache support.
126
+ */
127
+ async *stream(request) {
128
+ if (!this.provider.stream) {
129
+ throw new Error("Provider does not support streaming");
130
+ }
131
+ if (!this.config.enableStreamingCache) {
132
+ yield* this.provider.stream(request);
133
+ return;
134
+ }
135
+ const chunks = [];
136
+ let finishReason = "";
137
+ for await (const chunk of this.provider.stream(request)) {
138
+ if (chunk.content) {
139
+ chunks.push(chunk.content);
140
+ }
141
+ if (chunk.finishReason) {
142
+ finishReason = chunk.finishReason;
143
+ }
144
+ yield chunk;
145
+ }
146
+ try {
147
+ await this.cache.set(
148
+ {
149
+ model: request.model,
150
+ messages: request.messages,
151
+ temperature: request.temperature,
152
+ maxTokens: request.maxTokens
153
+ },
154
+ {
155
+ content: chunks.join(""),
156
+ model: request.model,
157
+ finishReason
158
+ }
159
+ );
160
+ } catch {
161
+ }
162
+ }
163
+ /**
164
+ * Get the underlying provider
165
+ */
166
+ getProvider() {
167
+ return this.provider;
168
+ }
169
+ /**
170
+ * Get the cache instance
171
+ */
172
+ getCache() {
173
+ return this.cache;
174
+ }
175
+ /**
176
+ * Clear cache entries for this provider
177
+ */
178
+ async clearCache() {
179
+ await this.cache.clear();
180
+ }
181
+ /**
182
+ * Get cache statistics
183
+ */
184
+ getCacheStats() {
185
+ return this.cache.getStats();
186
+ }
187
+ };
188
+ function createCachedProvider(config) {
189
+ return new CachedProvider(config);
190
+ }
191
+ function withCache(provider, cache, options) {
192
+ return new CachedProvider({
193
+ provider,
194
+ cache,
195
+ ...options
196
+ });
197
+ }
198
+
199
+ export { CacheMiddleware, CachedProvider, createCacheMiddleware, createCachedProvider, withCache };
200
+ //# sourceMappingURL=index.js.map
201
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/integrations/agentsea/CacheMiddleware.ts","../../../src/integrations/agentsea/CachedProvider.ts"],"names":[],"mappings":";AAkFO,IAAM,kBAAN,MAAsB;AAAA,EACnB,MAAA;AAAA,EAER,YAAY,MAAA,EAA+B;AACzC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,MAAA,CACJ,OAAA,EACA,IAAA,EAC6B;AAE7B,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,OAAO,CAAA,EAAG;AAC5B,MAAA,OAAO,KAAK,OAAO,CAAA;AAAA,IACrB;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,OAAO,CAAA;AAGzC,IAAA,OAAO,IAAA,CAAK,OAAO,KAAA,CAAM,IAAA;AAAA,MACvB;AAAA,QACE,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,aAAa,OAAA,CAAQ,WAAA;AAAA,QACrB,WAAW,OAAA,CAAQ;AAAA,OACrB;AAAA,MACA,YAAY;AACV,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,OAAO,CAAA;AACnC,QAAA,OAAO;AAAA,UACL,SAAS,QAAA,CAAS,OAAA;AAAA,UAClB,OAAO,QAAA,CAAS,KAAA;AAAA,UAChB,YAAA,EAAc,SAAS,YAAA,IAAgB,MAAA;AAAA,UACvC,OAAO,QAAA,CAAS;AAAA,SAClB;AAAA,MACF,CAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAA,GAGiC;AAC/B,IAAA,OAAO,CAAC,OAAA,EAAS,IAAA,KAAS,IAAA,CAAK,MAAA,CAAO,SAAS,IAAI,CAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,MAAA,EAA8C;AACtD,IAAA,IAAA,CAAK,SAAS,EAAE,GAAG,IAAA,CAAK,MAAA,EAAQ,GAAG,MAAA,EAAO;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA0B;AACxB,IAAA,OAAO,KAAK,MAAA,CAAO,KAAA;AAAA,EACrB;AAAA,EAEQ,WAAW,OAAA,EAAqC;AAEtD,IAAA,IAAI,KAAK,MAAA,CAAO,UAAA,EAAY,QAAA,CAAS,OAAA,CAAQ,KAAK,CAAA,EAAG;AACnD,MAAA,OAAO,IAAA;AAAA,IACT;AAGA,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,gBAAA,IAAoB,OAAA,CAAQ,OAAO,MAAA,EAAQ;AACzD,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,aAAa,OAAA,EAAyC;AAC5D,IAAA,MAAM,UAAuB,EAAC;AAE9B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,UAAA,KAAe,MAAA,EAAW;AACxC,MAAA,OAAA,CAAQ,GAAA,GAAM,KAAK,MAAA,CAAO,UAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,SAAA,EAAW;AACzB,MAAA,OAAA,CAAQ,IAAA,GAAO,CAAC,CAAA,EAAG,IAAA,CAAK,OAAO,SAAS,CAAA,CAAA,EAAI,OAAA,CAAQ,KAAK,CAAA,CAAE,CAAA;AAAA,IAC7D;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,SAAA,EAAW;AACzB,MAAA,OAAA,CAAQ,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,SAAA,CAAU,OAAO,CAAA;AAAA,IAChD;AAEA,IAAA,IAAI,IAAA,CAAK,OAAO,UAAA,EAAY;AAC1B,MAAA,OAAA,CAAQ,OAAA,GAAU,IAAA,CAAK,MAAA,CAAO,UAAA,CAAW,OAAO,CAAA;AAAA,IAClD;AAEA,IAAA,OAAO,OAAA;AAAA,EACT;AACF;AAKO,SAAS,sBACd,MAAA,EACiB;AACjB,EAAA,OAAO,IAAI,gBAAgB,MAAM,CAAA;AACnC;;;AChGO,IAAM,iBAAN,MAA4C;AAAA,EACzC,QAAA;AAAA,EACA,KAAA;AAAA,EACA,MAAA;AAAA,EAER,YAAY,MAAA,EAA8B;AACxC,IAAA,IAAA,CAAK,WAAW,MAAA,CAAO,QAAA;AACvB,IAAA,IAAA,CAAK,QAAQ,MAAA,CAAO,KAAA;AACpB,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,SAAS,OAAA,EAAyD;AAEtE,IAAA,IAAI,KAAK,MAAA,CAAO,UAAA,EAAY,QAAA,CAAS,OAAA,CAAQ,KAAK,CAAA,EAAG;AACnD,MAAA,OAAO,IAAA,CAAK,QAAA,CAAS,QAAA,CAAS,OAAO,CAAA;AAAA,IACvC;AAGA,IAAA,MAAM,OAAA,GAAuB;AAAA,MAC3B,GAAG,KAAK,MAAA,CAAO;AAAA,KACjB;AAGA,IAAA,OAAO,KAAK,KAAA,CAAM,IAAA;AAAA,MAChB;AAAA,QACE,OAAO,OAAA,CAAQ,KAAA;AAAA,QACf,UAAU,OAAA,CAAQ,QAAA;AAAA,QAClB,aAAa,OAAA,CAAQ,WAAA;AAAA,QACrB,WAAW,OAAA,CAAQ;AAAA,OACrB;AAAA,MACA,YAAY;AACV,QAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,QAAA,CAAS,SAAS,OAAO,CAAA;AACrD,QAAA,OAAO;AAAA,UACL,SAAS,QAAA,CAAS,OAAA;AAAA,UAClB,OAAO,QAAA,CAAS,KAAA;AAAA,UAChB,cAAc,QAAA,CAAS,YAAA;AAAA,UACvB,OAAO,QAAA,CAAS;AAAA,SAClB;AAAA,MACF,CAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,OAAO,OAAA,EAAyD;AAErE,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ;AACzB,MAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,IACvD;AAIA,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,oBAAA,EAAsB;AACrC,MAAA,OAAO,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA;AACnC,MAAA;AAAA,IACF;AAGA,IAAA,MAAM,SAAmB,EAAC;AAC1B,IAAA,IAAI,YAAA,GAAe,EAAA;AAEnB,IAAA,WAAA,MAAiB,KAAA,IAAS,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,OAAO,CAAA,EAAG;AACvD,MAAA,IAAI,MAAM,OAAA,EAAS;AACjB,QAAA,MAAA,CAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,MAC3B;AACA,MAAA,IAAI,MAAM,YAAA,EAAc;AACtB,QAAA,YAAA,GAAe,KAAA,CAAM,YAAA;AAAA,MACvB;AACA,MAAA,MAAM,KAAA;AAAA,IACR;AAGA,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,KAAA,CAAM,GAAA;AAAA,QACf;AAAA,UACE,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf,UAAU,OAAA,CAAQ,QAAA;AAAA,UAClB,aAAa,OAAA,CAAQ,WAAA;AAAA,UACrB,WAAW,OAAA,CAAQ;AAAA,SACrB;AAAA,QACA;AAAA,UACE,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,UACvB,OAAO,OAAA,CAAQ,KAAA;AAAA,UACf;AAAA;AACF,OACF;AAAA,IACF,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,GAA2B;AACzB,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAA,GAA0B;AACxB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,MAAM,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,aAAA,GAAgB;AACd,IAAA,OAAO,IAAA,CAAK,MAAM,QAAA,EAAS;AAAA,EAC7B;AACF;AAKO,SAAS,qBACd,MAAA,EACgB;AAChB,EAAA,OAAO,IAAI,eAAe,MAAM,CAAA;AAClC;AAKO,SAAS,SAAA,CACd,QAAA,EACA,KAAA,EACA,OAAA,EACgB;AAChB,EAAA,OAAO,IAAI,cAAA,CAAe;AAAA,IACxB,QAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AACH","file":"index.js","sourcesContent":["/**\n * CacheMiddleware\n *\n * Middleware for integrating semantic cache with AgentSea agents.\n */\n\nimport type { SemanticCache } from '../../core/SemanticCache.js';\nimport type { CacheMessage, WrapOptions } from '../../types/index.js';\n\n/**\n * Middleware request\n */\nexport interface MiddlewareRequest {\n model: string;\n messages: CacheMessage[];\n temperature?: number;\n maxTokens?: number;\n tools?: unknown[];\n [key: string]: unknown;\n}\n\n/**\n * Middleware response\n */\nexport interface MiddlewareResponse {\n content: string;\n model: string;\n finishReason?: string;\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n toolCalls?: unknown[];\n [key: string]: unknown;\n}\n\n/**\n * Next function in middleware chain\n */\nexport type MiddlewareNext = (\n request: MiddlewareRequest,\n) => Promise<MiddlewareResponse>;\n\n/**\n * Middleware configuration\n */\nexport interface CacheMiddlewareConfig {\n /** Cache instance */\n cache: SemanticCache;\n /** Skip cache for specific models */\n skipModels?: string[];\n /** Skip cache for tool-using requests */\n skipToolRequests?: boolean;\n /** Default TTL for cached entries */\n defaultTTL?: number;\n /** Tag prefix for cached entries */\n tagPrefix?: string;\n /** User ID extractor */\n getUserId?: (request: MiddlewareRequest) => string | undefined;\n /** Agent ID extractor */\n getAgentId?: (request: MiddlewareRequest) => string | undefined;\n /** Custom key generator */\n keyGenerator?: (request: MiddlewareRequest) => string;\n}\n\n/**\n * CacheMiddleware\n *\n * Middleware that adds semantic caching to LLM requests.\n *\n * @example\n * ```typescript\n * const middleware = new CacheMiddleware({\n * cache: semanticCache,\n * skipToolRequests: true\n * });\n *\n * // Use in agent pipeline\n * const response = await middleware.handle(request, next);\n * ```\n */\nexport class CacheMiddleware {\n private config: CacheMiddlewareConfig;\n\n constructor(config: CacheMiddlewareConfig) {\n this.config = config;\n }\n\n /**\n * Handle a request with caching\n */\n async handle(\n request: MiddlewareRequest,\n next: MiddlewareNext,\n ): Promise<MiddlewareResponse> {\n // Check if we should skip caching\n if (this.shouldSkip(request)) {\n return next(request);\n }\n\n const options = this.buildOptions(request);\n\n // Use cache.wrap to handle caching transparently\n return this.config.cache.wrap(\n {\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n },\n async () => {\n const response = await next(request);\n return {\n content: response.content,\n model: response.model,\n finishReason: response.finishReason ?? 'stop',\n usage: response.usage,\n };\n },\n options,\n );\n }\n\n /**\n * Create express-style middleware function\n */\n middleware(): (\n request: MiddlewareRequest,\n next: MiddlewareNext,\n ) => Promise<MiddlewareResponse> {\n return (request, next) => this.handle(request, next);\n }\n\n /**\n * Update configuration\n */\n configure(config: Partial<CacheMiddlewareConfig>): void {\n this.config = { ...this.config, ...config };\n }\n\n /**\n * Get the underlying cache instance\n */\n getCache(): SemanticCache {\n return this.config.cache;\n }\n\n private shouldSkip(request: MiddlewareRequest): boolean {\n // Skip if model is in skip list\n if (this.config.skipModels?.includes(request.model)) {\n return true;\n }\n\n // Skip if request has tools and skipToolRequests is enabled\n if (this.config.skipToolRequests && request.tools?.length) {\n return true;\n }\n\n return false;\n }\n\n private buildOptions(request: MiddlewareRequest): WrapOptions {\n const options: WrapOptions = {};\n\n if (this.config.defaultTTL !== undefined) {\n options.ttl = this.config.defaultTTL;\n }\n\n if (this.config.tagPrefix) {\n options.tags = [`${this.config.tagPrefix}:${request.model}`];\n }\n\n if (this.config.getUserId) {\n options.userId = this.config.getUserId(request);\n }\n\n if (this.config.getAgentId) {\n options.agentId = this.config.getAgentId(request);\n }\n\n return options;\n }\n}\n\n/**\n * Create a CacheMiddleware instance\n */\nexport function createCacheMiddleware(\n config: CacheMiddlewareConfig,\n): CacheMiddleware {\n return new CacheMiddleware(config);\n}\n","/**\n * CachedProvider\n *\n * Wrapper for LLM providers that adds semantic caching.\n */\n\nimport type { SemanticCache } from '../../core/SemanticCache.js';\nimport type { CacheMessage, WrapOptions } from '../../types/index.js';\n\n/**\n * LLM Provider interface (compatible with AgentSea providers)\n */\nexport interface LLMProvider {\n /**\n * Generate a completion\n */\n complete(request: CompletionRequest): Promise<CompletionResponse>;\n\n /**\n * Generate a streaming completion\n */\n stream?(request: CompletionRequest): AsyncGenerator<StreamChunk>;\n}\n\n/**\n * Completion request\n */\nexport interface CompletionRequest {\n model: string;\n messages: CacheMessage[];\n temperature?: number;\n maxTokens?: number;\n tools?: unknown[];\n stream?: boolean;\n [key: string]: unknown;\n}\n\n/**\n * Completion response\n */\nexport interface CompletionResponse {\n content: string;\n model: string;\n finishReason: string;\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n toolCalls?: unknown[];\n}\n\n/**\n * Stream chunk\n */\nexport interface StreamChunk {\n content?: string;\n finishReason?: string;\n toolCall?: unknown;\n}\n\n/**\n * Cached provider configuration\n */\nexport interface CachedProviderConfig {\n /** Underlying LLM provider */\n provider: LLMProvider;\n /** Semantic cache instance */\n cache: SemanticCache;\n /** Skip caching for certain models */\n skipModels?: string[];\n /** Default cache options */\n defaultOptions?: WrapOptions;\n /** Enable streaming cache */\n enableStreamingCache?: boolean;\n}\n\n/**\n * CachedProvider\n *\n * Wraps an LLM provider with semantic caching.\n *\n * @example\n * ```typescript\n * const cachedProvider = new CachedProvider({\n * provider: anthropicProvider,\n * cache: semanticCache\n * });\n *\n * // Uses cache transparently\n * const response = await cachedProvider.complete({\n * model: 'claude-3-sonnet',\n * messages: [{ role: 'user', content: 'Hello' }]\n * });\n * ```\n */\nexport class CachedProvider implements LLMProvider {\n private provider: LLMProvider;\n private cache: SemanticCache;\n private config: CachedProviderConfig;\n\n constructor(config: CachedProviderConfig) {\n this.provider = config.provider;\n this.cache = config.cache;\n this.config = config;\n }\n\n /**\n * Generate a completion with caching\n */\n async complete(request: CompletionRequest): Promise<CompletionResponse> {\n // Skip cache if model is in skip list\n if (this.config.skipModels?.includes(request.model)) {\n return this.provider.complete(request);\n }\n\n // Build cache options\n const options: WrapOptions = {\n ...this.config.defaultOptions,\n };\n\n // Use cache.wrap to handle caching\n return this.cache.wrap(\n {\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n },\n async () => {\n const response = await this.provider.complete(request);\n return {\n content: response.content,\n model: response.model,\n finishReason: response.finishReason,\n usage: response.usage,\n };\n },\n options,\n );\n }\n\n /**\n * Generate a streaming completion\n *\n * Note: Streaming responses are passed through without caching by default.\n * Set enableStreamingCache to true for experimental streaming cache support.\n */\n async *stream(request: CompletionRequest): AsyncGenerator<StreamChunk> {\n // Check if provider supports streaming\n if (!this.provider.stream) {\n throw new Error('Provider does not support streaming');\n }\n\n // For now, pass through streaming without caching\n // Streaming cache support would require StreamCache integration\n if (!this.config.enableStreamingCache) {\n yield* this.provider.stream(request);\n return;\n }\n\n // Experimental: Collect stream for caching\n const chunks: string[] = [];\n let finishReason = '';\n\n for await (const chunk of this.provider.stream(request)) {\n if (chunk.content) {\n chunks.push(chunk.content);\n }\n if (chunk.finishReason) {\n finishReason = chunk.finishReason;\n }\n yield chunk;\n }\n\n // Cache the complete response after stream ends\n try {\n await this.cache.set(\n {\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n },\n {\n content: chunks.join(''),\n model: request.model,\n finishReason,\n },\n );\n } catch {\n // Silently ignore cache errors during streaming\n }\n }\n\n /**\n * Get the underlying provider\n */\n getProvider(): LLMProvider {\n return this.provider;\n }\n\n /**\n * Get the cache instance\n */\n getCache(): SemanticCache {\n return this.cache;\n }\n\n /**\n * Clear cache entries for this provider\n */\n async clearCache(): Promise<void> {\n await this.cache.clear();\n }\n\n /**\n * Get cache statistics\n */\n getCacheStats() {\n return this.cache.getStats();\n }\n}\n\n/**\n * Create a CachedProvider instance\n */\nexport function createCachedProvider(\n config: CachedProviderConfig,\n): CachedProvider {\n return new CachedProvider(config);\n}\n\n/**\n * Helper to wrap any LLM provider with caching\n */\nexport function withCache(\n provider: LLMProvider,\n cache: SemanticCache,\n options?: Partial<CachedProviderConfig>,\n): CachedProvider {\n return new CachedProvider({\n provider,\n cache,\n ...options,\n });\n}\n"]}
@@ -0,0 +1,98 @@
1
+ import EventEmitter from 'eventemitter3';
2
+ import { S as SemanticCache } from '../../SemanticCache-vysguwUQ.js';
3
+ import { C as CacheMessage, a as CacheLookupResult } from '../../cache.types-DMuyQseO.js';
4
+ import '../../store.types-BQy5Yyz9.js';
5
+ import '../../BaseMatchStrategy-1E1SHaUt.js';
6
+ import '../../SimilarityEngine-Cwv_mF9a.js';
7
+ import '../../analytics/index.js';
8
+
9
+ interface GatewayRequest {
10
+ id: string;
11
+ provider: string;
12
+ model: string;
13
+ messages: CacheMessage[];
14
+ temperature?: number;
15
+ maxTokens?: number;
16
+ stream?: boolean;
17
+ parameters?: Record<string, unknown>;
18
+ metadata?: {
19
+ userId?: string;
20
+ agentId?: string;
21
+ namespace?: string;
22
+ [key: string]: unknown;
23
+ };
24
+ }
25
+ interface GatewayResponse {
26
+ id: string;
27
+ provider: string;
28
+ model: string;
29
+ content: string;
30
+ finishReason: string;
31
+ usage?: {
32
+ promptTokens: number;
33
+ completionTokens: number;
34
+ totalTokens: number;
35
+ };
36
+ toolCalls?: unknown[];
37
+ metadata?: Record<string, unknown>;
38
+ }
39
+ interface GatewayCacheEvents {
40
+ 'cache:hit': (request: GatewayRequest, result: CacheLookupResult) => void;
41
+ 'cache:miss': (request: GatewayRequest) => void;
42
+ 'cache:set': (request: GatewayRequest, response: GatewayResponse) => void;
43
+ 'cache:error': (error: Error, request: GatewayRequest) => void;
44
+ }
45
+ interface GatewayCacheConfig {
46
+ cache: SemanticCache;
47
+ enabled?: boolean;
48
+ skipStreaming?: boolean;
49
+ skipProviders?: string[];
50
+ skipModels?: string[];
51
+ defaultTTL?: number;
52
+ namespace?: string;
53
+ keyGenerator?: (request: GatewayRequest) => string;
54
+ }
55
+ interface GatewayCacheStats {
56
+ totalRequests: number;
57
+ cacheHits: number;
58
+ cacheMisses: number;
59
+ hitRate: number;
60
+ avgLatencyMs: number;
61
+ byProvider: Record<string, {
62
+ hits: number;
63
+ misses: number;
64
+ }>;
65
+ byModel: Record<string, {
66
+ hits: number;
67
+ misses: number;
68
+ }>;
69
+ }
70
+ declare class GatewayCache extends EventEmitter<GatewayCacheEvents> {
71
+ private cache;
72
+ private config;
73
+ private stats;
74
+ private latencies;
75
+ constructor(config: GatewayCacheConfig);
76
+ get(request: GatewayRequest): Promise<{
77
+ hit: boolean;
78
+ response?: GatewayResponse;
79
+ similarity?: number;
80
+ }>;
81
+ set(request: GatewayRequest, response: GatewayResponse): Promise<void>;
82
+ invalidate(criteria: {
83
+ provider?: string;
84
+ model?: string;
85
+ namespace?: string;
86
+ olderThan?: number;
87
+ }): Promise<number>;
88
+ getStats(): GatewayCacheStats;
89
+ resetStats(): void;
90
+ isEnabled(): boolean;
91
+ setEnabled(enabled: boolean): void;
92
+ getCache(): SemanticCache;
93
+ private shouldCache;
94
+ private updateStats;
95
+ }
96
+ declare function createGatewayCache(config: GatewayCacheConfig): GatewayCache;
97
+
98
+ export { GatewayCache, type GatewayCacheConfig, type GatewayCacheEvents, type GatewayCacheStats, type GatewayRequest, type GatewayResponse, createGatewayCache };
@@ -0,0 +1,205 @@
1
+ import EventEmitter from 'eventemitter3';
2
+
3
+ // src/integrations/gateway/GatewayCache.ts
4
+ var GatewayCache = class extends EventEmitter {
5
+ cache;
6
+ config;
7
+ stats = {
8
+ totalRequests: 0,
9
+ cacheHits: 0,
10
+ cacheMisses: 0,
11
+ hitRate: 0,
12
+ avgLatencyMs: 0,
13
+ byProvider: {},
14
+ byModel: {}
15
+ };
16
+ latencies = [];
17
+ constructor(config) {
18
+ super();
19
+ this.cache = config.cache;
20
+ this.config = {
21
+ enabled: true,
22
+ skipStreaming: true,
23
+ ...config
24
+ };
25
+ }
26
+ /**
27
+ * Get cached response for a request
28
+ */
29
+ async get(request) {
30
+ const startTime = performance.now();
31
+ this.stats.totalRequests++;
32
+ if (!this.shouldCache(request)) {
33
+ this.stats.cacheMisses++;
34
+ this.updateStats(request, false);
35
+ return { hit: false };
36
+ }
37
+ try {
38
+ const result = await this.cache.get({
39
+ model: request.model,
40
+ messages: request.messages,
41
+ temperature: request.temperature,
42
+ maxTokens: request.maxTokens
43
+ });
44
+ const latency = performance.now() - startTime;
45
+ this.latencies.push(latency);
46
+ if (result.hit && result.entry) {
47
+ this.stats.cacheHits++;
48
+ this.updateStats(request, true);
49
+ const response = {
50
+ id: request.id,
51
+ provider: request.provider,
52
+ model: result.entry.response.model,
53
+ content: result.entry.response.content,
54
+ finishReason: result.entry.response.finishReason,
55
+ usage: result.entry.response.usage,
56
+ metadata: {
57
+ cached: true,
58
+ cacheHit: result.source,
59
+ similarity: result.similarity,
60
+ cachedAt: result.entry.metadata.createdAt
61
+ }
62
+ };
63
+ this.emit("cache:hit", request, result);
64
+ return { hit: true, response, similarity: result.similarity };
65
+ }
66
+ this.stats.cacheMisses++;
67
+ this.updateStats(request, false);
68
+ this.emit("cache:miss", request);
69
+ return { hit: false };
70
+ } catch (error) {
71
+ this.emit("cache:error", error, request);
72
+ return { hit: false };
73
+ }
74
+ }
75
+ /**
76
+ * Cache a response
77
+ */
78
+ async set(request, response) {
79
+ if (!this.shouldCache(request)) {
80
+ return;
81
+ }
82
+ try {
83
+ await this.cache.set(
84
+ {
85
+ model: request.model,
86
+ messages: request.messages,
87
+ temperature: request.temperature,
88
+ maxTokens: request.maxTokens
89
+ },
90
+ {
91
+ content: response.content,
92
+ model: response.model,
93
+ finishReason: response.finishReason,
94
+ usage: response.usage
95
+ },
96
+ {
97
+ ttl: this.config.defaultTTL,
98
+ namespace: this.config.namespace ?? request.metadata?.namespace,
99
+ userId: request.metadata?.userId,
100
+ agentId: request.metadata?.agentId
101
+ }
102
+ );
103
+ this.emit("cache:set", request, response);
104
+ } catch (error) {
105
+ this.emit("cache:error", error, request);
106
+ }
107
+ }
108
+ /**
109
+ * Invalidate cache entries matching criteria
110
+ */
111
+ async invalidate(criteria) {
112
+ if (!criteria.provider && !criteria.model && !criteria.namespace) {
113
+ await this.cache.clear();
114
+ return 0;
115
+ }
116
+ return 0;
117
+ }
118
+ /**
119
+ * Get cache statistics
120
+ */
121
+ getStats() {
122
+ return {
123
+ ...this.stats,
124
+ hitRate: this.stats.totalRequests > 0 ? this.stats.cacheHits / this.stats.totalRequests * 100 : 0,
125
+ avgLatencyMs: this.latencies.length > 0 ? this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length : 0
126
+ };
127
+ }
128
+ /**
129
+ * Reset statistics
130
+ */
131
+ resetStats() {
132
+ this.stats = {
133
+ totalRequests: 0,
134
+ cacheHits: 0,
135
+ cacheMisses: 0,
136
+ hitRate: 0,
137
+ avgLatencyMs: 0,
138
+ byProvider: {},
139
+ byModel: {}
140
+ };
141
+ this.latencies = [];
142
+ }
143
+ /**
144
+ * Check if caching is enabled
145
+ */
146
+ isEnabled() {
147
+ return this.config.enabled ?? true;
148
+ }
149
+ /**
150
+ * Enable or disable caching
151
+ */
152
+ setEnabled(enabled) {
153
+ this.config.enabled = enabled;
154
+ }
155
+ /**
156
+ * Get the underlying cache
157
+ */
158
+ getCache() {
159
+ return this.cache;
160
+ }
161
+ shouldCache(request) {
162
+ if (!this.config.enabled) {
163
+ return false;
164
+ }
165
+ if (this.config.skipStreaming && request.stream) {
166
+ return false;
167
+ }
168
+ if (this.config.skipProviders?.includes(request.provider)) {
169
+ return false;
170
+ }
171
+ if (this.config.skipModels?.includes(request.model)) {
172
+ return false;
173
+ }
174
+ return true;
175
+ }
176
+ updateStats(request, hit) {
177
+ if (!this.stats.byProvider[request.provider]) {
178
+ this.stats.byProvider[request.provider] = { hits: 0, misses: 0 };
179
+ }
180
+ if (hit) {
181
+ this.stats.byProvider[request.provider].hits++;
182
+ } else {
183
+ this.stats.byProvider[request.provider].misses++;
184
+ }
185
+ if (!this.stats.byModel[request.model]) {
186
+ this.stats.byModel[request.model] = { hits: 0, misses: 0 };
187
+ }
188
+ if (hit) {
189
+ this.stats.byModel[request.model].hits++;
190
+ } else {
191
+ this.stats.byModel[request.model].misses++;
192
+ }
193
+ this.stats.hitRate = this.stats.totalRequests > 0 ? this.stats.cacheHits / this.stats.totalRequests * 100 : 0;
194
+ if (this.latencies.length > 0) {
195
+ this.stats.avgLatencyMs = this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;
196
+ }
197
+ }
198
+ };
199
+ function createGatewayCache(config) {
200
+ return new GatewayCache(config);
201
+ }
202
+
203
+ export { GatewayCache, createGatewayCache };
204
+ //# sourceMappingURL=index.js.map
205
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/integrations/gateway/GatewayCache.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * GatewayCache\n *\n * Cache layer for LLM Gateway integration.\n */\n\nimport EventEmitter from 'eventemitter3';\nimport type { SemanticCache } from '../../core/SemanticCache.js';\nimport type { CacheMessage, CacheLookupResult } from '../../types/index.js';\n\n/**\n * Gateway request format\n */\nexport interface GatewayRequest {\n /** Request ID */\n id: string;\n /** Target provider (e.g., 'openai', 'anthropic') */\n provider: string;\n /** Model name */\n model: string;\n /** Messages */\n messages: CacheMessage[];\n /** Temperature */\n temperature?: number;\n /** Max tokens */\n maxTokens?: number;\n /** Stream mode */\n stream?: boolean;\n /** Additional parameters */\n parameters?: Record<string, unknown>;\n /** Request metadata */\n metadata?: {\n userId?: string;\n agentId?: string;\n namespace?: string;\n [key: string]: unknown;\n };\n}\n\n/**\n * Gateway response format\n */\nexport interface GatewayResponse {\n /** Request ID */\n id: string;\n /** Provider used */\n provider: string;\n /** Model used */\n model: string;\n /** Response content */\n content: string;\n /** Finish reason */\n finishReason: string;\n /** Token usage */\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n /** Tool calls */\n toolCalls?: unknown[];\n /** Response metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Gateway cache events\n */\nexport interface GatewayCacheEvents {\n 'cache:hit': (request: GatewayRequest, result: CacheLookupResult) => void;\n 'cache:miss': (request: GatewayRequest) => void;\n 'cache:set': (request: GatewayRequest, response: GatewayResponse) => void;\n 'cache:error': (error: Error, request: GatewayRequest) => void;\n}\n\n/**\n * Gateway cache configuration\n */\nexport interface GatewayCacheConfig {\n /** Semantic cache instance */\n cache: SemanticCache;\n /** Enable caching */\n enabled?: boolean;\n /** Skip caching for streaming requests */\n skipStreaming?: boolean;\n /** Skip caching for specific providers */\n skipProviders?: string[];\n /** Skip caching for specific models */\n skipModels?: string[];\n /** Default TTL in seconds */\n defaultTTL?: number;\n /** Namespace for cache isolation */\n namespace?: string;\n /** Custom key generator */\n keyGenerator?: (request: GatewayRequest) => string;\n}\n\n/**\n * Gateway cache statistics\n */\nexport interface GatewayCacheStats {\n totalRequests: number;\n cacheHits: number;\n cacheMisses: number;\n hitRate: number;\n avgLatencyMs: number;\n byProvider: Record<string, { hits: number; misses: number }>;\n byModel: Record<string, { hits: number; misses: number }>;\n}\n\n/**\n * GatewayCache\n *\n * Cache layer for LLM Gateway requests.\n *\n * @example\n * ```typescript\n * const gatewayCache = new GatewayCache({\n * cache: semanticCache,\n * skipStreaming: true\n * });\n *\n * // Check cache before routing\n * const cached = await gatewayCache.get(request);\n * if (cached.hit) {\n * return cached.response;\n * }\n *\n * // After getting response from provider\n * await gatewayCache.set(request, response);\n * ```\n */\nexport class GatewayCache extends EventEmitter<GatewayCacheEvents> {\n private cache: SemanticCache;\n private config: GatewayCacheConfig;\n private stats: GatewayCacheStats = {\n totalRequests: 0,\n cacheHits: 0,\n cacheMisses: 0,\n hitRate: 0,\n avgLatencyMs: 0,\n byProvider: {},\n byModel: {},\n };\n private latencies: number[] = [];\n\n constructor(config: GatewayCacheConfig) {\n super();\n this.cache = config.cache;\n this.config = {\n enabled: true,\n skipStreaming: true,\n ...config,\n };\n }\n\n /**\n * Get cached response for a request\n */\n async get(request: GatewayRequest): Promise<{\n hit: boolean;\n response?: GatewayResponse;\n similarity?: number;\n }> {\n const startTime = performance.now();\n this.stats.totalRequests++;\n\n // Check if caching is disabled or should be skipped\n if (!this.shouldCache(request)) {\n this.stats.cacheMisses++;\n this.updateStats(request, false);\n return { hit: false };\n }\n\n try {\n const result = await this.cache.get({\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n });\n\n const latency = performance.now() - startTime;\n this.latencies.push(latency);\n\n if (result.hit && result.entry) {\n this.stats.cacheHits++;\n this.updateStats(request, true);\n\n const response: GatewayResponse = {\n id: request.id,\n provider: request.provider,\n model: result.entry.response.model,\n content: result.entry.response.content,\n finishReason: result.entry.response.finishReason,\n usage: result.entry.response.usage,\n metadata: {\n cached: true,\n cacheHit: result.source,\n similarity: result.similarity,\n cachedAt: result.entry.metadata.createdAt,\n },\n };\n\n this.emit('cache:hit', request, result);\n return { hit: true, response, similarity: result.similarity };\n }\n\n this.stats.cacheMisses++;\n this.updateStats(request, false);\n this.emit('cache:miss', request);\n return { hit: false };\n } catch (error) {\n this.emit('cache:error', error as Error, request);\n return { hit: false };\n }\n }\n\n /**\n * Cache a response\n */\n async set(request: GatewayRequest, response: GatewayResponse): Promise<void> {\n if (!this.shouldCache(request)) {\n return;\n }\n\n try {\n await this.cache.set(\n {\n model: request.model,\n messages: request.messages,\n temperature: request.temperature,\n maxTokens: request.maxTokens,\n },\n {\n content: response.content,\n model: response.model,\n finishReason: response.finishReason,\n usage: response.usage,\n },\n {\n ttl: this.config.defaultTTL,\n namespace: this.config.namespace ?? request.metadata?.namespace,\n userId: request.metadata?.userId,\n agentId: request.metadata?.agentId,\n },\n );\n\n this.emit('cache:set', request, response);\n } catch (error) {\n this.emit('cache:error', error as Error, request);\n }\n }\n\n /**\n * Invalidate cache entries matching criteria\n */\n async invalidate(criteria: {\n provider?: string;\n model?: string;\n namespace?: string;\n olderThan?: number;\n }): Promise<number> {\n // For now, just clear all if criteria is empty\n // A more sophisticated implementation would filter entries\n if (!criteria.provider && !criteria.model && !criteria.namespace) {\n await this.cache.clear();\n return 0;\n }\n\n // This would need store-level support for filtered deletion\n // For now, return 0 indicating no entries removed\n return 0;\n }\n\n /**\n * Get cache statistics\n */\n getStats(): GatewayCacheStats {\n return {\n ...this.stats,\n hitRate:\n this.stats.totalRequests > 0\n ? (this.stats.cacheHits / this.stats.totalRequests) * 100\n : 0,\n avgLatencyMs:\n this.latencies.length > 0\n ? this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length\n : 0,\n };\n }\n\n /**\n * Reset statistics\n */\n resetStats(): void {\n this.stats = {\n totalRequests: 0,\n cacheHits: 0,\n cacheMisses: 0,\n hitRate: 0,\n avgLatencyMs: 0,\n byProvider: {},\n byModel: {},\n };\n this.latencies = [];\n }\n\n /**\n * Check if caching is enabled\n */\n isEnabled(): boolean {\n return this.config.enabled ?? true;\n }\n\n /**\n * Enable or disable caching\n */\n setEnabled(enabled: boolean): void {\n this.config.enabled = enabled;\n }\n\n /**\n * Get the underlying cache\n */\n getCache(): SemanticCache {\n return this.cache;\n }\n\n private shouldCache(request: GatewayRequest): boolean {\n // Check if disabled\n if (!this.config.enabled) {\n return false;\n }\n\n // Skip streaming requests\n if (this.config.skipStreaming && request.stream) {\n return false;\n }\n\n // Skip specific providers\n if (this.config.skipProviders?.includes(request.provider)) {\n return false;\n }\n\n // Skip specific models\n if (this.config.skipModels?.includes(request.model)) {\n return false;\n }\n\n return true;\n }\n\n private updateStats(request: GatewayRequest, hit: boolean): void {\n // Update provider stats\n if (!this.stats.byProvider[request.provider]) {\n this.stats.byProvider[request.provider] = { hits: 0, misses: 0 };\n }\n if (hit) {\n this.stats.byProvider[request.provider].hits++;\n } else {\n this.stats.byProvider[request.provider].misses++;\n }\n\n // Update model stats\n if (!this.stats.byModel[request.model]) {\n this.stats.byModel[request.model] = { hits: 0, misses: 0 };\n }\n if (hit) {\n this.stats.byModel[request.model].hits++;\n } else {\n this.stats.byModel[request.model].misses++;\n }\n\n // Update hit rate\n this.stats.hitRate =\n this.stats.totalRequests > 0\n ? (this.stats.cacheHits / this.stats.totalRequests) * 100\n : 0;\n\n // Update average latency\n if (this.latencies.length > 0) {\n this.stats.avgLatencyMs =\n this.latencies.reduce((a, b) => a + b, 0) / this.latencies.length;\n }\n }\n}\n\n/**\n * Create a GatewayCache instance\n */\nexport function createGatewayCache(config: GatewayCacheConfig): GatewayCache {\n return new GatewayCache(config);\n}\n"]}