@cogitator-ai/core 0.11.5 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/README.md +212 -0
  2. package/dist/cache/cache-key.d.ts +11 -0
  3. package/dist/cache/cache-key.d.ts.map +1 -0
  4. package/dist/cache/cache-key.js +65 -0
  5. package/dist/cache/cache-key.js.map +1 -0
  6. package/dist/cache/index.d.ts +6 -0
  7. package/dist/cache/index.d.ts.map +1 -0
  8. package/dist/cache/index.js +5 -0
  9. package/dist/cache/index.js.map +1 -0
  10. package/dist/cache/storage/index.d.ts +4 -0
  11. package/dist/cache/storage/index.d.ts.map +1 -0
  12. package/dist/cache/storage/index.js +3 -0
  13. package/dist/cache/storage/index.js.map +1 -0
  14. package/dist/cache/storage/memory.d.ts +24 -0
  15. package/dist/cache/storage/memory.d.ts.map +1 -0
  16. package/dist/cache/storage/memory.js +108 -0
  17. package/dist/cache/storage/memory.js.map +1 -0
  18. package/dist/cache/storage/redis.d.ts +32 -0
  19. package/dist/cache/storage/redis.d.ts.map +1 -0
  20. package/dist/cache/storage/redis.js +127 -0
  21. package/dist/cache/storage/redis.js.map +1 -0
  22. package/dist/cache/tool-cache.d.ts +8 -0
  23. package/dist/cache/tool-cache.d.ts.map +1 -0
  24. package/dist/cache/tool-cache.js +127 -0
  25. package/dist/cache/tool-cache.js.map +1 -0
  26. package/dist/cogitator/initializers.d.ts +4 -0
  27. package/dist/cogitator/initializers.d.ts.map +1 -1
  28. package/dist/cogitator/initializers.js +14 -0
  29. package/dist/cogitator/initializers.js.map +1 -1
  30. package/dist/cogitator.d.ts +38 -1
  31. package/dist/cogitator.d.ts.map +1 -1
  32. package/dist/cogitator.js +56 -1
  33. package/dist/cogitator.js.map +1 -1
  34. package/dist/cost-routing/cost-estimator.d.ts +18 -0
  35. package/dist/cost-routing/cost-estimator.d.ts.map +1 -0
  36. package/dist/cost-routing/cost-estimator.js +149 -0
  37. package/dist/cost-routing/cost-estimator.js.map +1 -0
  38. package/dist/cost-routing/index.d.ts +2 -0
  39. package/dist/cost-routing/index.d.ts.map +1 -1
  40. package/dist/cost-routing/index.js +2 -0
  41. package/dist/cost-routing/index.js.map +1 -1
  42. package/dist/cost-routing/token-estimator.d.ts +22 -0
  43. package/dist/cost-routing/token-estimator.d.ts.map +1 -0
  44. package/dist/cost-routing/token-estimator.js +88 -0
  45. package/dist/cost-routing/token-estimator.js.map +1 -0
  46. package/dist/index.d.ts +7 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +3 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/security/classifiers/index.d.ts +3 -0
  51. package/dist/security/classifiers/index.d.ts.map +1 -0
  52. package/dist/security/classifiers/index.js +3 -0
  53. package/dist/security/classifiers/index.js.map +1 -0
  54. package/dist/security/classifiers/llm-classifier.d.ts +10 -0
  55. package/dist/security/classifiers/llm-classifier.d.ts.map +1 -0
  56. package/dist/security/classifiers/llm-classifier.js +110 -0
  57. package/dist/security/classifiers/llm-classifier.js.map +1 -0
  58. package/dist/security/classifiers/local-classifier.d.ts +8 -0
  59. package/dist/security/classifiers/local-classifier.d.ts.map +1 -0
  60. package/dist/security/classifiers/local-classifier.js +130 -0
  61. package/dist/security/classifiers/local-classifier.js.map +1 -0
  62. package/dist/security/index.d.ts +5 -0
  63. package/dist/security/index.d.ts.map +1 -0
  64. package/dist/security/index.js +4 -0
  65. package/dist/security/index.js.map +1 -0
  66. package/dist/security/patterns.d.ts +6 -0
  67. package/dist/security/patterns.d.ts.map +1 -0
  68. package/dist/security/patterns.js +338 -0
  69. package/dist/security/patterns.js.map +1 -0
  70. package/dist/security/prompt-injection-detector.d.ts +28 -0
  71. package/dist/security/prompt-injection-detector.d.ts.map +1 -0
  72. package/dist/security/prompt-injection-detector.js +134 -0
  73. package/dist/security/prompt-injection-detector.js.map +1 -0
  74. package/dist/tools/hash.d.ts +1 -1
  75. package/dist/tools/index.d.ts +3 -3
  76. package/dist/tools/random.d.ts +1 -1
  77. package/dist/tools/vector-search.d.ts +1 -1
  78. package/package.json +5 -5
