@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 @@
1
+ {"version":3,"sources":["../../src/stores/BaseCacheStore.ts","../../src/core/utils.ts","../../src/stores/MemoryCacheStore.ts","../../src/similarity/metrics/SimilarityMetrics.ts","../../src/stores/RedisCacheStore.ts","../../src/stores/SQLiteCacheStore.ts","../../src/stores/TieredCacheStore.ts","../../src/stores/PineconeCacheStore.ts"],"names":["DEFAULT_CONFIG"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * BaseCacheStore\n *\n * Abstract base class for cache stores.\n * Follows the template method pattern.\n */\n\nimport type {\n CacheEntry,\n CacheBackendType,\n StoreConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n StoreMetrics,\n} from '../types/index.js';\n\n/**\n * Abstract base class for cache stores\n *\n * All store implementations must extend this class and implement\n * the abstract methods for their specific storage backend.\n */\nexport abstract class BaseCacheStore {\n /** Store type identifier */\n abstract readonly storeType: CacheBackendType;\n\n /** Store configuration */\n protected config: StoreConfig;\n\n /** Store metrics */\n protected metrics: StoreMetrics = {\n gets: 0,\n sets: 0,\n deletes: 0,\n hits: 0,\n misses: 0,\n };\n\n constructor(config: StoreConfig) {\n this.config = {\n namespace: config.namespace ?? 'default',\n ...config,\n };\n }\n\n /**\n * Get an entry by key (exact match)\n *\n * @param key - The cache key\n * @returns The cache entry or undefined if not found\n */\n abstract get(key: string): Promise<CacheEntry | undefined>;\n\n /**\n * Set an entry in the store\n *\n * @param key - The cache key\n * @param entry - The cache entry to store\n * @returns The result of the upsert operation\n */\n abstract set(key: string, entry: CacheEntry): Promise<UpsertResult>;\n\n /**\n * Check if a key exists in the store\n *\n * @param key - The cache key\n * @returns Whether the key exists\n */\n abstract has(key: string): Promise<boolean>;\n\n /**\n * Delete an entry from the store\n *\n * @param key - The cache key\n * @returns Whether the entry was deleted\n */\n abstract delete(key: string): Promise<boolean>;\n\n /**\n * Clear all entries from the store\n */\n abstract clear(): Promise<void>;\n\n /**\n * Get the number of entries in the store\n */\n abstract size(): Promise<number>;\n\n /**\n * Get all keys in the store\n */\n abstract keys(): Promise<string[]>;\n\n /**\n * Query by vector similarity (for semantic matching)\n *\n * @param vector - The query embedding vector\n * @param options - Query options\n * @returns Query results with similarity scores\n */\n abstract query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult>;\n\n /**\n * Check store health\n *\n * @returns Health status\n */\n abstract checkHealth(): Promise<StoreHealth>;\n\n /**\n * Close/cleanup the store\n */\n abstract close(): Promise<void>;\n\n /**\n * Get the store namespace\n */\n get namespace(): string {\n return this.config.namespace ?? 'default';\n }\n\n /**\n * Get store metrics\n */\n getMetrics(): StoreMetrics {\n return { ...this.metrics };\n }\n\n /**\n * Reset store metrics\n */\n resetMetrics(): void {\n this.metrics = {\n gets: 0,\n sets: 0,\n deletes: 0,\n hits: 0,\n misses: 0,\n };\n }\n\n /**\n * Increment a metric counter\n */\n protected incrementMetric(metric: keyof StoreMetrics, amount = 1): void {\n if (typeof this.metrics[metric] === 'number') {\n this.metrics[metric] += amount;\n }\n }\n}\n","/**\n * Core Utilities\n *\n * Helper functions for the semantic cache.\n */\n\nimport { nanoid } from 'nanoid';\n\n/**\n * Generate a unique ID with optional prefix\n */\nexport function generateId(prefix?: string): string {\n const id = nanoid(16);\n return prefix ? `${prefix}_${id}` : id;\n}\n\n/**\n * Get current timestamp in milliseconds\n */\nexport function now(): number {\n return Date.now();\n}\n\n/**\n * Check if an entry has expired based on TTL\n */\nexport function isExpired(createdAt: number, ttlSeconds: number): boolean {\n if (ttlSeconds <= 0) return false;\n return now() > createdAt + ttlSeconds * 1000;\n}\n\n/**\n * Estimate the size of an object in bytes\n */\nexport function estimateSize(obj: unknown): number {\n const str = JSON.stringify(obj);\n // Rough estimate: 2 bytes per character for UTF-16\n return str.length * 2;\n}\n\n/**\n * Estimate size of a cache entry\n */\nexport function estimateEntrySize(entry: {\n embedding?: number[];\n request: { messages: Array<{ content: string }> };\n response: { content: string };\n}): number {\n // Vector: 4 bytes per float32\n const vectorSize = (entry.embedding?.length ?? 0) * 4;\n\n // Content: roughly 2 bytes per character\n const messageSize = entry.request.messages.reduce(\n (acc, m) => acc + (m.content?.length ?? 0) * 2,\n 0,\n );\n const responseSize = (entry.response.content?.length ?? 0) * 2;\n\n // Metadata overhead\n const overheadSize = 500;\n\n return vectorSize + messageSize + responseSize + overheadSize;\n}\n\n/**\n * Sleep for a specified duration\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function retry<T>(\n fn: () => Promise<T>,\n options: {\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n } = {},\n): Promise<T> {\n const {\n maxAttempts = 3,\n initialDelayMs = 100,\n maxDelayMs = 5000,\n backoffMultiplier = 2,\n } = options;\n\n let lastError: Error | undefined;\n let delay = initialDelayMs;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxAttempts) {\n await sleep(delay);\n delay = Math.min(delay * backoffMultiplier, maxDelayMs);\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Chunk an array into smaller arrays\n */\nexport function chunk<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size));\n }\n return chunks;\n}\n\n/**\n * Deep clone an object\n */\nexport function deepClone<T>(obj: T): T {\n return JSON.parse(JSON.stringify(obj));\n}\n\n/**\n * Calculate percentile from an array of numbers\n */\nexport function percentile(values: number[], p: number): number {\n if (values.length === 0) return 0;\n const sorted = [...values].sort((a, b) => a - b);\n const index = Math.ceil((p / 100) * sorted.length) - 1;\n return sorted[Math.max(0, index)];\n}\n\n/**\n * Calculate mean of an array of numbers\n */\nexport function mean(values: number[]): number {\n if (values.length === 0) return 0;\n return values.reduce((a, b) => a + b, 0) / values.length;\n}\n","/**\n * MemoryCacheStore\n *\n * In-memory LRU cache store with vector search support.\n */\n\nimport { LRUCache } from 'lru-cache';\nimport { BaseCacheStore } from './BaseCacheStore.js';\nimport type {\n CacheEntry,\n CacheBackendType,\n MemoryStoreConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n} from '../types/index.js';\nimport { estimateEntrySize, now } from '../core/utils.js';\n\n/**\n * Default memory store configuration\n */\nconst DEFAULT_CONFIG: Partial<MemoryStoreConfig> = {\n maxEntries: 10000,\n maxSizeBytes: 1024 * 1024 * 1024, // 1GB\n evictionPolicy: 'lru',\n};\n\n/**\n * MemoryCacheStore\n *\n * In-memory cache store using LRU eviction.\n * Supports vector similarity search for semantic matching.\n *\n * @example\n * ```typescript\n * const store = new MemoryCacheStore({\n * type: 'memory',\n * maxEntries: 10000,\n * evictionPolicy: 'lru'\n * });\n *\n * await store.set('key', entry);\n * const result = await store.get('key');\n * ```\n */\nexport class MemoryCacheStore extends BaseCacheStore {\n readonly storeType: CacheBackendType = 'memory';\n\n private cache: LRUCache<string, CacheEntry>;\n private vectors: Map<string, { id: string; vector: number[] }> = new Map();\n private memoryConfig: MemoryStoreConfig;\n private closed = false;\n\n constructor(config: MemoryStoreConfig = { type: 'memory' }) {\n super(config);\n this.memoryConfig = { ...DEFAULT_CONFIG, ...config };\n\n this.cache = new LRUCache({\n max: this.memoryConfig.maxEntries ?? 10000,\n maxSize: this.memoryConfig.maxSizeBytes ?? 1024 * 1024 * 1024,\n sizeCalculation: (entry) => estimateEntrySize(entry),\n ttl: 0, // TTL handled per-entry\n updateAgeOnGet: true,\n allowStale: false,\n });\n }\n\n get(key: string): Promise<CacheEntry | undefined> {\n this.incrementMetric('gets');\n const entry = this.cache.get(key);\n\n if (entry) {\n this.incrementMetric('hits');\n // Update access metadata\n entry.metadata.accessedAt = now();\n entry.metadata.accessCount++;\n return Promise.resolve(entry);\n }\n\n this.incrementMetric('misses');\n return Promise.resolve(undefined);\n }\n\n set(key: string, entry: CacheEntry): Promise<UpsertResult> {\n const startTime = performance.now();\n this.incrementMetric('sets');\n\n // Set TTL if specified\n const ttlMs =\n entry.metadata.ttl > 0 ? entry.metadata.ttl * 1000 : undefined;\n\n this.cache.set(key, entry, { ttl: ttlMs });\n\n // Store vector for similarity search\n if (entry.embedding && entry.embedding.length > 0) {\n this.vectors.set(key, {\n id: entry.id,\n vector: entry.embedding,\n });\n }\n\n return Promise.resolve({\n success: true,\n id: entry.id,\n durationMs: performance.now() - startTime,\n });\n }\n\n has(key: string): Promise<boolean> {\n return Promise.resolve(this.cache.has(key));\n }\n\n delete(key: string): Promise<boolean> {\n this.incrementMetric('deletes');\n const existed = this.cache.has(key);\n this.cache.delete(key);\n this.vectors.delete(key);\n return Promise.resolve(existed);\n }\n\n clear(): Promise<void> {\n this.cache.clear();\n this.vectors.clear();\n return Promise.resolve();\n }\n\n size(): Promise<number> {\n return Promise.resolve(this.cache.size);\n }\n\n keys(): Promise<string[]> {\n return Promise.resolve(Array.from(this.cache.keys()));\n }\n\n query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult> {\n const startTime = performance.now();\n const topK = options?.topK ?? 10;\n const minSimilarity = options?.minSimilarity ?? 0;\n\n const results: Array<CacheEntry & { score: number }> = [];\n\n // Compute similarity for all vectors\n for (const [key, stored] of this.vectors) {\n // Filter by namespace if specified\n const entry = this.cache.get(key);\n if (!entry) continue;\n\n if (\n options?.namespace &&\n entry.metadata.namespace !== options.namespace\n ) {\n continue;\n }\n\n const similarity = this.cosineSimilarity(vector, stored.vector);\n\n if (similarity >= minSimilarity) {\n results.push({ ...entry, score: similarity });\n }\n }\n\n // Sort by score descending\n results.sort((a, b) => b.score - a.score);\n\n return Promise.resolve({\n entries: results.slice(0, topK),\n durationMs: performance.now() - startTime,\n });\n }\n\n checkHealth(): Promise<StoreHealth> {\n return Promise.resolve({\n healthy: !this.closed,\n latencyMs: 0,\n lastCheck: now(),\n error: this.closed ? 'Store is closed' : undefined,\n });\n }\n\n close(): Promise<void> {\n this.closed = true;\n this.cache.clear();\n this.vectors.clear();\n return Promise.resolve();\n }\n\n /**\n * Compute cosine similarity between two vectors\n */\n private cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n if (denominator === 0) return 0;\n\n return dotProduct / denominator;\n }\n\n /**\n * Get memory usage information\n */\n getMemoryInfo(): {\n entries: number;\n calculatedSize: number;\n maxSize: number;\n vectorCount: number;\n } {\n return {\n entries: this.cache.size,\n calculatedSize: this.cache.calculatedSize ?? 0,\n maxSize: this.memoryConfig.maxSizeBytes ?? 0,\n vectorCount: this.vectors.size,\n };\n }\n\n /**\n * Prune expired entries\n */\n prune(): Promise<number> {\n // LRUCache handles TTL automatically, but we can force a purge\n this.cache.purgeStale();\n\n // Clean up orphaned vectors\n let pruned = 0;\n for (const key of this.vectors.keys()) {\n if (!this.cache.has(key)) {\n this.vectors.delete(key);\n pruned++;\n }\n }\n\n return Promise.resolve(pruned);\n }\n}\n\n/**\n * Create a MemoryCacheStore instance\n */\nexport function createMemoryCacheStore(\n config?: Partial<MemoryStoreConfig>,\n): MemoryCacheStore {\n return new MemoryCacheStore({ type: 'memory', ...config });\n}\n","/**\n * Similarity Metrics\n *\n * Common similarity and distance metrics for vector comparison.\n */\n\n/**\n * Compute cosine similarity between two vectors\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns Similarity score between -1 and 1 (1 = identical)\n */\nexport function cosineSimilarity(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let dotProduct = 0;\n let normA = 0;\n let normB = 0;\n\n for (let i = 0; i < a.length; i++) {\n dotProduct += a[i] * b[i];\n normA += a[i] * a[i];\n normB += b[i] * b[i];\n }\n\n const denominator = Math.sqrt(normA) * Math.sqrt(normB);\n if (denominator === 0) return 0;\n\n return dotProduct / denominator;\n}\n\n/**\n * Compute Euclidean distance between two vectors\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns Distance (0 = identical, higher = more different)\n */\nexport function euclideanDistance(a: number[], b: number[]): number {\n if (a.length !== b.length) return Infinity;\n\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n const diff = a[i] - b[i];\n sum += diff * diff;\n }\n\n return Math.sqrt(sum);\n}\n\n/**\n * Compute dot product between two vectors\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns Dot product value\n */\nexport function dotProduct(a: number[], b: number[]): number {\n if (a.length !== b.length) return 0;\n\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n sum += a[i] * b[i];\n }\n\n return sum;\n}\n\n/**\n * Compute Manhattan distance between two vectors\n *\n * @param a - First vector\n * @param b - Second vector\n * @returns Distance (0 = identical, higher = more different)\n */\nexport function manhattanDistance(a: number[], b: number[]): number {\n if (a.length !== b.length) return Infinity;\n\n let sum = 0;\n for (let i = 0; i < a.length; i++) {\n sum += Math.abs(a[i] - b[i]);\n }\n\n return sum;\n}\n\n/**\n * Convert Euclidean distance to similarity (0-1)\n *\n * @param distance - Euclidean distance\n * @returns Similarity score between 0 and 1\n */\nexport function distanceToSimilarity(distance: number): number {\n return 1 / (1 + distance);\n}\n\n/**\n * Normalize a vector to unit length\n *\n * @param vector - Vector to normalize\n * @returns Normalized vector\n */\nexport function normalize(vector: number[]): number[] {\n const magnitude = Math.sqrt(vector.reduce((sum, v) => sum + v * v, 0));\n if (magnitude === 0) return vector;\n return vector.map((v) => v / magnitude);\n}\n\n/**\n * Compute the magnitude (L2 norm) of a vector\n *\n * @param vector - Vector\n * @returns Magnitude\n */\nexport function magnitude(vector: number[]): number {\n return Math.sqrt(vector.reduce((sum, v) => sum + v * v, 0));\n}\n","/**\n * RedisCacheStore\n *\n * Redis-based cache store for distributed caching.\n */\n\nimport { BaseCacheStore } from './BaseCacheStore.js';\nimport type {\n CacheEntry,\n CacheBackendType,\n RedisStoreConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n} from '../types/index.js';\nimport { now } from '../core/utils.js';\nimport { cosineSimilarity } from '../similarity/metrics/SimilarityMetrics.js';\n\n/**\n * Redis client interface (compatible with ioredis)\n */\ninterface RedisClient {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, ...args: unknown[]): Promise<unknown>;\n del(...keys: string[]): Promise<number>;\n exists(...keys: string[]): Promise<number>;\n keys(pattern: string): Promise<string[]>;\n quit(): Promise<unknown>;\n ping(): Promise<string>;\n expire(key: string, seconds: number): Promise<number>;\n}\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Partial<RedisStoreConfig> = {\n host: 'localhost',\n port: 6379,\n db: 0,\n keyPrefix: 'llm-cache',\n connectTimeout: 10000,\n};\n\n/**\n * RedisCacheStore\n *\n * Redis-based cache store for distributed caching scenarios.\n *\n * @example\n * ```typescript\n * const store = new RedisCacheStore({\n * type: 'redis',\n * url: 'redis://localhost:6379',\n * keyPrefix: 'my-app-cache'\n * });\n *\n * await store.connect();\n * await store.set('key', entry);\n * ```\n */\nexport class RedisCacheStore extends BaseCacheStore {\n readonly storeType: CacheBackendType = 'redis';\n\n private client: RedisClient | null = null;\n private redisConfig: RedisStoreConfig;\n private connected = false;\n\n constructor(config: RedisStoreConfig) {\n super(config);\n this.redisConfig = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Connect to Redis\n */\n async connect(): Promise<void> {\n if (this.connected) return;\n\n try {\n const { Redis } = await import('ioredis');\n\n if (this.redisConfig.url) {\n this.client = new Redis(this.redisConfig.url, {\n connectTimeout: this.redisConfig.connectTimeout ?? 10000,\n lazyConnect: false,\n tls: this.redisConfig.tls ? {} : undefined,\n }) as unknown as RedisClient;\n } else {\n this.client = new Redis({\n host: this.redisConfig.host ?? 'localhost',\n port: this.redisConfig.port ?? 6379,\n password: this.redisConfig.password,\n db: this.redisConfig.db ?? 0,\n connectTimeout: this.redisConfig.connectTimeout ?? 10000,\n tls: this.redisConfig.tls ? {} : undefined,\n }) as unknown as RedisClient;\n }\n\n await this.client.ping();\n this.connected = true;\n } catch (error) {\n throw new Error(\n `Failed to connect to Redis: ${(error as Error).message}`,\n );\n }\n }\n\n private async ensureConnected(): Promise<RedisClient> {\n if (!this.connected || !this.client) {\n await this.connect();\n }\n if (!this.client) {\n throw new Error('Redis client not initialized');\n }\n return this.client;\n }\n\n private prefixKey(key: string): string {\n const prefix = this.redisConfig.keyPrefix ?? 'llm-cache';\n return `${prefix}:${this.namespace}:${key}`;\n }\n\n async get(key: string): Promise<CacheEntry | undefined> {\n this.incrementMetric('gets');\n const client = await this.ensureConnected();\n const data = await client.get(this.prefixKey(key));\n\n if (!data) {\n this.incrementMetric('misses');\n return undefined;\n }\n\n this.incrementMetric('hits');\n try {\n const entry = JSON.parse(data) as CacheEntry;\n entry.metadata.accessedAt = now();\n entry.metadata.accessCount++;\n // Fire and forget update\n client.set(this.prefixKey(key), JSON.stringify(entry)).catch(() => {});\n return entry;\n } catch {\n return undefined;\n }\n }\n\n async set(key: string, entry: CacheEntry): Promise<UpsertResult> {\n const startTime = performance.now();\n this.incrementMetric('sets');\n const client = await this.ensureConnected();\n\n await client.set(this.prefixKey(key), JSON.stringify(entry));\n\n // Set TTL if specified\n if (entry.metadata.ttl > 0) {\n await client.expire(this.prefixKey(key), entry.metadata.ttl);\n }\n\n return {\n success: true,\n id: entry.id,\n durationMs: performance.now() - startTime,\n };\n }\n\n async has(key: string): Promise<boolean> {\n const client = await this.ensureConnected();\n return (await client.exists(this.prefixKey(key))) > 0;\n }\n\n async delete(key: string): Promise<boolean> {\n this.incrementMetric('deletes');\n const client = await this.ensureConnected();\n return (await client.del(this.prefixKey(key))) > 0;\n }\n\n async clear(): Promise<void> {\n const client = await this.ensureConnected();\n const pattern = this.prefixKey('*');\n const keys = await client.keys(pattern);\n if (keys.length > 0) {\n await client.del(...keys);\n }\n }\n\n async size(): Promise<number> {\n const client = await this.ensureConnected();\n const keys = await client.keys(this.prefixKey('*'));\n return keys.length;\n }\n\n async keys(): Promise<string[]> {\n const client = await this.ensureConnected();\n const keys = await client.keys(this.prefixKey('*'));\n const prefix = this.prefixKey('');\n return keys.map((k) => k.slice(prefix.length));\n }\n\n async query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult> {\n const startTime = performance.now();\n\n // Basic Redis doesn't support vector search natively.\n // For production, use Redis Stack with vector search.\n // This fallback loads entries and computes similarity client-side.\n\n const allKeys = await this.keys();\n const entries: Array<CacheEntry & { score: number }> = [];\n\n // Limit keys to process for performance\n const keysToProcess = allKeys.slice(0, 1000);\n\n for (const key of keysToProcess) {\n const entry = await this.get(key);\n if (entry?.embedding) {\n const score = cosineSimilarity(vector, entry.embedding);\n if (score >= (options?.minSimilarity ?? 0)) {\n // Filter by namespace if specified\n if (\n options?.namespace &&\n entry.metadata.namespace !== options.namespace\n ) {\n continue;\n }\n entries.push({ ...entry, score });\n }\n }\n }\n\n entries.sort((a, b) => b.score - a.score);\n\n return {\n entries: entries.slice(0, options?.topK ?? 10),\n durationMs: performance.now() - startTime,\n };\n }\n\n async checkHealth(): Promise<StoreHealth> {\n const startTime = performance.now();\n try {\n const client = await this.ensureConnected();\n await client.ping();\n return {\n healthy: true,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n };\n } catch (error) {\n return {\n healthy: false,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n error: (error as Error).message,\n };\n }\n }\n\n async close(): Promise<void> {\n if (this.client) {\n await this.client.quit();\n this.client = null;\n this.connected = false;\n }\n }\n\n /**\n * Check if connected to Redis\n */\n isConnected(): boolean {\n return this.connected;\n }\n}\n\n/**\n * Create a RedisCacheStore instance\n */\nexport function createRedisCacheStore(\n config: RedisStoreConfig,\n): RedisCacheStore {\n return new RedisCacheStore(config);\n}\n","/**\n * SQLiteCacheStore\n *\n * SQLite-based cache store with optional vector search support.\n */\n\nimport { BaseCacheStore } from './BaseCacheStore.js';\nimport type {\n CacheEntry,\n CacheBackendType,\n SQLiteStoreConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n} from '../types/index.js';\nimport { now } from '../core/utils.js';\nimport { cosineSimilarity } from '../similarity/metrics/SimilarityMetrics.js';\n\n/**\n * SQLite database interface (compatible with better-sqlite3)\n */\ninterface Database {\n prepare(sql: string): Statement;\n exec(sql: string): void;\n close(): void;\n}\n\ninterface Statement {\n run(...params: unknown[]): { changes: number };\n get(...params: unknown[]): unknown;\n all(...params: unknown[]): unknown[];\n}\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: Partial<SQLiteStoreConfig> = {\n dbPath: 'cache.db',\n inMemory: false,\n enableVector: false,\n};\n\n/**\n * SQLiteCacheStore\n *\n * SQLite-based cache store for persistent local caching.\n * Supports optional vector search for semantic matching.\n *\n * @example\n * ```typescript\n * const store = new SQLiteCacheStore({\n * type: 'sqlite',\n * dbPath: './cache.db'\n * });\n *\n * await store.init();\n * await store.set('key', entry);\n * ```\n */\nexport class SQLiteCacheStore extends BaseCacheStore {\n readonly storeType: CacheBackendType = 'sqlite';\n\n private db: Database | null = null;\n private sqliteConfig: SQLiteStoreConfig;\n private initialized = false;\n\n constructor(config: SQLiteStoreConfig) {\n super(config);\n this.sqliteConfig = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Initialize the database\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n try {\n const BetterSqlite3 = (await import('better-sqlite3')).default;\n\n const db = new BetterSqlite3(\n this.sqliteConfig.inMemory\n ? ':memory:'\n : (this.sqliteConfig.dbPath ?? 'cache.db'),\n );\n this.db = db;\n\n // Create tables\n db.exec(`\n CREATE TABLE IF NOT EXISTS cache_entries (\n key TEXT PRIMARY KEY,\n id TEXT NOT NULL,\n data TEXT NOT NULL,\n embedding BLOB,\n model TEXT NOT NULL,\n namespace TEXT,\n created_at INTEGER NOT NULL,\n accessed_at INTEGER NOT NULL,\n ttl INTEGER DEFAULT 0\n );\n\n CREATE INDEX IF NOT EXISTS idx_namespace ON cache_entries(namespace);\n CREATE INDEX IF NOT EXISTS idx_model ON cache_entries(model);\n CREATE INDEX IF NOT EXISTS idx_created_at ON cache_entries(created_at);\n CREATE INDEX IF NOT EXISTS idx_accessed_at ON cache_entries(accessed_at);\n `);\n\n this.initialized = true;\n } catch (error) {\n throw new Error(\n `Failed to initialize SQLite database: ${(error as Error).message}`,\n );\n }\n }\n\n private ensureInitialized(): Database {\n if (!this.initialized || !this.db) {\n throw new Error('SQLite store not initialized. Call init() first.');\n }\n return this.db;\n }\n\n get(key: string): Promise<CacheEntry | undefined> {\n this.incrementMetric('gets');\n const db = this.ensureInitialized();\n\n const row = db\n .prepare('SELECT data FROM cache_entries WHERE key = ?')\n .get(key) as { data: string } | undefined;\n\n if (!row) {\n this.incrementMetric('misses');\n return Promise.resolve(undefined);\n }\n\n this.incrementMetric('hits');\n try {\n const entry = JSON.parse(row.data) as CacheEntry;\n\n // Update access metadata\n entry.metadata.accessedAt = now();\n entry.metadata.accessCount++;\n db.prepare(\n 'UPDATE cache_entries SET accessed_at = ?, data = ? WHERE key = ?',\n ).run(now(), JSON.stringify(entry), key);\n\n return Promise.resolve(entry);\n } catch {\n return Promise.resolve(undefined);\n }\n }\n\n set(key: string, entry: CacheEntry): Promise<UpsertResult> {\n const startTime = performance.now();\n this.incrementMetric('sets');\n const db = this.ensureInitialized();\n\n // Convert embedding to buffer if present\n const embedding = entry.embedding\n ? Buffer.from(new Float32Array(entry.embedding).buffer)\n : null;\n\n db.prepare(\n `\n INSERT OR REPLACE INTO cache_entries\n (key, id, data, embedding, model, namespace, created_at, accessed_at, ttl)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n `,\n ).run(\n key,\n entry.id,\n JSON.stringify(entry),\n embedding,\n entry.request.model,\n entry.metadata.namespace ?? null,\n entry.metadata.createdAt,\n entry.metadata.accessedAt,\n entry.metadata.ttl,\n );\n\n return Promise.resolve({\n success: true,\n id: entry.id,\n durationMs: performance.now() - startTime,\n });\n }\n\n has(key: string): Promise<boolean> {\n const db = this.ensureInitialized();\n const row = db\n .prepare('SELECT 1 FROM cache_entries WHERE key = ?')\n .get(key);\n return Promise.resolve(!!row);\n }\n\n delete(key: string): Promise<boolean> {\n this.incrementMetric('deletes');\n const db = this.ensureInitialized();\n const result = db\n .prepare('DELETE FROM cache_entries WHERE key = ?')\n .run(key);\n return Promise.resolve(result.changes > 0);\n }\n\n clear(): Promise<void> {\n const db = this.ensureInitialized();\n if (this.namespace === 'default') {\n db.prepare('DELETE FROM cache_entries').run();\n } else {\n db.prepare('DELETE FROM cache_entries WHERE namespace = ?').run(\n this.namespace,\n );\n }\n return Promise.resolve();\n }\n\n size(): Promise<number> {\n const db = this.ensureInitialized();\n const row = db\n .prepare('SELECT COUNT(*) as count FROM cache_entries')\n .get() as { count: number };\n return Promise.resolve(row.count);\n }\n\n keys(): Promise<string[]> {\n const db = this.ensureInitialized();\n const rows = db.prepare('SELECT key FROM cache_entries').all() as Array<{\n key: string;\n }>;\n return Promise.resolve(rows.map((r) => r.key));\n }\n\n query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult> {\n const startTime = performance.now();\n const db = this.ensureInitialized();\n\n // Build query with optional namespace filter\n let sql = `\n SELECT key, data, embedding FROM cache_entries\n WHERE embedding IS NOT NULL\n `;\n const params: unknown[] = [];\n\n if (options?.namespace) {\n sql += ' AND namespace = ?';\n params.push(options.namespace);\n }\n\n const rows = db.prepare(sql).all(...params) as Array<{\n key: string;\n data: string;\n embedding: Buffer;\n }>;\n\n // Compute similarities\n const results: Array<CacheEntry & { score: number }> = [];\n\n for (const row of rows) {\n const stored = new Float32Array(\n row.embedding.buffer,\n row.embedding.byteOffset,\n row.embedding.length / 4,\n );\n const similarity = cosineSimilarity(vector, Array.from(stored));\n\n if (similarity >= (options?.minSimilarity ?? 0)) {\n try {\n const entry = JSON.parse(row.data) as CacheEntry;\n results.push({ ...entry, score: similarity });\n } catch {\n // Skip invalid entries\n }\n }\n }\n\n results.sort((a, b) => b.score - a.score);\n\n return Promise.resolve({\n entries: results.slice(0, options?.topK ?? 10),\n durationMs: performance.now() - startTime,\n });\n }\n\n checkHealth(): Promise<StoreHealth> {\n const startTime = performance.now();\n try {\n this.ensureInitialized();\n return Promise.resolve({\n healthy: true,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n });\n } catch (error) {\n return Promise.resolve({\n healthy: false,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n error: (error as Error).message,\n });\n }\n }\n\n close(): Promise<void> {\n if (this.db) {\n this.db.close();\n this.db = null;\n this.initialized = false;\n }\n return Promise.resolve();\n }\n\n /**\n * Prune expired entries\n */\n pruneExpired(): Promise<number> {\n const db = this.ensureInitialized();\n const currentTime = now();\n\n const result = db\n .prepare(\n `\n DELETE FROM cache_entries\n WHERE ttl > 0 AND (created_at + (ttl * 1000)) < ?\n `,\n )\n .run(currentTime);\n\n return Promise.resolve(result.changes);\n }\n\n /**\n * Get database file size (for non-memory databases)\n */\n async getDbSize(): Promise<number | null> {\n if (this.sqliteConfig.inMemory) return null;\n\n try {\n const { statSync } = await import('fs');\n const stats = statSync(this.sqliteConfig.dbPath ?? 'cache.db');\n return stats.size;\n } catch {\n return null;\n }\n }\n\n /**\n * Check if database is initialized\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n}\n\n/**\n * Create a SQLiteCacheStore instance\n */\nexport function createSQLiteCacheStore(\n config: SQLiteStoreConfig,\n): SQLiteCacheStore {\n return new SQLiteCacheStore(config);\n}\n","/**\n * TieredCacheStore\n *\n * Multi-tier cache store with automatic promotion and demotion.\n */\n\nimport { BaseCacheStore } from './BaseCacheStore.js';\nimport type {\n CacheEntry,\n CacheBackendType,\n TieredStoreConfig,\n TierConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n} from '../types/index.js';\nimport { now } from '../core/utils.js';\n\n/**\n * TieredCacheStore\n *\n * Multi-tier cache store that manages multiple cache backends\n * with automatic promotion and demotion based on access patterns.\n *\n * @example\n * ```typescript\n * const tieredStore = new TieredCacheStore({\n * type: 'tiered',\n * tiers: [\n * {\n * name: 'hot',\n * store: memoryStore,\n * priority: 1,\n * maxSize: 1000,\n * promotionThreshold: 3\n * },\n * {\n * name: 'warm',\n * store: redisStore,\n * priority: 2,\n * maxSize: 10000\n * },\n * {\n * name: 'cold',\n * store: sqliteStore,\n * priority: 3\n * }\n * ]\n * });\n *\n * await tieredStore.set('key', entry);\n * const result = await tieredStore.get('key');\n * ```\n */\n/**\n * Internal tier representation with guaranteed store\n */\ninterface InternalTier extends TierConfig {\n store: BaseCacheStore;\n}\n\nexport class TieredCacheStore extends BaseCacheStore {\n readonly storeType: CacheBackendType = 'tiered';\n\n private tiers: InternalTier[];\n private accessCounts: Map<string, number> = new Map();\n\n constructor(config: TieredStoreConfig) {\n super(config);\n\n // Filter and validate tiers that have stores\n const validTiers = config.tiers.filter(\n (t): t is InternalTier => t.store !== undefined,\n );\n\n if (validTiers.length === 0) {\n throw new Error(\n 'TieredCacheStore requires at least one tier with a store',\n );\n }\n\n // Sort tiers by priority (lower = higher priority)\n this.tiers = validTiers.sort((a, b) => a.priority - b.priority);\n }\n\n async get(key: string): Promise<CacheEntry | undefined> {\n this.incrementMetric('gets');\n\n // Search tiers from highest to lowest priority\n for (let i = 0; i < this.tiers.length; i++) {\n const tier = this.tiers[i];\n const entry = await tier.store.get(key);\n\n if (entry) {\n this.incrementMetric('hits');\n\n // Track access count\n const accessCount = (this.accessCounts.get(key) ?? 0) + 1;\n this.accessCounts.set(key, accessCount);\n\n // Check for promotion\n if (i > 0) {\n await this.checkPromotion(key, entry, i, accessCount);\n }\n\n return entry;\n }\n }\n\n this.incrementMetric('misses');\n return undefined;\n }\n\n async set(key: string, entry: CacheEntry): Promise<UpsertResult> {\n const startTime = performance.now();\n this.incrementMetric('sets');\n\n // Set in the primary (first) tier\n const result = await this.tiers[0].store.set(key, entry);\n\n // Initialize access count\n this.accessCounts.set(key, 0);\n\n // Check if we need to demote entries from the primary tier\n await this.checkDemotion(0);\n\n return {\n ...result,\n durationMs: performance.now() - startTime,\n };\n }\n\n async has(key: string): Promise<boolean> {\n for (const tier of this.tiers) {\n if (await tier.store.has(key)) {\n return true;\n }\n }\n return false;\n }\n\n async delete(key: string): Promise<boolean> {\n this.incrementMetric('deletes');\n let deleted = false;\n\n // Delete from all tiers\n for (const tier of this.tiers) {\n if (await tier.store.delete(key)) {\n deleted = true;\n }\n }\n\n this.accessCounts.delete(key);\n return deleted;\n }\n\n async clear(): Promise<void> {\n for (const tier of this.tiers) {\n await tier.store.clear();\n }\n this.accessCounts.clear();\n }\n\n async size(): Promise<number> {\n // Count unique keys across all tiers\n const allKeys = new Set<string>();\n for (const tier of this.tiers) {\n const keys = await tier.store.keys();\n keys.forEach((k) => allKeys.add(k));\n }\n return allKeys.size;\n }\n\n async keys(): Promise<string[]> {\n const allKeys = new Set<string>();\n for (const tier of this.tiers) {\n const keys = await tier.store.keys();\n keys.forEach((k) => allKeys.add(k));\n }\n return Array.from(allKeys);\n }\n\n async query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult> {\n const startTime = performance.now();\n const entriesMap = new Map<string, CacheEntry & { score: number }>();\n\n // Query all tiers and merge results\n for (const tier of this.tiers) {\n const result = await tier.store.query(vector, options);\n for (const entry of result.entries) {\n // Keep highest score if entry exists in multiple tiers\n const existing = entriesMap.get(entry.key);\n if (!existing || entry.score > existing.score) {\n entriesMap.set(entry.key, entry);\n }\n }\n }\n\n // Sort by score and limit\n const entries = Array.from(entriesMap.values())\n .sort((a, b) => b.score - a.score)\n .slice(0, options?.topK ?? 10);\n\n return {\n entries,\n durationMs: performance.now() - startTime,\n };\n }\n\n async checkHealth(): Promise<StoreHealth> {\n const startTime = performance.now();\n const tierHealths: Array<{ name: string; healthy: boolean }> = [];\n\n for (const tier of this.tiers) {\n const health = await tier.store.checkHealth();\n tierHealths.push({ name: tier.name, healthy: health.healthy });\n }\n\n const allHealthy = tierHealths.every((t) => t.healthy);\n\n return {\n healthy: allHealthy,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n error: allHealthy\n ? undefined\n : `Unhealthy tiers: ${tierHealths\n .filter((t) => !t.healthy)\n .map((t) => t.name)\n .join(', ')}`,\n };\n }\n\n async close(): Promise<void> {\n for (const tier of this.tiers) {\n await tier.store.close();\n }\n }\n\n /**\n * Get tier statistics\n */\n async getTierStats(): Promise<\n Array<{\n name: string;\n priority: number;\n size: number;\n maxSize?: number;\n }>\n > {\n const stats = [];\n for (const tier of this.tiers) {\n stats.push({\n name: tier.name,\n priority: tier.priority,\n size: await tier.store.size(),\n maxSize: tier.maxSize,\n });\n }\n return stats;\n }\n\n /**\n * Manually promote an entry to a higher tier\n */\n async promote(key: string, targetTierIndex = 0): Promise<boolean> {\n // Find the entry\n for (let i = targetTierIndex + 1; i < this.tiers.length; i++) {\n const entry = await this.tiers[i].store.get(key);\n if (entry) {\n // Set in target tier\n await this.tiers[targetTierIndex].store.set(key, entry);\n // Delete from source tier\n await this.tiers[i].store.delete(key);\n return true;\n }\n }\n return false;\n }\n\n /**\n * Manually demote an entry to a lower tier\n */\n async demote(key: string, targetTierIndex?: number): Promise<boolean> {\n // Find the entry\n for (let i = 0; i < this.tiers.length - 1; i++) {\n const entry = await this.tiers[i].store.get(key);\n if (entry) {\n const target = targetTierIndex ?? i + 1;\n if (target >= this.tiers.length) return false;\n\n // Set in target tier\n await this.tiers[target].store.set(key, entry);\n // Delete from source tier\n await this.tiers[i].store.delete(key);\n return true;\n }\n }\n return false;\n }\n\n private async checkPromotion(\n key: string,\n entry: CacheEntry,\n currentTierIndex: number,\n accessCount: number,\n ): Promise<void> {\n // Check if entry should be promoted to a higher tier\n for (let i = currentTierIndex - 1; i >= 0; i--) {\n const tier = this.tiers[i];\n const threshold = tier.promotionThreshold ?? 3;\n\n if (accessCount >= threshold) {\n // Promote to this tier\n await tier.store.set(key, entry);\n // Remove from current tier\n await this.tiers[currentTierIndex].store.delete(key);\n break;\n }\n }\n }\n\n private async checkDemotion(tierIndex: number): Promise<void> {\n const tier = this.tiers[tierIndex];\n if (!tier.maxSize) return;\n\n const size = await tier.store.size();\n if (size <= tier.maxSize) return;\n\n // Need to demote some entries\n const demotionTarget = tier.demotionTarget ?? 0.9; // Demote to 90% capacity\n const targetSize = Math.floor(tier.maxSize * demotionTarget);\n const toRemove = size - targetSize;\n\n if (toRemove <= 0) return;\n\n // Get keys sorted by access count (least accessed first)\n const keys = await tier.store.keys();\n const keysByAccess = keys\n .map((k) => ({ key: k, count: this.accessCounts.get(k) ?? 0 }))\n .sort((a, b) => a.count - b.count);\n\n // Demote the least accessed entries\n const nextTierIndex = tierIndex + 1;\n if (nextTierIndex >= this.tiers.length) {\n // No lower tier, just delete\n for (let i = 0; i < toRemove && i < keysByAccess.length; i++) {\n await tier.store.delete(keysByAccess[i].key);\n this.accessCounts.delete(keysByAccess[i].key);\n }\n } else {\n // Demote to next tier\n for (let i = 0; i < toRemove && i < keysByAccess.length; i++) {\n const key = keysByAccess[i].key;\n const entry = await tier.store.get(key);\n if (entry) {\n await this.tiers[nextTierIndex].store.set(key, entry);\n await tier.store.delete(key);\n }\n }\n }\n }\n}\n\n/**\n * Create a TieredCacheStore instance\n */\nexport function createTieredCacheStore(\n config: TieredStoreConfig,\n): TieredCacheStore {\n return new TieredCacheStore(config);\n}\n","/**\n * PineconeCacheStore\n *\n * Pinecone vector database store for scalable semantic caching.\n * Native vector search for high-performance similarity matching.\n */\n\nimport { BaseCacheStore } from './BaseCacheStore.js';\nimport type {\n CacheEntry,\n CacheBackendType,\n PineconeStoreConfig,\n StoreHealth,\n StoreQueryOptions,\n StoreQueryResult,\n UpsertResult,\n} from '../types/index.js';\nimport { now } from '../core/utils.js';\n\n/**\n * Pinecone client interface\n */\ninterface PineconeClient {\n Index(name: string): PineconeIndex;\n}\n\ninterface PineconeIndex {\n namespace(name: string): PineconeNamespace;\n describeIndexStats(): Promise<{\n namespaces: Record<string, { recordCount: number }>;\n }>;\n}\n\ninterface PineconeNamespace {\n upsert(vectors: PineconeVector[]): Promise<void>;\n query(options: PineconeQueryOptions): Promise<PineconeQueryResponse>;\n deleteOne(id: string): Promise<void>;\n deleteMany(ids: string[]): Promise<void>;\n deleteAll(): Promise<void>;\n fetch(ids: string[]): Promise<{ records: Record<string, PineconeRecord> }>;\n listPaginated(options?: {\n prefix?: string;\n limit?: number;\n }): Promise<{ vectors: Array<{ id: string }> }>;\n}\n\ninterface PineconeVector {\n id: string;\n values: number[];\n metadata?: Record<string, unknown>;\n}\n\ninterface PineconeQueryOptions {\n vector: number[];\n topK: number;\n includeMetadata?: boolean;\n includeValues?: boolean;\n filter?: Record<string, unknown>;\n}\n\ninterface PineconeQueryResponse {\n matches: Array<{\n id: string;\n score: number;\n values?: number[];\n metadata?: Record<string, unknown>;\n }>;\n}\n\ninterface PineconeRecord {\n id: string;\n values: number[];\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Pinecone metadata structure for cache entries\n */\ninterface CacheMetadata {\n key: string;\n model: string;\n content: string;\n createdAt: number;\n accessedAt: number;\n accessCount: number;\n hitCount: number;\n ttl: number;\n namespace: string;\n tags: string[];\n entryData: string; // JSON stringified full entry\n}\n\n/**\n * PineconeCacheStore\n *\n * Vector database store for scalable semantic caching.\n * Uses Pinecone for native vector similarity search.\n *\n * @example\n * ```typescript\n * const store = new PineconeCacheStore({\n * type: 'pinecone',\n * apiKey: process.env.PINECONE_API_KEY!,\n * index: 'llm-cache',\n * namespace: 'production'\n * });\n *\n * await store.set('key', entry);\n * const results = await store.query(embedding, { topK: 5 });\n * ```\n */\nexport class PineconeCacheStore extends BaseCacheStore {\n readonly storeType: CacheBackendType = 'pinecone';\n\n private client: PineconeClient | null = null;\n private index: PineconeIndex | null = null;\n private ns: PineconeNamespace | null = null;\n private pineconeConfig: PineconeStoreConfig;\n private connected = false;\n\n constructor(config: PineconeStoreConfig) {\n super(config);\n this.pineconeConfig = config;\n }\n\n /**\n * Connect to Pinecone\n */\n async connect(): Promise<void> {\n if (this.connected) return;\n\n try {\n const { Pinecone } = await import('@pinecone-database/pinecone');\n\n this.client = new Pinecone({\n apiKey: this.pineconeConfig.apiKey,\n }) as unknown as PineconeClient;\n\n this.index = this.client.Index(this.pineconeConfig.index);\n this.ns = this.index.namespace(this.namespace);\n this.connected = true;\n } catch (error) {\n throw new Error(\n `Failed to connect to Pinecone: ${(error as Error).message}`,\n );\n }\n }\n\n private async ensureConnected(): Promise<PineconeNamespace> {\n if (!this.connected || !this.ns) {\n await this.connect();\n }\n if (!this.ns) {\n throw new Error('Pinecone namespace not initialized');\n }\n return this.ns;\n }\n\n async get(key: string): Promise<CacheEntry | undefined> {\n this.incrementMetric('gets');\n const ns = await this.ensureConnected();\n\n try {\n // Fetch by ID (key is used as vector ID)\n const result = await ns.fetch([key]);\n\n if (!result.records[key]) {\n this.incrementMetric('misses');\n return undefined;\n }\n\n this.incrementMetric('hits');\n const record = result.records[key];\n const metadata = record.metadata as unknown as CacheMetadata;\n\n // Parse the full entry from metadata\n const entry = JSON.parse(metadata.entryData) as CacheEntry;\n entry.metadata.accessedAt = now();\n entry.metadata.accessCount++;\n\n // Update access metadata (fire and forget)\n this.updateAccessMetadata(key, record.values, metadata).catch(() => {});\n\n return entry;\n } catch {\n this.incrementMetric('misses');\n return undefined;\n }\n }\n\n private async updateAccessMetadata(\n key: string,\n values: number[],\n metadata: CacheMetadata,\n ): Promise<void> {\n const ns = await this.ensureConnected();\n const updatedEntry = JSON.parse(metadata.entryData) as CacheEntry;\n updatedEntry.metadata.accessedAt = now();\n updatedEntry.metadata.accessCount++;\n\n await ns.upsert([\n {\n id: key,\n values,\n metadata: {\n ...metadata,\n accessedAt: now(),\n accessCount: metadata.accessCount + 1,\n entryData: JSON.stringify(updatedEntry),\n },\n },\n ]);\n }\n\n async set(key: string, entry: CacheEntry): Promise<UpsertResult> {\n const startTime = performance.now();\n this.incrementMetric('sets');\n const ns = await this.ensureConnected();\n\n // Ensure entry has an embedding\n if (!entry.embedding || entry.embedding.length === 0) {\n return {\n success: false,\n id: entry.id,\n durationMs: performance.now() - startTime,\n };\n }\n\n const metadata: CacheMetadata = {\n key,\n model: entry.request.model,\n content: entry.response.content.substring(0, 30000), // Pinecone metadata limit\n createdAt: entry.metadata.createdAt,\n accessedAt: entry.metadata.accessedAt,\n accessCount: entry.metadata.accessCount,\n hitCount: entry.metadata.hitCount,\n ttl: entry.metadata.ttl,\n namespace: entry.metadata.namespace ?? this.namespace,\n tags: entry.metadata.tags ?? [],\n entryData: JSON.stringify(entry),\n };\n\n try {\n await ns.upsert([\n {\n id: key,\n values: entry.embedding,\n metadata: metadata as unknown as Record<string, unknown>,\n },\n ]);\n\n return {\n success: true,\n id: entry.id,\n durationMs: performance.now() - startTime,\n };\n } catch (error) {\n return {\n success: false,\n id: entry.id,\n durationMs: performance.now() - startTime,\n };\n }\n }\n\n async has(key: string): Promise<boolean> {\n const ns = await this.ensureConnected();\n try {\n const result = await ns.fetch([key]);\n return !!result.records[key];\n } catch {\n return false;\n }\n }\n\n async delete(key: string): Promise<boolean> {\n this.incrementMetric('deletes');\n const ns = await this.ensureConnected();\n\n try {\n await ns.deleteOne(key);\n return true;\n } catch {\n return false;\n }\n }\n\n async clear(): Promise<void> {\n const ns = await this.ensureConnected();\n await ns.deleteAll();\n }\n\n async size(): Promise<number> {\n if (!this.index) {\n await this.connect();\n }\n\n try {\n const stats = await this.index!.describeIndexStats();\n return stats.namespaces[this.namespace]?.recordCount ?? 0;\n } catch {\n return 0;\n }\n }\n\n async keys(): Promise<string[]> {\n const ns = await this.ensureConnected();\n\n try {\n // Note: Pinecone doesn't support listing all keys efficiently\n // This uses pagination but may be limited\n const result = await ns.listPaginated({ limit: 10000 });\n return result.vectors.map((v) => v.id);\n } catch {\n return [];\n }\n }\n\n async query(\n vector: number[],\n options?: StoreQueryOptions,\n ): Promise<StoreQueryResult> {\n const startTime = performance.now();\n const ns = await this.ensureConnected();\n\n const queryOptions: PineconeQueryOptions = {\n vector,\n topK: options?.topK ?? 10,\n includeMetadata: true,\n includeValues: options?.includeEmbedding ?? false,\n };\n\n // Add namespace filter if specified\n if (options?.filter) {\n queryOptions.filter = options.filter;\n }\n\n try {\n const result = await ns.query(queryOptions);\n\n const entries: Array<CacheEntry & { score: number }> = [];\n\n for (const match of result.matches) {\n // Skip if below similarity threshold\n if (options?.minSimilarity && match.score < options.minSimilarity) {\n continue;\n }\n\n const metadata = match.metadata as unknown as CacheMetadata;\n\n if (metadata?.entryData) {\n try {\n const entry = JSON.parse(metadata.entryData) as CacheEntry;\n\n // Include embedding if requested\n if (options?.includeEmbedding && match.values) {\n entry.embedding = match.values;\n }\n\n entries.push({\n ...entry,\n score: match.score,\n });\n } catch {\n // Skip malformed entries\n }\n }\n }\n\n return {\n entries,\n durationMs: performance.now() - startTime,\n };\n } catch (error) {\n return {\n entries: [],\n durationMs: performance.now() - startTime,\n };\n }\n }\n\n async checkHealth(): Promise<StoreHealth> {\n const startTime = performance.now();\n\n try {\n if (!this.index) {\n await this.connect();\n }\n\n await this.index!.describeIndexStats();\n\n return {\n healthy: true,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n };\n } catch (error) {\n return {\n healthy: false,\n latencyMs: performance.now() - startTime,\n lastCheck: now(),\n error: (error as Error).message,\n };\n }\n }\n\n close(): Promise<void> {\n // Pinecone client doesn't require explicit cleanup\n this.client = null;\n this.index = null;\n this.ns = null;\n this.connected = false;\n return Promise.resolve();\n }\n\n /**\n * Check if connected to Pinecone\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Get index stats\n */\n async getIndexStats(): Promise<{\n namespaces: Record<string, { recordCount: number }>;\n } | null> {\n if (!this.index) {\n await this.connect();\n }\n\n try {\n return await this.index!.describeIndexStats();\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Create a PineconeCacheStore instance\n */\nexport function createPineconeCacheStore(\n config: PineconeStoreConfig,\n): PineconeCacheStore {\n return new PineconeCacheStore(config);\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { B as BaseMatchStrategy, M as MatchStrategyType, E as ExactMatchConfig, b as MatchRequest, a as MatchOptions, S as SemanticMatchConfig, H as HybridMatchConfig } from '../BaseMatchStrategy-1E1SHaUt.js';
2
+ export { d as ContextDetector, C as ContextType, F as FuzzyMatchConfig, c as MatchResult, T as ThresholdConfig } from '../BaseMatchStrategy-1E1SHaUt.js';
3
+ import { a as CacheLookupResult } from '../cache.types-DMuyQseO.js';
4
+ import { B as BaseCacheStore } from '../store.types-BQy5Yyz9.js';
5
+ import { S as SimilarityEngine } from '../SimilarityEngine-Cwv_mF9a.js';
6
+
7
+ declare class ExactMatchStrategy extends BaseMatchStrategy {
8
+ readonly name: MatchStrategyType;
9
+ private config;
10
+ constructor(config?: Partial<ExactMatchConfig>);
11
+ match(request: MatchRequest, store: BaseCacheStore, _similarity?: SimilarityEngine, options?: MatchOptions): Promise<CacheLookupResult>;
12
+ }
13
+ declare function createExactMatchStrategy(config?: Partial<ExactMatchConfig>): ExactMatchStrategy;
14
+
15
+ declare class SemanticMatchStrategy extends BaseMatchStrategy {
16
+ readonly name: MatchStrategyType;
17
+ private config;
18
+ constructor(config?: Partial<SemanticMatchConfig>);
19
+ match(request: MatchRequest, store: BaseCacheStore, similarity?: SimilarityEngine, options?: MatchOptions): Promise<CacheLookupResult>;
20
+ }
21
+ declare function createSemanticMatchStrategy(config?: Partial<SemanticMatchConfig>): SemanticMatchStrategy;
22
+
23
+ declare class HybridMatchStrategy extends BaseMatchStrategy {
24
+ readonly name: MatchStrategyType;
25
+ private exact;
26
+ private semantic;
27
+ private config;
28
+ constructor(config?: Partial<HybridMatchConfig>);
29
+ match(request: MatchRequest, store: BaseCacheStore, similarity?: SimilarityEngine, options?: MatchOptions): Promise<CacheLookupResult>;
30
+ private shouldUseExactOnly;
31
+ private shouldUseSemantic;
32
+ private extractUserMessage;
33
+ }
34
+ declare function createHybridMatchStrategy(config?: Partial<HybridMatchConfig>): HybridMatchStrategy;
35
+
36
+ export { BaseMatchStrategy, ExactMatchConfig, ExactMatchStrategy, HybridMatchConfig, HybridMatchStrategy, MatchOptions, MatchRequest, MatchStrategyType, SemanticMatchConfig, SemanticMatchStrategy, createExactMatchStrategy, createHybridMatchStrategy, createSemanticMatchStrategy };
@@ -0,0 +1,280 @@
1
+ import murmurhash from 'murmurhash';
2
+
3
+ // src/strategies/BaseMatchStrategy.ts
4
+ var BaseMatchStrategy = class {
5
+ };
6
+ var DEFAULT_KEY_OPTIONS = {
7
+ includeTemperature: false,
8
+ includeTools: false,
9
+ normalizeWhitespace: true,
10
+ extractUserMessage: false
11
+ };
12
+ function generateCacheKey(model, messages, options = {}) {
13
+ const opts = { ...DEFAULT_KEY_OPTIONS, ...options };
14
+ const normalized = normalizeRequest(model, messages, opts);
15
+ const hash = murmurhash.v3(JSON.stringify(normalized)).toString(16);
16
+ return `cache:${model}:${hash}`;
17
+ }
18
+ function normalizeRequest(model, messages, options = {}) {
19
+ const normalizedMessages = messages.map((m) => ({
20
+ role: m.role,
21
+ content: options.normalizeWhitespace ? normalizeWhitespace(m.content) : m.content
22
+ }));
23
+ return {
24
+ model,
25
+ messages: options.extractUserMessage ? extractUserMessage(normalizedMessages) : normalizedMessages
26
+ };
27
+ }
28
+ function normalizeWhitespace(text) {
29
+ return text.trim().replace(/\r\n/g, "\n").replace(/\s+/g, " ");
30
+ }
31
+ function extractUserMessage(messages) {
32
+ for (let i = messages.length - 1; i >= 0; i--) {
33
+ if (messages[i].role === "user") {
34
+ return messages[i].content;
35
+ }
36
+ }
37
+ return "";
38
+ }
39
+
40
+ // src/strategies/ExactMatchStrategy.ts
41
+ var DEFAULT_CONFIG = {
42
+ normalizeWhitespace: true,
43
+ hashFields: ["model", "messages"]
44
+ };
45
+ var ExactMatchStrategy = class extends BaseMatchStrategy {
46
+ name = "exact";
47
+ config;
48
+ constructor(config) {
49
+ super();
50
+ this.config = { ...DEFAULT_CONFIG, ...config };
51
+ }
52
+ async match(request, store, _similarity, options) {
53
+ const startTime = performance.now();
54
+ const namespace = options?.namespace;
55
+ const baseKey = generateCacheKey(request.model, request.messages, {
56
+ normalizeWhitespace: this.config.normalizeWhitespace,
57
+ includeTemperature: this.config.hashFields?.includes("temperature")
58
+ });
59
+ const tempSuffix = request.temperature !== void 0 ? `:t:${request.temperature}` : "";
60
+ const key = namespace && namespace !== "default" ? `${baseKey}${tempSuffix}:ns:${namespace}` : `${baseKey}${tempSuffix}`;
61
+ const entry = await store.get(key);
62
+ if (entry) {
63
+ if (namespace && entry.metadata.namespace && entry.metadata.namespace !== namespace) {
64
+ return {
65
+ hit: false,
66
+ latencyMs: performance.now() - startTime,
67
+ source: "miss"
68
+ };
69
+ }
70
+ return {
71
+ hit: true,
72
+ entry,
73
+ similarity: 1,
74
+ // Exact match = 100% similarity
75
+ latencyMs: performance.now() - startTime,
76
+ source: "exact"
77
+ };
78
+ }
79
+ return {
80
+ hit: false,
81
+ latencyMs: performance.now() - startTime,
82
+ source: "miss"
83
+ };
84
+ }
85
+ };
86
+ function createExactMatchStrategy(config) {
87
+ return new ExactMatchStrategy(config);
88
+ }
89
+
90
+ // src/strategies/SemanticMatchStrategy.ts
91
+ var DEFAULT_CONFIG2 = {
92
+ threshold: 0.92,
93
+ matchModel: true,
94
+ topK: 5
95
+ };
96
+ var SemanticMatchStrategy = class extends BaseMatchStrategy {
97
+ name = "semantic";
98
+ config;
99
+ constructor(config) {
100
+ super();
101
+ this.config = { ...DEFAULT_CONFIG2, ...config };
102
+ }
103
+ async match(request, store, similarity, options) {
104
+ const startTime = performance.now();
105
+ if (!similarity) {
106
+ return {
107
+ hit: false,
108
+ latencyMs: performance.now() - startTime,
109
+ source: "miss"
110
+ };
111
+ }
112
+ const userMessage = extractUserMessage(request.messages);
113
+ if (!userMessage) {
114
+ return {
115
+ hit: false,
116
+ latencyMs: performance.now() - startTime,
117
+ source: "miss"
118
+ };
119
+ }
120
+ try {
121
+ const queryEmbedding = await similarity.embed(userMessage);
122
+ const threshold = options?.threshold ?? this.config.threshold ?? 0.92;
123
+ const topK = options?.topK ?? this.config.topK ?? 5;
124
+ const results = await store.query(queryEmbedding, {
125
+ topK,
126
+ minSimilarity: threshold,
127
+ namespace: options?.namespace
128
+ });
129
+ if (results.entries.length > 0) {
130
+ let bestMatch = results.entries[0];
131
+ if (this.config.matchModel) {
132
+ const modelMatch = results.entries.find(
133
+ (e) => e.request.model === request.model
134
+ );
135
+ if (modelMatch) {
136
+ bestMatch = modelMatch;
137
+ }
138
+ }
139
+ if (bestMatch && bestMatch.score >= threshold) {
140
+ return {
141
+ hit: true,
142
+ entry: bestMatch,
143
+ similarity: bestMatch.score,
144
+ latencyMs: performance.now() - startTime,
145
+ source: "semantic"
146
+ };
147
+ }
148
+ }
149
+ return {
150
+ hit: false,
151
+ latencyMs: performance.now() - startTime,
152
+ source: "miss"
153
+ };
154
+ } catch (error) {
155
+ console.error("Semantic match error:", error);
156
+ return {
157
+ hit: false,
158
+ latencyMs: performance.now() - startTime,
159
+ source: "miss"
160
+ };
161
+ }
162
+ }
163
+ };
164
+ function createSemanticMatchStrategy(config) {
165
+ return new SemanticMatchStrategy(config);
166
+ }
167
+
168
+ // src/strategies/HybridMatchStrategy.ts
169
+ var DEFAULT_CONFIG3 = {
170
+ exact: {
171
+ normalizeWhitespace: true,
172
+ hashFields: ["model", "messages"]
173
+ },
174
+ semantic: {
175
+ threshold: 0.92,
176
+ matchModel: true,
177
+ topK: 5
178
+ }
179
+ };
180
+ var HybridMatchStrategy = class extends BaseMatchStrategy {
181
+ name = "hybrid";
182
+ exact;
183
+ semantic;
184
+ config;
185
+ constructor(config) {
186
+ super();
187
+ this.config = { ...DEFAULT_CONFIG3, ...config };
188
+ this.exact = new ExactMatchStrategy(this.config.exact);
189
+ this.semantic = new SemanticMatchStrategy(this.config.semantic);
190
+ }
191
+ async match(request, store, similarity, options) {
192
+ const startTime = performance.now();
193
+ if (this.shouldUseExactOnly(request)) {
194
+ const result = await this.exact.match(
195
+ request,
196
+ store,
197
+ similarity,
198
+ options
199
+ );
200
+ return {
201
+ ...result,
202
+ latencyMs: performance.now() - startTime
203
+ };
204
+ }
205
+ const exactResult = await this.exact.match(
206
+ request,
207
+ store,
208
+ similarity,
209
+ options
210
+ );
211
+ if (exactResult.hit) {
212
+ return {
213
+ ...exactResult,
214
+ latencyMs: performance.now() - startTime
215
+ };
216
+ }
217
+ if (!this.shouldUseSemantic(request)) {
218
+ return {
219
+ hit: false,
220
+ latencyMs: performance.now() - startTime,
221
+ source: "miss"
222
+ };
223
+ }
224
+ if (similarity) {
225
+ const semanticResult = await this.semantic.match(
226
+ request,
227
+ store,
228
+ similarity,
229
+ options
230
+ );
231
+ return {
232
+ ...semanticResult,
233
+ latencyMs: performance.now() - startTime
234
+ };
235
+ }
236
+ return {
237
+ hit: false,
238
+ latencyMs: performance.now() - startTime,
239
+ source: "miss"
240
+ };
241
+ }
242
+ /**
243
+ * Check if request should use exact-only matching
244
+ */
245
+ shouldUseExactOnly(request) {
246
+ if (!this.config.exactOnlyPatterns) return false;
247
+ const userMessage = this.extractUserMessage(request);
248
+ return this.config.exactOnlyPatterns.some(
249
+ (pattern) => pattern.test(userMessage)
250
+ );
251
+ }
252
+ /**
253
+ * Check if semantic matching should be used
254
+ */
255
+ shouldUseSemantic(request) {
256
+ if (!this.config.semanticPatterns) return true;
257
+ const userMessage = this.extractUserMessage(request);
258
+ return this.config.semanticPatterns.some(
259
+ (pattern) => pattern.test(userMessage)
260
+ );
261
+ }
262
+ /**
263
+ * Extract user message from request
264
+ */
265
+ extractUserMessage(request) {
266
+ for (let i = request.messages.length - 1; i >= 0; i--) {
267
+ if (request.messages[i].role === "user") {
268
+ return request.messages[i].content;
269
+ }
270
+ }
271
+ return "";
272
+ }
273
+ };
274
+ function createHybridMatchStrategy(config) {
275
+ return new HybridMatchStrategy(config);
276
+ }
277
+
278
+ export { BaseMatchStrategy, ExactMatchStrategy, HybridMatchStrategy, SemanticMatchStrategy, createExactMatchStrategy, createHybridMatchStrategy, createSemanticMatchStrategy };
279
+ //# sourceMappingURL=index.js.map
280
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/strategies/BaseMatchStrategy.ts","../../src/core/CacheKey.ts","../../src/strategies/ExactMatchStrategy.ts","../../src/strategies/SemanticMatchStrategy.ts","../../src/strategies/HybridMatchStrategy.ts"],"names":["DEFAULT_CONFIG"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * BaseMatchStrategy\n *\n * Abstract base class for cache matching strategies.\n */\n\nimport type {\n CacheLookupResult,\n MatchOptions,\n MatchRequest,\n MatchStrategyType,\n} from '../types/index.js';\nimport type { BaseCacheStore } from '../stores/BaseCacheStore.js';\nimport type { SimilarityEngine } from '../similarity/SimilarityEngine.js';\n\n/**\n * Abstract match strategy\n *\n * All matching strategies must extend this class and implement\n * the match method for their specific matching algorithm.\n */\nexport abstract class BaseMatchStrategy {\n /** Strategy name/type */\n abstract readonly name: MatchStrategyType;\n\n /**\n * Match a request against the cache\n *\n * @param request - The request to match\n * @param store - The cache store to search\n * @param similarity - Optional similarity engine for semantic matching\n * @param options - Match options\n * @returns The lookup result\n */\n abstract match(\n request: MatchRequest,\n store: BaseCacheStore,\n similarity?: SimilarityEngine,\n options?: MatchOptions,\n ): Promise<CacheLookupResult>;\n}\n","/**\n * Cache Key Generation\n *\n * Utilities for generating and normalizing cache keys.\n */\n\nimport murmurhash from 'murmurhash';\nimport type { CacheMessage, CacheKeyOptions } from '../types/index.js';\n\n/**\n * Default key options\n */\nconst DEFAULT_KEY_OPTIONS: CacheKeyOptions = {\n includeTemperature: false,\n includeTools: false,\n normalizeWhitespace: true,\n extractUserMessage: false,\n};\n\n/**\n * Generate a cache key from request parameters\n *\n * @param model - The model name\n * @param messages - The conversation messages\n * @param options - Key generation options\n * @returns A unique cache key string\n */\nexport function generateCacheKey(\n model: string,\n messages: CacheMessage[],\n options: CacheKeyOptions = {},\n): string {\n const opts = { ...DEFAULT_KEY_OPTIONS, ...options };\n const normalized = normalizeRequest(model, messages, opts);\n const hash = murmurhash.v3(JSON.stringify(normalized)).toString(16);\n return `cache:${model}:${hash}`;\n}\n\n/**\n * Normalize request for consistent hashing\n */\nexport function normalizeRequest(\n model: string,\n messages: CacheMessage[],\n options: CacheKeyOptions = {},\n): Record<string, unknown> {\n const normalizedMessages = messages.map((m) => ({\n role: m.role,\n content: options.normalizeWhitespace\n ? normalizeWhitespace(m.content)\n : m.content,\n }));\n\n return {\n model,\n messages: options.extractUserMessage\n ? extractUserMessage(normalizedMessages)\n : normalizedMessages,\n };\n}\n\n/**\n * Normalize whitespace in text\n *\n * - Trims leading/trailing whitespace\n * - Collapses multiple spaces into single space\n * - Normalizes line endings\n */\nexport function normalizeWhitespace(text: string): string {\n return text.trim().replace(/\\r\\n/g, '\\n').replace(/\\s+/g, ' ');\n}\n\n/**\n * Extract the last user message for semantic comparison\n */\nexport function extractUserMessage(\n messages: CacheMessage[] | Array<{ role: string; content: string }>,\n): string {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === 'user') {\n return messages[i].content;\n }\n }\n return '';\n}\n\n/**\n * Extract system prompt from messages\n */\nexport function extractSystemPrompt(\n messages: CacheMessage[],\n): string | undefined {\n const systemMessage = messages.find((m) => m.role === 'system');\n return systemMessage?.content;\n}\n\n/**\n * Generate a semantic key for embedding lookup\n * Uses only the user message and model for semantic matching\n */\nexport function generateSemanticKey(\n model: string,\n messages: CacheMessage[],\n): string {\n const userMessage = extractUserMessage(messages);\n const normalized = normalizeWhitespace(userMessage);\n return `${model}:${normalized}`;\n}\n\n/**\n * Generate a fingerprint for a conversation\n * Useful for detecting similar conversation patterns\n */\nexport function generateConversationFingerprint(\n messages: CacheMessage[],\n): string {\n const pattern = messages\n .map((m) => `${m.role}:${m.content.length}`)\n .join('|');\n return murmurhash.v3(pattern).toString(16);\n}\n\n/**\n * Parse a cache key to extract components\n */\nexport function parseCacheKey(key: string): {\n prefix: string;\n model: string;\n hash: string;\n} | null {\n const parts = key.split(':');\n if (parts.length !== 3 || parts[0] !== 'cache') {\n return null;\n }\n return {\n prefix: parts[0],\n model: parts[1],\n hash: parts[2],\n };\n}\n\n/**\n * Check if two cache keys are for the same model\n */\nexport function isSameModel(key1: string, key2: string): boolean {\n const parsed1 = parseCacheKey(key1);\n const parsed2 = parseCacheKey(key2);\n if (!parsed1 || !parsed2) return false;\n return parsed1.model === parsed2.model;\n}\n","/**\n * ExactMatchStrategy\n *\n * Hash-based exact matching strategy.\n * Uses murmurhash to generate cache keys for exact lookups.\n */\n\nimport { BaseMatchStrategy } from './BaseMatchStrategy.js';\nimport type {\n CacheLookupResult,\n MatchOptions,\n MatchRequest,\n MatchStrategyType,\n ExactMatchConfig,\n} from '../types/index.js';\nimport type { BaseCacheStore } from '../stores/BaseCacheStore.js';\nimport type { SimilarityEngine } from '../similarity/SimilarityEngine.js';\nimport { generateCacheKey } from '../core/CacheKey.js';\n\n/**\n * Default exact match configuration\n */\nconst DEFAULT_CONFIG: ExactMatchConfig = {\n normalizeWhitespace: true,\n hashFields: ['model', 'messages'],\n};\n\n/**\n * ExactMatchStrategy\n *\n * Matches requests by computing a hash of the request parameters.\n * This is the fastest matching strategy but only finds identical requests.\n *\n * @example\n * ```typescript\n * const strategy = new ExactMatchStrategy({\n * normalizeWhitespace: true,\n * hashFields: ['model', 'messages']\n * });\n *\n * const result = await strategy.match(request, store);\n * if (result.hit) {\n * console.log('Exact match found:', result.entry);\n * }\n * ```\n */\nexport class ExactMatchStrategy extends BaseMatchStrategy {\n readonly name: MatchStrategyType = 'exact';\n private config: ExactMatchConfig;\n\n constructor(config?: Partial<ExactMatchConfig>) {\n super();\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n async match(\n request: MatchRequest,\n store: BaseCacheStore,\n _similarity?: SimilarityEngine,\n options?: MatchOptions,\n ): Promise<CacheLookupResult> {\n const startTime = performance.now();\n\n // Generate cache key with namespace if provided for exact matching\n const namespace = options?.namespace;\n const baseKey = generateCacheKey(request.model, request.messages, {\n normalizeWhitespace: this.config.normalizeWhitespace,\n includeTemperature: this.config.hashFields?.includes('temperature'),\n });\n\n // Include temperature in key if specified (different temps = different cache entries)\n const tempSuffix =\n request.temperature !== undefined ? `:t:${request.temperature}` : '';\n // Include namespace in key for namespace isolation (matching SemanticCache.set behavior)\n const key =\n namespace && namespace !== 'default'\n ? `${baseKey}${tempSuffix}:ns:${namespace}`\n : `${baseKey}${tempSuffix}`;\n\n // Look up in store\n const entry = await store.get(key);\n\n if (entry) {\n // Verify namespace match if specified\n if (\n namespace &&\n entry.metadata.namespace &&\n entry.metadata.namespace !== namespace\n ) {\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n\n return {\n hit: true,\n entry,\n similarity: 1.0, // Exact match = 100% similarity\n latencyMs: performance.now() - startTime,\n source: 'exact',\n };\n }\n\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n}\n\n/**\n * Create an ExactMatchStrategy instance\n */\nexport function createExactMatchStrategy(\n config?: Partial<ExactMatchConfig>,\n): ExactMatchStrategy {\n return new ExactMatchStrategy(config);\n}\n","/**\n * SemanticMatchStrategy\n *\n * Embedding-based semantic matching strategy.\n * Uses vector similarity to find semantically similar cached responses.\n */\n\nimport { BaseMatchStrategy } from './BaseMatchStrategy.js';\nimport type {\n CacheLookupResult,\n MatchOptions,\n MatchRequest,\n MatchStrategyType,\n SemanticMatchConfig,\n} from '../types/index.js';\nimport type { BaseCacheStore } from '../stores/BaseCacheStore.js';\nimport type { SimilarityEngine } from '../similarity/SimilarityEngine.js';\nimport { extractUserMessage } from '../core/CacheKey.js';\n\n/**\n * Default semantic match configuration\n */\nconst DEFAULT_CONFIG: SemanticMatchConfig = {\n threshold: 0.92,\n matchModel: true,\n topK: 5,\n};\n\n/**\n * SemanticMatchStrategy\n *\n * Matches requests by computing semantic similarity between embeddings.\n * Requires a SimilarityEngine to generate and compare embeddings.\n *\n * @example\n * ```typescript\n * const strategy = new SemanticMatchStrategy({\n * threshold: 0.92,\n * topK: 5\n * });\n *\n * const result = await strategy.match(request, store, similarityEngine);\n * if (result.hit) {\n * console.log('Semantic match found:', result.similarity);\n * }\n * ```\n */\nexport class SemanticMatchStrategy extends BaseMatchStrategy {\n readonly name: MatchStrategyType = 'semantic';\n private config: SemanticMatchConfig;\n\n constructor(config?: Partial<SemanticMatchConfig>) {\n super();\n this.config = { ...DEFAULT_CONFIG, ...config };\n }\n\n async match(\n request: MatchRequest,\n store: BaseCacheStore,\n similarity?: SimilarityEngine,\n options?: MatchOptions,\n ): Promise<CacheLookupResult> {\n const startTime = performance.now();\n\n // Require similarity engine for semantic matching\n if (!similarity) {\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n\n // Extract user message for semantic comparison\n const userMessage = extractUserMessage(request.messages);\n\n if (!userMessage) {\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n\n try {\n // Generate embedding for query\n const queryEmbedding = await similarity.embed(userMessage);\n\n // Query store for similar entries\n const threshold = options?.threshold ?? this.config.threshold ?? 0.92;\n const topK = options?.topK ?? this.config.topK ?? 5;\n\n const results = await store.query(queryEmbedding, {\n topK,\n minSimilarity: threshold,\n namespace: options?.namespace,\n });\n\n if (results.entries.length > 0) {\n // Find best match, optionally filtering by model\n let bestMatch = results.entries[0];\n\n if (this.config.matchModel) {\n const modelMatch = results.entries.find(\n (e) => e.request.model === request.model,\n );\n if (modelMatch) {\n bestMatch = modelMatch;\n }\n }\n\n if (bestMatch && bestMatch.score >= threshold) {\n return {\n hit: true,\n entry: bestMatch,\n similarity: bestMatch.score,\n latencyMs: performance.now() - startTime,\n source: 'semantic',\n };\n }\n }\n\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n } catch (error) {\n // On embedding error, return miss\n console.error('Semantic match error:', error);\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n }\n}\n\n/**\n * Create a SemanticMatchStrategy instance\n */\nexport function createSemanticMatchStrategy(\n config?: Partial<SemanticMatchConfig>,\n): SemanticMatchStrategy {\n return new SemanticMatchStrategy(config);\n}\n","/**\n * HybridMatchStrategy\n *\n * Combined exact + semantic matching strategy.\n * Tries exact match first, then falls back to semantic.\n */\n\nimport { BaseMatchStrategy } from './BaseMatchStrategy.js';\nimport { ExactMatchStrategy } from './ExactMatchStrategy.js';\nimport { SemanticMatchStrategy } from './SemanticMatchStrategy.js';\nimport type {\n CacheLookupResult,\n MatchOptions,\n MatchRequest,\n MatchStrategyType,\n HybridMatchConfig,\n} from '../types/index.js';\nimport type { BaseCacheStore } from '../stores/BaseCacheStore.js';\nimport type { SimilarityEngine } from '../similarity/SimilarityEngine.js';\n\n/**\n * Default hybrid match configuration\n */\nconst DEFAULT_CONFIG: HybridMatchConfig = {\n exact: {\n normalizeWhitespace: true,\n hashFields: ['model', 'messages'],\n },\n semantic: {\n threshold: 0.92,\n matchModel: true,\n topK: 5,\n },\n};\n\n/**\n * HybridMatchStrategy\n *\n * Combines exact and semantic matching for optimal performance.\n * - First tries exact hash match (fast, free)\n * - Falls back to semantic match if no exact match found\n * - Can be configured to use semantic only for certain patterns\n *\n * @example\n * ```typescript\n * const strategy = new HybridMatchStrategy({\n * semantic: { threshold: 0.92 },\n * semanticPatterns: [/what|how|why/i]\n * });\n *\n * const result = await strategy.match(request, store, similarity);\n * console.log('Match source:', result.source); // 'exact' or 'semantic'\n * ```\n */\nexport class HybridMatchStrategy extends BaseMatchStrategy {\n readonly name: MatchStrategyType = 'hybrid';\n\n private exact: ExactMatchStrategy;\n private semantic: SemanticMatchStrategy;\n private config: HybridMatchConfig;\n\n constructor(config?: Partial<HybridMatchConfig>) {\n super();\n this.config = { ...DEFAULT_CONFIG, ...config };\n this.exact = new ExactMatchStrategy(this.config.exact);\n this.semantic = new SemanticMatchStrategy(this.config.semantic);\n }\n\n async match(\n request: MatchRequest,\n store: BaseCacheStore,\n similarity?: SimilarityEngine,\n options?: MatchOptions,\n ): Promise<CacheLookupResult> {\n const startTime = performance.now();\n\n // Check if this request should use exact-only matching\n if (this.shouldUseExactOnly(request)) {\n const result = await this.exact.match(\n request,\n store,\n similarity,\n options,\n );\n return {\n ...result,\n latencyMs: performance.now() - startTime,\n };\n }\n\n // Try exact match first (fast)\n const exactResult = await this.exact.match(\n request,\n store,\n similarity,\n options,\n );\n\n if (exactResult.hit) {\n return {\n ...exactResult,\n latencyMs: performance.now() - startTime,\n };\n }\n\n // Check if semantic matching should be used for this request\n if (!this.shouldUseSemantic(request)) {\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n\n // Fall back to semantic match\n if (similarity) {\n const semanticResult = await this.semantic.match(\n request,\n store,\n similarity,\n options,\n );\n\n return {\n ...semanticResult,\n latencyMs: performance.now() - startTime,\n };\n }\n\n return {\n hit: false,\n latencyMs: performance.now() - startTime,\n source: 'miss',\n };\n }\n\n /**\n * Check if request should use exact-only matching\n */\n private shouldUseExactOnly(request: MatchRequest): boolean {\n if (!this.config.exactOnlyPatterns) return false;\n\n const userMessage = this.extractUserMessage(request);\n return this.config.exactOnlyPatterns.some((pattern) =>\n pattern.test(userMessage),\n );\n }\n\n /**\n * Check if semantic matching should be used\n */\n private shouldUseSemantic(request: MatchRequest): boolean {\n // If no semantic patterns defined, always use semantic\n if (!this.config.semanticPatterns) return true;\n\n const userMessage = this.extractUserMessage(request);\n return this.config.semanticPatterns.some((pattern) =>\n pattern.test(userMessage),\n );\n }\n\n /**\n * Extract user message from request\n */\n private extractUserMessage(request: MatchRequest): string {\n for (let i = request.messages.length - 1; i >= 0; i--) {\n if (request.messages[i].role === 'user') {\n return request.messages[i].content;\n }\n }\n return '';\n }\n}\n\n/**\n * Create a HybridMatchStrategy instance\n */\nexport function createHybridMatchStrategy(\n config?: Partial<HybridMatchConfig>,\n): HybridMatchStrategy {\n return new HybridMatchStrategy(config);\n}\n"]}