nttp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +245 -0
- package/dist/NTTP.d.ts +121 -0
- package/dist/NTTP.d.ts.map +1 -0
- package/dist/NTTP.js +229 -0
- package/dist/NTTP.js.map +1 -0
- package/dist/cache/exact-cache.d.ts +46 -0
- package/dist/cache/exact-cache.d.ts.map +1 -0
- package/dist/cache/exact-cache.js +104 -0
- package/dist/cache/exact-cache.js.map +1 -0
- package/dist/cache/index.d.ts +8 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +7 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/semantic-cache.d.ts +82 -0
- package/dist/cache/semantic-cache.d.ts.map +1 -0
- package/dist/cache/semantic-cache.js +243 -0
- package/dist/cache/semantic-cache.js.map +1 -0
- package/dist/cache/types.d.ts +135 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +5 -0
- package/dist/cache/types.js.map +1 -0
- package/dist/cache.d.ts +71 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +129 -0
- package/dist/cache.js.map +1 -0
- package/dist/errors.d.ts +35 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +55 -0
- package/dist/errors.js.map +1 -0
- package/dist/executor.d.ts +82 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +395 -0
- package/dist/executor.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/intent.d.ts +55 -0
- package/dist/intent.d.ts.map +1 -0
- package/dist/intent.js +183 -0
- package/dist/intent.js.map +1 -0
- package/dist/llm.d.ts +60 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +171 -0
- package/dist/llm.js.map +1 -0
- package/dist/types.d.ts +280 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +61 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +19 -0
- package/dist/utils.js.map +1 -0
- package/package.json +94 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L1 Exact Match Cache
|
|
3
|
+
* Fast hash-based cache for identical queries
|
|
4
|
+
*/
|
|
5
|
+
import { createHash } from 'crypto';
|
|
6
|
+
/**
|
|
7
|
+
* L1 exact match cache using Map with LRU eviction
|
|
8
|
+
*/
|
|
9
|
+
export class ExactCache {
|
|
10
|
+
cache = new Map();
|
|
11
|
+
accessOrder = new Map();
|
|
12
|
+
accessCounter = 0;
|
|
13
|
+
maxSize;
|
|
14
|
+
hits = 0;
|
|
15
|
+
misses = 0;
|
|
16
|
+
constructor(maxSize = 1000) {
|
|
17
|
+
this.maxSize = maxSize;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Get cached result for a query
|
|
21
|
+
*/
|
|
22
|
+
get(query) {
|
|
23
|
+
const key = this.normalizeQuery(query);
|
|
24
|
+
const result = this.cache.get(key);
|
|
25
|
+
if (result) {
|
|
26
|
+
// Update hit count and access time
|
|
27
|
+
result.hitCount++;
|
|
28
|
+
result.lastUsedAt = new Date();
|
|
29
|
+
this.accessOrder.set(key, ++this.accessCounter);
|
|
30
|
+
this.hits++;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
this.misses++;
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Set cached result for a query
|
|
38
|
+
*/
|
|
39
|
+
set(query, result) {
|
|
40
|
+
const key = this.normalizeQuery(query);
|
|
41
|
+
// Evict if at max size
|
|
42
|
+
if (!this.cache.has(key) && this.cache.size >= this.maxSize) {
|
|
43
|
+
this.evictLRU();
|
|
44
|
+
}
|
|
45
|
+
this.cache.set(key, result);
|
|
46
|
+
this.accessOrder.set(key, ++this.accessCounter);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Clear all cached results
|
|
50
|
+
*/
|
|
51
|
+
clear() {
|
|
52
|
+
this.cache.clear();
|
|
53
|
+
this.accessOrder.clear();
|
|
54
|
+
this.accessCounter = 0;
|
|
55
|
+
this.hits = 0;
|
|
56
|
+
this.misses = 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get cache statistics
|
|
60
|
+
*/
|
|
61
|
+
getStats() {
|
|
62
|
+
return {
|
|
63
|
+
size: this.cache.size,
|
|
64
|
+
hits: this.hits,
|
|
65
|
+
misses: this.misses,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Normalize query string for consistent cache keys
|
|
70
|
+
* - Convert to lowercase
|
|
71
|
+
* - Trim whitespace
|
|
72
|
+
* - Collapse multiple spaces
|
|
73
|
+
* - Hash to fixed-length key
|
|
74
|
+
*/
|
|
75
|
+
normalizeQuery(query) {
|
|
76
|
+
const normalized = query
|
|
77
|
+
.toLowerCase()
|
|
78
|
+
.trim()
|
|
79
|
+
.replace(/\s+/g, ' ');
|
|
80
|
+
// Use SHA-256 hash for cache key
|
|
81
|
+
return createHash('sha256')
|
|
82
|
+
.update(normalized)
|
|
83
|
+
.digest('hex')
|
|
84
|
+
.substring(0, 16);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Evict least recently used entry
|
|
88
|
+
*/
|
|
89
|
+
evictLRU() {
|
|
90
|
+
let oldestKey = null;
|
|
91
|
+
let oldestAccess = Infinity;
|
|
92
|
+
for (const [key, accessTime] of this.accessOrder.entries()) {
|
|
93
|
+
if (accessTime < oldestAccess) {
|
|
94
|
+
oldestAccess = accessTime;
|
|
95
|
+
oldestKey = key;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (oldestKey) {
|
|
99
|
+
this.cache.delete(oldestKey);
|
|
100
|
+
this.accessOrder.delete(oldestKey);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=exact-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exact-cache.js","sourceRoot":"","sources":["../../src/cache/exact-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nttp cache system
|
|
3
|
+
* Exports for 3-layer caching architecture
|
|
4
|
+
*/
|
|
5
|
+
export { ExactCache } from './exact-cache.js';
|
|
6
|
+
export { SemanticCache } from './semantic-cache.js';
|
|
7
|
+
export type { CachedResult, SemanticMatch, SemanticCacheConfig, LayerStats, CacheStats, } from './types.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L2 Semantic Cache
|
|
3
|
+
* Embedding-based similarity matching using AI SDK
|
|
4
|
+
*
|
|
5
|
+
* PERFORMANCE NOTE: This implementation uses O(N) linear scan for similarity search.
|
|
6
|
+
* For large caches (>10,000 entries), consider using a vector database like:
|
|
7
|
+
* - Pinecone
|
|
8
|
+
* - Weaviate
|
|
9
|
+
* - FAISS (via Node.js bindings)
|
|
10
|
+
* - Qdrant
|
|
11
|
+
*
|
|
12
|
+
* These provide approximate nearest neighbor (ANN) search in O(log N) time.
|
|
13
|
+
*/
|
|
14
|
+
import type { CachedResult, SemanticMatch, SemanticCacheConfig, LayerStats } from './types.js';
|
|
15
|
+
/**
|
|
16
|
+
* L2 semantic similarity cache using embeddings
|
|
17
|
+
*/
|
|
18
|
+
export declare class SemanticCache {
|
|
19
|
+
private entries;
|
|
20
|
+
private threshold;
|
|
21
|
+
private maxSize;
|
|
22
|
+
private model;
|
|
23
|
+
private modelPromise;
|
|
24
|
+
private config;
|
|
25
|
+
private hits;
|
|
26
|
+
private misses;
|
|
27
|
+
constructor(config: SemanticCacheConfig);
|
|
28
|
+
/**
|
|
29
|
+
* Lazy initialization of embedding model
|
|
30
|
+
* Supports multiple providers with dynamic imports
|
|
31
|
+
*/
|
|
32
|
+
private initializeModel;
|
|
33
|
+
/**
|
|
34
|
+
* Load the embedding model based on provider configuration
|
|
35
|
+
* Passes API keys directly to avoid process.env race conditions
|
|
36
|
+
*/
|
|
37
|
+
private loadEmbeddingModel;
|
|
38
|
+
/**
|
|
39
|
+
* Find semantically similar cached query
|
|
40
|
+
* ALWAYS returns the embedding to prevent double API billing on cache miss
|
|
41
|
+
*
|
|
42
|
+
* Usage pattern:
|
|
43
|
+
* const { match, embedding } = await cache.find(query);
|
|
44
|
+
* if (match) {
|
|
45
|
+
* // Cache hit - use match.result
|
|
46
|
+
* } else {
|
|
47
|
+
* // Cache miss - generate result and use addWithEmbedding(query, embedding, result)
|
|
48
|
+
* }
|
|
49
|
+
*/
|
|
50
|
+
find(query: string): Promise<{
|
|
51
|
+
match: SemanticMatch | null;
|
|
52
|
+
embedding: number[];
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Add new entry to cache with embedding generation
|
|
56
|
+
*/
|
|
57
|
+
add(query: string, result: CachedResult): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* Add new entry with pre-computed embedding
|
|
60
|
+
* Used when embedding was already computed during find()
|
|
61
|
+
*/
|
|
62
|
+
addWithEmbedding(query: string, embedding: number[], result: CachedResult): void;
|
|
63
|
+
/**
|
|
64
|
+
* Clear all cached results
|
|
65
|
+
*/
|
|
66
|
+
clear(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Get cache statistics
|
|
69
|
+
*/
|
|
70
|
+
getStats(): LayerStats;
|
|
71
|
+
/**
|
|
72
|
+
* Evict least recently used entry
|
|
73
|
+
*
|
|
74
|
+
* NOTE: Minor race condition possible with concurrent adds in async code.
|
|
75
|
+
* Multiple parallel add() calls might all pass the size check before any
|
|
76
|
+
* eviction completes, temporarily exceeding maxSize by a few entries.
|
|
77
|
+
* This is acceptable for most use cases. For strict size limits, consider
|
|
78
|
+
* using a mutex/semaphore around the add operation.
|
|
79
|
+
*/
|
|
80
|
+
private evictLRU;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=semantic-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-cache.d.ts","sourceRoot":"","sources":["../../src/cache/semantic-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,UAAU,EACX,MAAM,YAAY,CAAC;AAWpB;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAM;IACnB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,IAAI,CAAK;IACjB,OAAO,CAAC,MAAM,CAAK;gBAEP,MAAM,EAAE,mBAAmB;IAMvC;;;OAGG;YACW,eAAe;IAa7B;;;OAGG;YACW,kBAAkB;IAmFhC;;;;;;;;;;;OAWG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA8CxF;;OAEG;IACG,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAY7D;;;OAGG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI;IAahF;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,QAAQ,IAAI,UAAU;IAQtB;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ;CAkBjB"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L2 Semantic Cache
|
|
3
|
+
* Embedding-based similarity matching using AI SDK
|
|
4
|
+
*
|
|
5
|
+
* PERFORMANCE NOTE: This implementation uses O(N) linear scan for similarity search.
|
|
6
|
+
* For large caches (>10,000 entries), consider using a vector database like:
|
|
7
|
+
* - Pinecone
|
|
8
|
+
* - Weaviate
|
|
9
|
+
* - FAISS (via Node.js bindings)
|
|
10
|
+
* - Qdrant
|
|
11
|
+
*
|
|
12
|
+
* These provide approximate nearest neighbor (ANN) search in O(log N) time.
|
|
13
|
+
*/
|
|
14
|
+
import { embed, cosineSimilarity } from 'ai';
|
|
15
|
+
/**
|
|
16
|
+
* L2 semantic similarity cache using embeddings
|
|
17
|
+
*/
|
|
18
|
+
export class SemanticCache {
|
|
19
|
+
entries = [];
|
|
20
|
+
threshold;
|
|
21
|
+
maxSize;
|
|
22
|
+
model;
|
|
23
|
+
modelPromise = null;
|
|
24
|
+
config;
|
|
25
|
+
hits = 0;
|
|
26
|
+
misses = 0;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.threshold = config.threshold ?? 0.85;
|
|
29
|
+
this.maxSize = config.maxSize ?? 500;
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Lazy initialization of embedding model
|
|
34
|
+
* Supports multiple providers with dynamic imports
|
|
35
|
+
*/
|
|
36
|
+
async initializeModel() {
|
|
37
|
+
if (this.model) {
|
|
38
|
+
return this.model;
|
|
39
|
+
}
|
|
40
|
+
if (this.modelPromise) {
|
|
41
|
+
return this.modelPromise;
|
|
42
|
+
}
|
|
43
|
+
this.modelPromise = this.loadEmbeddingModel();
|
|
44
|
+
return this.modelPromise;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Load the embedding model based on provider configuration
|
|
48
|
+
* Passes API keys directly to avoid process.env race conditions
|
|
49
|
+
*/
|
|
50
|
+
async loadEmbeddingModel() {
|
|
51
|
+
switch (this.config.provider) {
|
|
52
|
+
case 'openai': {
|
|
53
|
+
try {
|
|
54
|
+
const { createOpenAI } = await import('@ai-sdk/openai');
|
|
55
|
+
const openai = createOpenAI({
|
|
56
|
+
apiKey: this.config.apiKey || process.env.OPENAI_API_KEY,
|
|
57
|
+
});
|
|
58
|
+
this.model = openai.textEmbeddingModel(this.config.model);
|
|
59
|
+
return this.model;
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
throw new Error(`Failed to load @ai-sdk/openai. Install it with: npm install @ai-sdk/openai\nOriginal error: ${error}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
case 'cohere': {
|
|
66
|
+
try {
|
|
67
|
+
// @ts-expect-error - Optional peer dependency
|
|
68
|
+
const { createCohere } = await import('@ai-sdk/cohere');
|
|
69
|
+
const cohere = createCohere({
|
|
70
|
+
apiKey: this.config.apiKey || process.env.COHERE_API_KEY,
|
|
71
|
+
});
|
|
72
|
+
this.model = cohere.embedding(this.config.model);
|
|
73
|
+
return this.model;
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
throw new Error(`Failed to load @ai-sdk/cohere. Install it with: npm install @ai-sdk/cohere\nOriginal error: ${error}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
case 'mistral': {
|
|
80
|
+
try {
|
|
81
|
+
// @ts-expect-error - Optional peer dependency
|
|
82
|
+
const { createMistral } = await import('@ai-sdk/mistral');
|
|
83
|
+
const mistral = createMistral({
|
|
84
|
+
apiKey: this.config.apiKey || process.env.MISTRAL_API_KEY,
|
|
85
|
+
});
|
|
86
|
+
this.model = mistral.embedding(this.config.model);
|
|
87
|
+
return this.model;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw new Error(`Failed to load @ai-sdk/mistral. Install it with: npm install @ai-sdk/mistral\nOriginal error: ${error}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
case 'google': {
|
|
94
|
+
try {
|
|
95
|
+
// @ts-expect-error - Optional peer dependency
|
|
96
|
+
const { createGoogleGenerativeAI } = await import('@ai-sdk/google');
|
|
97
|
+
const google = createGoogleGenerativeAI({
|
|
98
|
+
apiKey: this.config.apiKey || process.env.GOOGLE_GENERATIVE_AI_API_KEY,
|
|
99
|
+
});
|
|
100
|
+
this.model = google.textEmbeddingModel(this.config.model);
|
|
101
|
+
return this.model;
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
throw new Error(`Failed to load @ai-sdk/google. Install it with: npm install @ai-sdk/google\nOriginal error: ${error}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
default: {
|
|
108
|
+
// Default to OpenAI for backward compatibility
|
|
109
|
+
try {
|
|
110
|
+
const { createOpenAI } = await import('@ai-sdk/openai');
|
|
111
|
+
const openai = createOpenAI({
|
|
112
|
+
apiKey: this.config.apiKey || process.env.OPENAI_API_KEY,
|
|
113
|
+
});
|
|
114
|
+
this.model = openai.textEmbeddingModel(this.config.model);
|
|
115
|
+
return this.model;
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw new Error(`Failed to load @ai-sdk/openai. Install it with: npm install @ai-sdk/openai\nOriginal error: ${error}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Find semantically similar cached query
|
|
125
|
+
* ALWAYS returns the embedding to prevent double API billing on cache miss
|
|
126
|
+
*
|
|
127
|
+
* Usage pattern:
|
|
128
|
+
* const { match, embedding } = await cache.find(query);
|
|
129
|
+
* if (match) {
|
|
130
|
+
* // Cache hit - use match.result
|
|
131
|
+
* } else {
|
|
132
|
+
* // Cache miss - generate result and use addWithEmbedding(query, embedding, result)
|
|
133
|
+
* }
|
|
134
|
+
*/
|
|
135
|
+
async find(query) {
|
|
136
|
+
// Initialize model if needed
|
|
137
|
+
const model = await this.initializeModel();
|
|
138
|
+
// Generate embedding for the query (COST: 1 API call)
|
|
139
|
+
const { embedding } = await embed({
|
|
140
|
+
model,
|
|
141
|
+
value: query,
|
|
142
|
+
});
|
|
143
|
+
// Search for best match above threshold (O(N) linear scan)
|
|
144
|
+
let bestMatch = null;
|
|
145
|
+
let bestScore = 0;
|
|
146
|
+
for (const entry of this.entries) {
|
|
147
|
+
const score = cosineSimilarity(embedding, entry.embedding);
|
|
148
|
+
if (score >= this.threshold && score > bestScore) {
|
|
149
|
+
bestScore = score;
|
|
150
|
+
bestMatch = entry;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (bestMatch) {
|
|
154
|
+
// Update hit count and access time
|
|
155
|
+
bestMatch.result.hitCount++;
|
|
156
|
+
bestMatch.result.lastUsedAt = new Date();
|
|
157
|
+
this.hits++;
|
|
158
|
+
return {
|
|
159
|
+
match: {
|
|
160
|
+
result: bestMatch.result,
|
|
161
|
+
similarity: bestScore,
|
|
162
|
+
originalQuery: bestMatch.query,
|
|
163
|
+
},
|
|
164
|
+
embedding, // Return embedding for potential reuse
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
this.misses++;
|
|
168
|
+
return {
|
|
169
|
+
match: null,
|
|
170
|
+
embedding, // CRITICAL: Return embedding so caller can use addWithEmbedding()
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Add new entry to cache with embedding generation
|
|
175
|
+
*/
|
|
176
|
+
async add(query, result) {
|
|
177
|
+
// Initialize model if needed
|
|
178
|
+
const model = await this.initializeModel();
|
|
179
|
+
const { embedding } = await embed({
|
|
180
|
+
model,
|
|
181
|
+
value: query,
|
|
182
|
+
});
|
|
183
|
+
this.addWithEmbedding(query, embedding, result);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Add new entry with pre-computed embedding
|
|
187
|
+
* Used when embedding was already computed during find()
|
|
188
|
+
*/
|
|
189
|
+
addWithEmbedding(query, embedding, result) {
|
|
190
|
+
// Evict if at max size
|
|
191
|
+
if (this.entries.length >= this.maxSize) {
|
|
192
|
+
this.evictLRU();
|
|
193
|
+
}
|
|
194
|
+
this.entries.push({
|
|
195
|
+
query,
|
|
196
|
+
embedding,
|
|
197
|
+
result,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Clear all cached results
|
|
202
|
+
*/
|
|
203
|
+
clear() {
|
|
204
|
+
this.entries = [];
|
|
205
|
+
this.hits = 0;
|
|
206
|
+
this.misses = 0;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get cache statistics
|
|
210
|
+
*/
|
|
211
|
+
getStats() {
|
|
212
|
+
return {
|
|
213
|
+
size: this.entries.length,
|
|
214
|
+
hits: this.hits,
|
|
215
|
+
misses: this.misses,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Evict least recently used entry
|
|
220
|
+
*
|
|
221
|
+
* NOTE: Minor race condition possible with concurrent adds in async code.
|
|
222
|
+
* Multiple parallel add() calls might all pass the size check before any
|
|
223
|
+
* eviction completes, temporarily exceeding maxSize by a few entries.
|
|
224
|
+
* This is acceptable for most use cases. For strict size limits, consider
|
|
225
|
+
* using a mutex/semaphore around the add operation.
|
|
226
|
+
*/
|
|
227
|
+
evictLRU() {
|
|
228
|
+
if (this.entries.length === 0) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
let oldestIndex = 0;
|
|
232
|
+
let oldestTime = this.entries[0].result.lastUsedAt;
|
|
233
|
+
for (let i = 1; i < this.entries.length; i++) {
|
|
234
|
+
const entryTime = this.entries[i].result.lastUsedAt;
|
|
235
|
+
if (entryTime < oldestTime) {
|
|
236
|
+
oldestTime = entryTime;
|
|
237
|
+
oldestIndex = i;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
this.entries.splice(oldestIndex, 1);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=semantic-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic-cache.js","sourceRoot":"","sources":["../../src/cache/semantic-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for nttp caching system
|
|
3
|
+
*/
|
|
4
|
+
import type { JsonValue } from '../utils.js';
|
|
5
|
+
/**
|
|
6
|
+
* Cached query result with metadata
|
|
7
|
+
*/
|
|
8
|
+
export interface CachedResult {
|
|
9
|
+
/**
|
|
10
|
+
* Schema ID for this query pattern
|
|
11
|
+
*/
|
|
12
|
+
readonly schemaId: string;
|
|
13
|
+
/**
|
|
14
|
+
* Generated SQL query
|
|
15
|
+
*/
|
|
16
|
+
readonly sql: string;
|
|
17
|
+
/**
|
|
18
|
+
* SQL query parameters
|
|
19
|
+
*/
|
|
20
|
+
readonly params: JsonValue[];
|
|
21
|
+
/**
|
|
22
|
+
* Number of times this cache entry was hit (mutable)
|
|
23
|
+
*/
|
|
24
|
+
hitCount: number;
|
|
25
|
+
/**
|
|
26
|
+
* When this cache entry was created
|
|
27
|
+
*/
|
|
28
|
+
readonly createdAt: Date;
|
|
29
|
+
/**
|
|
30
|
+
* When this cache entry was last used (mutable)
|
|
31
|
+
*/
|
|
32
|
+
lastUsedAt: Date;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Semantic match result from L2 cache
|
|
36
|
+
* Note: Embedding is returned separately from find() to prevent double API billing
|
|
37
|
+
*/
|
|
38
|
+
export interface SemanticMatch {
|
|
39
|
+
/**
|
|
40
|
+
* The cached result
|
|
41
|
+
*/
|
|
42
|
+
result: CachedResult;
|
|
43
|
+
/**
|
|
44
|
+
* Cosine similarity score (0-1)
|
|
45
|
+
*/
|
|
46
|
+
similarity: number;
|
|
47
|
+
/**
|
|
48
|
+
* Original query that was cached
|
|
49
|
+
*/
|
|
50
|
+
originalQuery: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Statistics for a single cache layer
|
|
54
|
+
*/
|
|
55
|
+
export interface LayerStats {
|
|
56
|
+
/**
|
|
57
|
+
* Current size of the cache
|
|
58
|
+
*/
|
|
59
|
+
size: number;
|
|
60
|
+
/**
|
|
61
|
+
* Number of cache hits
|
|
62
|
+
*/
|
|
63
|
+
hits: number;
|
|
64
|
+
/**
|
|
65
|
+
* Number of cache misses
|
|
66
|
+
*/
|
|
67
|
+
misses: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Aggregate cache statistics
|
|
71
|
+
*/
|
|
72
|
+
export interface CacheStats {
|
|
73
|
+
/**
|
|
74
|
+
* L1 exact match cache stats
|
|
75
|
+
*/
|
|
76
|
+
l1: LayerStats;
|
|
77
|
+
/**
|
|
78
|
+
* L2 semantic cache stats
|
|
79
|
+
*/
|
|
80
|
+
l2: LayerStats;
|
|
81
|
+
/**
|
|
82
|
+
* L3 LLM fallback stats
|
|
83
|
+
*/
|
|
84
|
+
l3: {
|
|
85
|
+
/**
|
|
86
|
+
* Number of LLM calls made
|
|
87
|
+
*/
|
|
88
|
+
calls: number;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Total queries processed
|
|
92
|
+
*/
|
|
93
|
+
totalQueries: number;
|
|
94
|
+
/**
|
|
95
|
+
* Hit rates for each layer
|
|
96
|
+
*/
|
|
97
|
+
hitRates: {
|
|
98
|
+
l1: number;
|
|
99
|
+
l2: number;
|
|
100
|
+
l3: number;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Estimated cost saved (USD)
|
|
104
|
+
*/
|
|
105
|
+
estimatedCostSaved: number;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Configuration for L2 semantic cache
|
|
109
|
+
*/
|
|
110
|
+
export interface SemanticCacheConfig {
|
|
111
|
+
/**
|
|
112
|
+
* Embedding provider
|
|
113
|
+
*/
|
|
114
|
+
provider: 'openai' | 'cohere' | 'mistral' | 'google';
|
|
115
|
+
/**
|
|
116
|
+
* Embedding model name
|
|
117
|
+
*/
|
|
118
|
+
model: string;
|
|
119
|
+
/**
|
|
120
|
+
* Similarity threshold for matches (0-1)
|
|
121
|
+
* Recommended: 0.80-0.85 for natural language queries
|
|
122
|
+
* @default 0.85
|
|
123
|
+
*/
|
|
124
|
+
threshold?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Maximum cache size
|
|
127
|
+
* @default 500
|
|
128
|
+
*/
|
|
129
|
+
maxSize?: number;
|
|
130
|
+
/**
|
|
131
|
+
* API key for embedding provider (if needed)
|
|
132
|
+
*/
|
|
133
|
+
apiKey?: string;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC;IAE7B;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IAEzB;;OAEG;IACH,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,EAAE,EAAE,UAAU,CAAC;IAEf;;OAEG;IACH,EAAE,EAAE,UAAU,CAAC;IAEf;;OAEG;IACH,EAAE,EAAE;QACF;;WAEG;QACH,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IAEF;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IAEF;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAErD;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cache/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|