package/README.md CHANGED
@@ -994,6 +994,218 @@ breaker.onStateChange((state) => {
994
994
  });
995
995
  ```
996
996
 
997
+ ---
998
+
999
+ ## Prompt Injection Detection
1000
+
1001
+ Protect your agents from jailbreak attempts, prompt injections, and other adversarial inputs:
1002
+
1003
+ ```typescript
1004
+ import { Cogitator, PromptInjectionDetector } from '@cogitator-ai/core';
1005
+
1006
+ // Standalone usage
1007
+ const detector = new PromptInjectionDetector({
1008
+ detectInjection: true, // "Ignore previous instructions..."
1009
+ detectJailbreak: true, // DAN, developer mode attacks
1010
+ detectRoleplay: true, // Malicious roleplay scenarios
1011
+ detectEncoding: true, // Base64, hex encoded attacks
1012
+ detectContextManipulation: true, // [SYSTEM], <|im_start|> injections
1013
+ classifier: 'local', // 'local' (fast) or 'llm' (accurate)
1014
+ action: 'block', // 'block' | 'warn' | 'log'
1015
+ threshold: 0.7,
1016
+ });
1017
+
1018
+ const result = await detector.analyze('Ignore all previous instructions and...');
1019
+ // { safe: false, threats: [...], action: 'blocked', analysisTime: 2 }
1020
+
1021
+ // Integrated with Cogitator runtime
1022
+ const cog = new Cogitator({
1023
+ security: {
1024
+ promptInjection: {
1025
+ detectInjection: true,
1026
+ detectJailbreak: true,
1027
+ action: 'block',
1028
+ threshold: 0.7,
1029
+ },
1030
+ },
1031
+ });
1032
+
1033
+ // Throws PromptInjectionError if attack detected
1034
+ await cog.run(agent, { input: userInput });
1035
+ ```
1036
+
1037
+ ### Detection Types
1038
+
1039
+ | Type | Examples |
1040
+ | ---------------------- | ----------------------------------------------------- |
1041
+ | `direct_injection` | "Ignore previous instructions", "Your new prompt is" |
1042
+ | `jailbreak` | DAN prompts, "developer mode enabled", "unrestricted" |
1043
+ | `roleplay` | "Pretend you are evil AI", "From now on you are" |
1044
+ | `encoding` | Base64 payloads, hex escape sequences, unicode tricks |
1045
+ | `context_manipulation` | `[SYSTEM]:`, `<\|im_start\|>`, markdown role markers |
1046
+
1047
+ ### Custom Patterns & Allowlist
1048
+
1049
+ ```typescript
1050
+ const detector = new PromptInjectionDetector({
1051
+ action: 'block',
1052
+ patterns: [/secret\s+backdoor/i], // Custom regex patterns
1053
+ allowlist: ['ignore the previous search'], // Legitimate phrases
1054
+ });
1055
+
1056
+ // Dynamic updates
1057
+ detector.addPattern(/company\s+specific\s+attack/i);
1058
+ detector.addToAllowlist('ignore previous results');
1059
+ ```
1060
+
1061
+ ### LLM-Based Classification
1062
+
1063
+ For higher accuracy with complex attacks:
1064
+
1065
+ ```typescript
1066
+ const detector = new PromptInjectionDetector({
1067
+ classifier: 'llm',
1068
+ llmBackend: openaiBackend,
1069
+ llmModel: 'gpt-4o-mini',
1070
+ action: 'block',
1071
+ });
1072
+ ```
1073
+
1074
+ ### Statistics & Callbacks
1075
+
1076
+ ```typescript
1077
+ const detector = new PromptInjectionDetector({
1078
+ action: 'block',
1079
+ onThreat: (result, input) => {
1080
+ console.log('Attack detected:', result.threats);
1081
+ logToSecurity(input, result);
1082
+ },
1083
+ });
1084
+
1085
+ await detector.analyze('...');
1086
+ const stats = detector.getStats();
1087
+ // { analyzed: 100, blocked: 5, warned: 0, allowRate: 0.95 }
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ## Tool Caching
1093
+
1094
+ Cache tool results to avoid redundant API calls with exact or semantic matching:
1095
+
1096
+ ### Exact Match Caching
1097
+
1098
+ ```typescript
1099
+ import { tool, withCache } from '@cogitator-ai/core';
1100
+ import { z } from 'zod';
1101
+
1102
+ const webSearch = tool({
1103
+ name: 'web_search',
1104
+ description: 'Search the web',
1105
+ parameters: z.object({ query: z.string() }),
1106
+ execute: async ({ query }) => {
1107
+ return await searchApi(query);
1108
+ },
1109
+ });
1110
+
1111
+ const cachedSearch = withCache(webSearch, {
1112
+ strategy: 'exact',
1113
+ ttl: '1h',
1114
+ maxSize: 1000,
1115
+ storage: 'memory',
1116
+ });
1117
+
1118
+ await cachedSearch.execute({ query: 'weather in Paris' }, ctx);
1119
+ await cachedSearch.execute({ query: 'weather in Paris' }, ctx); // cache hit
1120
+
1121
+ console.log(cachedSearch.cache.stats());
1122
+ // { hits: 1, misses: 1, size: 1, evictions: 0, hitRate: 0.5 }
1123
+ ```
1124
+
1125
+ ### Semantic Caching
1126
+
1127
+ Similar queries hit the cache based on embedding similarity:
1128
+
1129
+ ```typescript
1130
+ import { withCache } from '@cogitator-ai/core';
1131
+ import type { EmbeddingService } from '@cogitator-ai/types';
1132
+
1133
+ const embeddingService: EmbeddingService = {
1134
+ embed: async (text) => openai.embeddings.create({ input: text }),
1135
+ embedBatch: async (texts) => /* ... */,
1136
+ dimensions: 1536,
1137
+ model: 'text-embedding-3-small',
1138
+ };
1139
+
1140
+ const cachedSearch = withCache(webSearch, {
1141
+ strategy: 'semantic',
1142
+ similarity: 0.95, // 95% similarity threshold
1143
+ ttl: '1h',
1144
+ maxSize: 1000,
1145
+ storage: 'memory',
1146
+ embeddingService,
1147
+ });
1148
+
1149
+ await cachedSearch.execute({ query: 'weather in Paris' }, ctx);
1150
+ await cachedSearch.execute({ query: 'Paris weather forecast' }, ctx); // semantic hit
1151
+ ```
1152
+
1153
+ ### Redis Storage
1154
+
1155
+ For production with persistence:
1156
+
1157
+ ```typescript
1158
+ import { withCache, RedisToolCacheStorage } from '@cogitator-ai/core';
1159
+
1160
+ const cachedTool = withCache(webSearch, {
1161
+ strategy: 'semantic',
1162
+ similarity: 0.95,
1163
+ ttl: '1h',
1164
+ maxSize: 1000,
1165
+ storage: 'redis',
1166
+ redisClient: redisClient, // ioredis compatible client
1167
+ keyPrefix: 'myapp:cache',
1168
+ embeddingService,
1169
+ });
1170
+ ```
1171
+
1172
+ ### Cache Management
1173
+
1174
+ ```typescript
1175
+ const cached = withCache(tool, config);
1176
+
1177
+ // Get statistics
1178
+ const stats = cached.cache.stats();
1179
+
1180
+ // Invalidate specific entry
1181
+ await cached.cache.invalidate({ query: 'specific query' });
1182
+
1183
+ // Clear all entries
1184
+ await cached.cache.clear();
1185
+
1186
+ // Pre-warm cache
1187
+ await cached.cache.warmup([
1188
+ { params: { query: 'common query 1' }, result: { data: '...' } },
1189
+ { params: { query: 'common query 2' }, result: { data: '...' } },
1190
+ ]);
1191
+ ```
1192
+
1193
+ ### Cache Callbacks
1194
+
1195
+ ```typescript
1196
+ const cached = withCache(tool, {
1197
+ strategy: 'exact',
1198
+ ttl: '1h',
1199
+ maxSize: 100,
1200
+ storage: 'memory',
1201
+ onHit: (key, params) => console.log('Cache hit:', key),
1202
+ onMiss: (key, params) => console.log('Cache miss:', key),
1203
+ onEvict: (key) => console.log('Evicted:', key),
1204
+ });
1205
+ ```
1206
+
1207
+ ---
1208
+
997
1209
  ### Fallback Patterns
998
1210
 
999
1211
  ```typescript
@@ -0,0 +1,11 @@
1
+ export interface CacheKeyOptions {
2
+ toolName: string;
3
+ params: unknown;
4
+ prefix?: string;
5
+ }
6
+ export declare function generateCacheKey(options: CacheKeyOptions): string;
7
+ export declare function stableStringify(obj: unknown): string;
8
+ export declare function paramsToQueryString(params: unknown): string;
9
+ export declare function cosineSimilarity(a: number[], b: number[]): number;
10
+ export declare function parseDuration(duration: string): number;
11
+ //# sourceMappingURL=cache-key.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-key.d.ts","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAKjE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAcpD;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAe3D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAejE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAmBtD"}
@@ -0,0 +1,65 @@
1
+ import { createHash } from 'crypto';
2
+ export function generateCacheKey(options) {
3
+ const { toolName, params, prefix = 'toolcache' } = options;
4
+ const paramsStr = stableStringify(params);
5
+ const hash = createHash('sha256').update(`${toolName}:${paramsStr}`).digest('hex').slice(0, 16);
6
+ return `${prefix}:${toolName}:${hash}`;
7
+ }
8
+ export function stableStringify(obj) {
9
+ if (obj === null || typeof obj !== 'object') {
10
+ return JSON.stringify(obj);
11
+ }
12
+ if (Array.isArray(obj)) {
13
+ return '[' + obj.map(stableStringify).join(',') + ']';
14
+ }
15
+ const keys = Object.keys(obj).sort();
16
+ const pairs = keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`);
17
+ return '{' + pairs.join(',') + '}';
18
+ }
19
+ export function paramsToQueryString(params) {
20
+ if (typeof params === 'string')
21
+ return params;
22
+ if (typeof params === 'object' && params !== null) {
23
+ const obj = params;
24
+ const queryFields = ['query', 'q', 'search', 'text', 'input', 'prompt', 'question'];
25
+ for (const field of queryFields) {
26
+ if (typeof obj[field] === 'string') {
27
+ return obj[field];
28
+ }
29
+ }
30
+ return JSON.stringify(params);
31
+ }
32
+ return String(params);
33
+ }
34
+ export function cosineSimilarity(a, b) {
35
+ if (a.length !== b.length)
36
+ return 0;
37
+ let dotProduct = 0;
38
+ let normA = 0;
39
+ let normB = 0;
40
+ for (let i = 0; i < a.length; i++) {
41
+ dotProduct += a[i] * b[i];
42
+ normA += a[i] * a[i];
43
+ normB += b[i] * b[i];
44
+ }
45
+ const magnitude = Math.sqrt(normA) * Math.sqrt(normB);
46
+ return magnitude === 0 ? 0 : dotProduct / magnitude;
47
+ }
48
+ export function parseDuration(duration) {
49
+ const match = /^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d|w)$/i.exec(duration);
50
+ if (!match) {
51
+ throw new Error(`Invalid duration format: ${duration}`);
52
+ }
53
+ const value = parseFloat(match[1]);
54
+ const unit = match[2].toLowerCase();
55
+ const multipliers = {
56
+ ms: 1,
57
+ s: 1000,
58
+ m: 60_000,
59
+ h: 3600_000,
60
+ d: 86400_000,
61
+ w: 604800_000,
62
+ };
63
+ return Math.floor(value * multipliers[unit]);
64
+ }
65
+ //# sourceMappingURL=cache-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-key.js","sourceRoot":"","sources":["../../src/cache/cache-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAQpC,MAAM,UAAU,gBAAgB,CAAC,OAAwB;IACvD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,GAAG,OAAO,CAAC;IAC3D,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAChG,OAAO,GAAG,MAAM,IAAI,QAAQ,IAAI,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACxD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,eAAe,CAAE,GAA+B,CAAC,CAAC,CAAC,CAAC,EAAE,CACtF,CAAC;IACF,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC;IAE9C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,MAAiC,CAAC;QAC9C,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACpF,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAChC,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE,CAAC;gBACnC,OAAO,GAAG,CAAC,KAAK,CAAW,CAAC;YAC9B,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAW,EAAE,CAAW;IACvD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IAEpC,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1B,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACrB,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtD,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,SAAS,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,KAAK,GAAG,qCAAqC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,4BAA4B,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAEpC,MAAM,WAAW,GAA2B;QAC1C,EAAE,EAAE,CAAC;QACL,CAAC,EAAE,IAAI;QACP,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,QAAQ;QACX,CAAC,EAAE,SAAS;QACZ,CAAC,EAAE,UAAU;KACd,CAAC;IAEF,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { withCache, createToolCacheStorage } from './tool-cache';
2
+ export { InMemoryToolCacheStorage } from './storage/memory';
3
+ export { RedisToolCacheStorage } from './storage/redis';
4
+ export type { RedisToolCacheStorageConfig } from './storage/redis';
5
+ export { generateCacheKey, paramsToQueryString, stableStringify, cosineSimilarity, parseDuration, } from './cache-key';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,aAAa,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { withCache, createToolCacheStorage } from './tool-cache';
2
+ export { InMemoryToolCacheStorage } from './storage/memory';
3
+ export { RedisToolCacheStorage } from './storage/redis';
4
+ export { generateCacheKey, paramsToQueryString, stableStringify, cosineSimilarity, parseDuration, } from './cache-key';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cache/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EAChB,aAAa,GACd,MAAM,aAAa,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { InMemoryToolCacheStorage } from './memory';
2
+ export { RedisToolCacheStorage } from './redis';
3
+ export type { RedisToolCacheStorageConfig } from './redis';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAChD,YAAY,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { InMemoryToolCacheStorage } from './memory';
2
+ export { RedisToolCacheStorage } from './redis';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cache/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { CacheEntry, CacheStats, ToolCacheStorage } from '@cogitator-ai/types';
2
+ export declare class InMemoryToolCacheStorage implements ToolCacheStorage {
3
+ private cache;
4
+ private maxSize;
5
+ private stats;
6
+ constructor(maxSize?: number);
7
+ private updateHitRate;
8
+ recordHit(): void;
9
+ recordMiss(): void;
10
+ recordEviction(): void;
11
+ getStats(): CacheStats;
12
+ get(key: string): Promise<CacheEntry | null>;
13
+ set(key: string, entry: CacheEntry): Promise<void>;
14
+ delete(key: string): Promise<void>;
15
+ has(key: string): Promise<boolean>;
16
+ clear(): Promise<void>;
17
+ getOldest(): Promise<CacheEntry | null>;
18
+ size(): Promise<number>;
19
+ findSimilar(embedding: number[], threshold: number, limit?: number): Promise<Array<CacheEntry & {
20
+ score: number;
21
+ }>>;
22
+ private evictOldest;
23
+ }
24
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/memory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAGpF,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAMX;gBAEU,OAAO,GAAE,MAAa;IAIlC,OAAO,CAAC,aAAa;IAKrB,SAAS,IAAI,IAAI;IAKjB,UAAU,IAAI,IAAI;IAKlB,cAAc,IAAI,IAAI;IAItB,QAAQ,IAAI,UAAU;IAIhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAe5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,SAAS,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAYvC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAIvB,WAAW,CACf,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;YAiBnC,WAAW;CAQ1B"}
@@ -0,0 +1,108 @@
1
+ import { cosineSimilarity } from '../cache-key';
2
+ export class InMemoryToolCacheStorage {
3
+ cache = new Map();
4
+ maxSize;
5
+ stats = {
6
+ hits: 0,
7
+ misses: 0,
8
+ size: 0,
9
+ evictions: 0,
10
+ hitRate: 0,
11
+ };
12
+ constructor(maxSize = 1000) {
13
+ this.maxSize = maxSize;
14
+ }
15
+ updateHitRate() {
16
+ const total = this.stats.hits + this.stats.misses;
17
+ this.stats.hitRate = total > 0 ? this.stats.hits / total : 0;
18
+ }
19
+ recordHit() {
20
+ this.stats.hits++;
21
+ this.updateHitRate();
22
+ }
23
+ recordMiss() {
24
+ this.stats.misses++;
25
+ this.updateHitRate();
26
+ }
27
+ recordEviction() {
28
+ this.stats.evictions++;
29
+ }
30
+ getStats() {
31
+ return { ...this.stats };
32
+ }
33
+ async get(key) {
34
+ const entry = this.cache.get(key);
35
+ if (!entry)
36
+ return null;
37
+ if (Date.now() > entry.expiresAt) {
38
+ this.cache.delete(key);
39
+ this.stats.size = this.cache.size;
40
+ return null;
41
+ }
42
+ entry.hits++;
43
+ entry.lastAccessedAt = Date.now();
44
+ return entry;
45
+ }
46
+ async set(key, entry) {
47
+ while (this.cache.size >= this.maxSize) {
48
+ await this.evictOldest();
49
+ }
50
+ this.cache.set(key, entry);
51
+ this.stats.size = this.cache.size;
52
+ }
53
+ async delete(key) {
54
+ this.cache.delete(key);
55
+ this.stats.size = this.cache.size;
56
+ }
57
+ async has(key) {
58
+ const entry = this.cache.get(key);
59
+ if (!entry)
60
+ return false;
61
+ if (Date.now() > entry.expiresAt) {
62
+ this.cache.delete(key);
63
+ this.stats.size = this.cache.size;
64
+ return false;
65
+ }
66
+ return true;
67
+ }
68
+ async clear() {
69
+ this.cache.clear();
70
+ this.stats.size = 0;
71
+ }
72
+ async getOldest() {
73
+ let oldest = null;
74
+ for (const entry of this.cache.values()) {
75
+ if (!oldest || entry.lastAccessedAt < oldest.lastAccessedAt) {
76
+ oldest = entry;
77
+ }
78
+ }
79
+ return oldest;
80
+ }
81
+ async size() {
82
+ return this.cache.size;
83
+ }
84
+ async findSimilar(embedding, threshold, limit = 1) {
85
+ const results = [];
86
+ const now = Date.now();
87
+ for (const entry of this.cache.values()) {
88
+ if (now > entry.expiresAt)
89
+ continue;
90
+ if (!entry.embedding)
91
+ continue;
92
+ const score = cosineSimilarity(embedding, entry.embedding);
93
+ if (score >= threshold) {
94
+ results.push({ ...entry, score });
95
+ }
96
+ }
97
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
98
+ }
99
+ async evictOldest() {
100
+ const oldest = await this.getOldest();
101
+ if (oldest) {
102
+ this.cache.delete(oldest.key);
103
+ this.stats.size = this.cache.size;
104
+ this.recordEviction();
105
+ }
106
+ }
107
+ }
108
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/cache/storage/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { CacheEntry, CacheStats, ToolCacheStorage, RedisClientLike } from '@cogitator-ai/types';
2
+ export interface RedisToolCacheStorageConfig {
3
+ client: RedisClientLike;
4
+ keyPrefix?: string;
5
+ maxSize?: number;
6
+ }
7
+ export declare class RedisToolCacheStorage implements ToolCacheStorage {
8
+ private client;
9
+ private prefix;
10
+ private maxSize;
11
+ private lruKey;
12
+ private stats;
13
+ constructor(config: RedisToolCacheStorageConfig);
14
+ private entryKey;
15
+ private updateHitRate;
16
+ recordHit(): void;
17
+ recordMiss(): void;
18
+ recordEviction(): void;
19
+ getStats(): CacheStats;
20
+ get(key: string): Promise<CacheEntry | null>;
21
+ set(key: string, entry: CacheEntry): Promise<void>;
22
+ delete(key: string): Promise<void>;
23
+ has(key: string): Promise<boolean>;
24
+ clear(): Promise<void>;
25
+ getOldest(): Promise<CacheEntry | null>;
26
+ size(): Promise<number>;
27
+ findSimilar(embedding: number[], threshold: number, limit?: number): Promise<Array<CacheEntry & {
28
+ score: number;
29
+ }>>;
30
+ private evictOldest;
31
+ }
32
+ //# sourceMappingURL=redis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../../src/cache/storage/redis.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAG7B,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAMX;gBAEU,MAAM,EAAE,2BAA2B;IAO/C,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,aAAa;IAKrB,SAAS,IAAI,IAAI;IAKjB,UAAU,IAAI,IAAI;IAKlB,cAAc,IAAI,IAAI;IAItB,QAAQ,IAAI,UAAU;IAIhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAuB5C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAelD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMlC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,SAAS,IAAI,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAMvC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IAKvB,WAAW,CACf,SAAS,EAAE,MAAM,EAAE,EACnB,SAAS,EAAE,MAAM,EACjB,KAAK,GAAE,MAAU,GAChB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;YAyBnC,WAAW;CAO1B"}
@@ -0,0 +1,127 @@
1
+ import { cosineSimilarity } from '../cache-key';
2
+ export class RedisToolCacheStorage {
3
+ client;
4
+ prefix;
5
+ maxSize;
6
+ lruKey;
7
+ stats = {
8
+ hits: 0,
9
+ misses: 0,
10
+ size: 0,
11
+ evictions: 0,
12
+ hitRate: 0,
13
+ };
14
+ constructor(config) {
15
+ this.client = config.client;
16
+ this.prefix = config.keyPrefix ?? 'toolcache:';
17
+ this.maxSize = config.maxSize ?? 1000;
18
+ this.lruKey = `${this.prefix}lru`;
19
+ }
20
+ entryKey(key) {
21
+ return `${this.prefix}entry:${key}`;
22
+ }
23
+ updateHitRate() {
24
+ const total = this.stats.hits + this.stats.misses;
25
+ this.stats.hitRate = total > 0 ? this.stats.hits / total : 0;
26
+ }
27
+ recordHit() {
28
+ this.stats.hits++;
29
+ this.updateHitRate();
30
+ }
31
+ recordMiss() {
32
+ this.stats.misses++;
33
+ this.updateHitRate();
34
+ }
35
+ recordEviction() {
36
+ this.stats.evictions++;
37
+ }
38
+ getStats() {
39
+ return { ...this.stats };
40
+ }
41
+ async get(key) {
42
+ const data = await this.client.get(this.entryKey(key));
43
+ if (!data)
44
+ return null;
45
+ const entry = JSON.parse(data);
46
+ if (Date.now() > entry.expiresAt) {
47
+ await this.delete(key);
48
+ return null;
49
+ }
50
+ entry.hits++;
51
+ entry.lastAccessedAt = Date.now();
52
+ const ttlSeconds = Math.ceil((entry.expiresAt - Date.now()) / 1000);
53
+ if (ttlSeconds > 0) {
54
+ await this.client.setex(this.entryKey(key), ttlSeconds, JSON.stringify(entry));
55
+ await this.client.zadd(this.lruKey, entry.lastAccessedAt, key);
56
+ }
57
+ return entry;
58
+ }
59
+ async set(key, entry) {
60
+ const currentSize = await this.size();
61
+ if (currentSize >= this.maxSize) {
62
+ await this.evictOldest();
63
+ }
64
+ const ttlSeconds = Math.ceil((entry.expiresAt - Date.now()) / 1000);
65
+ if (ttlSeconds > 0) {
66
+ await this.client.setex(this.entryKey(key), ttlSeconds, JSON.stringify(entry));
67
+ await this.client.zadd(this.lruKey, entry.lastAccessedAt, key);
68
+ }
69
+ this.stats.size = await this.size();
70
+ }
71
+ async delete(key) {
72
+ await this.client.del(this.entryKey(key));
73
+ await this.client.zrem(this.lruKey, key);
74
+ this.stats.size = await this.size();
75
+ }
76
+ async has(key) {
77
+ const data = await this.client.get(this.entryKey(key));
78
+ return data !== null;
79
+ }
80
+ async clear() {
81
+ const keys = await this.client.keys(`${this.prefix}*`);
82
+ if (keys.length > 0) {
83
+ await this.client.del(...keys);
84
+ }
85
+ this.stats.size = 0;
86
+ }
87
+ async getOldest() {
88
+ const keys = await this.client.zrange(this.lruKey, 0, 0);
89
+ if (keys.length === 0)
90
+ return null;
91
+ return this.get(keys[0]);
92
+ }
93
+ async size() {
94
+ const keys = await this.client.keys(`${this.prefix}entry:*`);
95
+ return keys.length;
96
+ }
97
+ async findSimilar(embedding, threshold, limit = 1) {
98
+ const keys = await this.client.keys(`${this.prefix}entry:*`);
99
+ if (keys.length === 0)
100
+ return [];
101
+ const results = [];
102
+ const now = Date.now();
103
+ const values = await this.client.mget(...keys);
104
+ for (const data of values) {
105
+ if (!data)
106
+ continue;
107
+ const entry = JSON.parse(data);
108
+ if (now > entry.expiresAt)
109
+ continue;
110
+ if (!entry.embedding)
111
+ continue;
112
+ const score = cosineSimilarity(embedding, entry.embedding);
113
+ if (score >= threshold) {
114
+ results.push({ ...entry, score });
115
+ }
116
+ }
117
+ return results.sort((a, b) => b.score - a.score).slice(0, limit);
118
+ }
119
+ async evictOldest() {
120
+ const keys = await this.client.zrange(this.lruKey, 0, 0);
121
+ if (keys.length > 0) {
122
+ await this.delete(keys[0]);
123
+ this.recordEviction();
124
+ }
125
+ }
126
+ }
127
+ //# sourceMappingURL=redis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis.js","sourceRoot":"","sources":["../../../src/cache/storage/redis.ts"],"names":[],"mappings":"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"}