@cachly-dev/mcp-server 0.9.19 → 0.9.21

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 (39) hide show
  1. package/.github/workflows/publish.yml +42 -0
  2. package/LICENSE +202 -0
  3. package/dist/handlers/advanced.d.ts +6 -0
  4. package/dist/handlers/advanced.js +586 -0
  5. package/dist/handlers/advanced.js.map +1 -0
  6. package/dist/handlers/cache.d.ts +6 -0
  7. package/dist/handlers/cache.js +520 -0
  8. package/dist/handlers/cache.js.map +1 -0
  9. package/dist/handlers/context.d.ts +6 -0
  10. package/dist/handlers/context.js +177 -0
  11. package/dist/handlers/context.js.map +1 -0
  12. package/dist/handlers/fedbrain.d.ts +6 -0
  13. package/dist/handlers/fedbrain.js +1078 -0
  14. package/dist/handlers/fedbrain.js.map +1 -0
  15. package/dist/handlers/instances.d.ts +9 -0
  16. package/dist/handlers/instances.js +153 -0
  17. package/dist/handlers/instances.js.map +1 -0
  18. package/dist/handlers/roadmap.d.ts +6 -0
  19. package/dist/handlers/roadmap.js +165 -0
  20. package/dist/handlers/roadmap.js.map +1 -0
  21. package/dist/handlers/syndicate.d.ts +6 -0
  22. package/dist/handlers/syndicate.js +339 -0
  23. package/dist/handlers/syndicate.js.map +1 -0
  24. package/dist/handlers/team.d.ts +6 -0
  25. package/dist/handlers/team.js +1048 -0
  26. package/dist/handlers/team.js.map +1 -0
  27. package/dist/index.js +38 -4018
  28. package/dist/index.js.map +1 -1
  29. package/glama.json +6 -0
  30. package/package.json +1 -1
  31. package/src/handlers/advanced.ts +637 -0
  32. package/src/handlers/cache.ts +634 -0
  33. package/src/handlers/context.ts +218 -0
  34. package/src/handlers/fedbrain.ts +1143 -0
  35. package/src/handlers/instances.ts +180 -0
  36. package/src/handlers/roadmap.ts +192 -0
  37. package/src/handlers/syndicate.ts +451 -0
  38. package/src/handlers/team.ts +1163 -0
  39. package/src/index.ts +44 -4465
@@ -0,0 +1,520 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js';
3
+ import { readdir, stat, readFile } from 'node:fs/promises';
4
+ import { join, relative, extname } from 'node:path';
5
+ import { computeEmbedding, hasEmbedProvider, embedProviderHint } from '../embeddings.js';
6
+ import { detectNamespace } from '../namespace.js';
7
+ import { simpleHash } from '../confidence.js';
8
+ export const CACHE_TOOL_NAMES = new Set([
9
+ 'cache_get', 'cache_set', 'cache_delete', 'cache_exists', 'cache_ttl', 'cache_keys',
10
+ 'cache_stats', 'semantic_search', 'detect_namespace', 'cache_warmup', 'index_project',
11
+ 'cache_mset', 'cache_mget', 'cache_lock_acquire', 'cache_lock_release',
12
+ 'cache_stream_set', 'cache_stream_get',
13
+ ]);
14
+ export async function handleCacheTool(name, args, getConnection, apiFetch) {
15
+ switch (name) {
16
+ case 'cache_get': {
17
+ const { instance_id, key } = args;
18
+ const redis = await getConnection(instance_id);
19
+ const value = await redis.get(key);
20
+ if (value === null)
21
+ return `Key \`${key}\` → **not found** (null)`;
22
+ let pretty = value;
23
+ try {
24
+ pretty = JSON.stringify(JSON.parse(value), null, 2);
25
+ }
26
+ catch {
27
+ // not JSON — return raw
28
+ }
29
+ return `Key \`${key}\`:\n\`\`\`\n${pretty}\n\`\`\``;
30
+ }
31
+ case 'cache_set': {
32
+ const { instance_id, key, value, ttl } = args;
33
+ const redis = await getConnection(instance_id);
34
+ if (ttl && ttl > 0) {
35
+ await redis.set(key, value, 'EX', ttl);
36
+ return `✅ Set \`${key}\` (TTL: ${ttl}s)`;
37
+ }
38
+ await redis.set(key, value);
39
+ return `✅ Set \`${key}\` (no expiry)`;
40
+ }
41
+ case 'cache_delete': {
42
+ const { instance_id, keys } = args;
43
+ const redis = await getConnection(instance_id);
44
+ const deleted = await redis.del(...keys);
45
+ return `✅ Deleted **${deleted}** of ${keys.length} key(s): ${keys.map((k) => `\`${k}\``).join(', ')}`;
46
+ }
47
+ case 'cache_exists': {
48
+ const { instance_id, keys } = args;
49
+ const redis = await getConnection(instance_id);
50
+ const count = await redis.exists(...keys);
51
+ return `**${count}** of ${keys.length} key(s) exist in cache.`;
52
+ }
53
+ case 'cache_ttl': {
54
+ const { instance_id, key } = args;
55
+ const redis = await getConnection(instance_id);
56
+ const ttl = await redis.ttl(key);
57
+ if (ttl === -2)
58
+ return `Key \`${key}\` → **does not exist**`;
59
+ if (ttl === -1)
60
+ return `Key \`${key}\` → **no expiry** (persists forever)`;
61
+ const mins = Math.floor(ttl / 60);
62
+ const secs = ttl % 60;
63
+ return `Key \`${key}\` → TTL: **${ttl}s** (${mins}m ${secs}s remaining)`;
64
+ }
65
+ case 'cache_keys': {
66
+ const { instance_id, pattern = '*', count = 50 } = args;
67
+ const limit = Math.min(count, 500);
68
+ const redis = await getConnection(instance_id);
69
+ const keys = [];
70
+ const stream = redis.scanStream({ match: pattern, count: 100 });
71
+ await new Promise((resolve, reject) => {
72
+ stream.on('data', (batch) => {
73
+ keys.push(...batch);
74
+ if (keys.length >= limit) {
75
+ stream.destroy();
76
+ resolve();
77
+ }
78
+ });
79
+ stream.on('end', resolve);
80
+ stream.on('error', reject);
81
+ });
82
+ const result = keys.slice(0, limit);
83
+ if (result.length === 0)
84
+ return `No keys found matching pattern \`${pattern}\`.`;
85
+ return [
86
+ `Found **${result.length}** key(s) matching \`${pattern}\`:`,
87
+ ...result.map((k) => ` • \`${k}\``),
88
+ result.length === limit ? `\n_(showing first ${limit} — narrow pattern to see more)_` : '',
89
+ ]
90
+ .filter(Boolean)
91
+ .join('\n');
92
+ }
93
+ case 'cache_stats': {
94
+ const { instance_id } = args;
95
+ const redis = await getConnection(instance_id);
96
+ const [infoAll, infoStats, infoKeyspace] = await Promise.all([
97
+ redis.info('memory'),
98
+ redis.info('stats'),
99
+ redis.info('keyspace'),
100
+ ]);
101
+ const parse = (section, field) => section.match(new RegExp(`${field}:([^\r\n]+)`))?.[1]?.trim() ?? 'n/a';
102
+ const usedMem = parse(infoAll, 'used_memory_human');
103
+ const peakMem = parse(infoAll, 'used_memory_peak_human');
104
+ const hits = parse(infoStats, 'keyspace_hits');
105
+ const misses = parse(infoStats, 'keyspace_misses');
106
+ const opsPerSec = parse(infoStats, 'instantaneous_ops_per_sec');
107
+ const connectedClients = (await redis.info('clients')).match(/connected_clients:(\d+)/)?.[1] ?? 'n/a';
108
+ const hitsN = parseInt(hits) || 0;
109
+ const missesN = parseInt(misses) || 0;
110
+ const total = hitsN + missesN;
111
+ const hitRate = total > 0 ? ((hitsN / total) * 100).toFixed(1) : 'n/a';
112
+ const keyspaceLines = infoKeyspace
113
+ .split('\n')
114
+ .filter((l) => l.startsWith('db'))
115
+ .map((l) => ` ${l.trim()}`);
116
+ return [
117
+ `📊 **Cache Stats for instance \`${instance_id}\`:**`,
118
+ ``,
119
+ ` 💾 Memory used: ${usedMem} (peak: ${peakMem})`,
120
+ ` ⚡ Ops/sec: ${opsPerSec}`,
121
+ ` 🎯 Hit rate: ${hitRate}% (${hits} hits / ${misses} misses)`,
122
+ ` 🔗 Clients: ${connectedClients}`,
123
+ ``,
124
+ keyspaceLines.length > 0
125
+ ? ` 🗂️ Keyspace:\n${keyspaceLines.join('\n')}`
126
+ : ` 🗂️ Keyspace: (empty)`,
127
+ ].join('\n');
128
+ }
129
+ case 'semantic_search': {
130
+ const { instance_id, query, threshold = 0.82, namespace: nsArg = 'cachly:sem', top_k = 5, use_hybrid = false, auto_namespace = false, } = args;
131
+ // resolve namespace from query text when requested
132
+ const namespace = auto_namespace ? detectNamespace(query) : nsArg;
133
+ if (!hasEmbedProvider()) {
134
+ return (`❌ semantic_search requires an embedding provider.\n\n` +
135
+ `Current: ${embedProviderHint()}\n\n` +
136
+ `Set one of these in your MCP env config:\n` +
137
+ ` OPENAI_API_KEY (provider: openai – default)\n` +
138
+ ` MISTRAL_API_KEY (provider: mistral)\n` +
139
+ ` COHERE_API_KEY (provider: cohere)\n` +
140
+ ` GEMINI_API_KEY (provider: gemini)\n` +
141
+ ` OLLAMA_BASE_URL (provider: ollama – local, no key needed)\n` +
142
+ `Also set: CACHLY_EMBED_PROVIDER=<provider>`);
143
+ }
144
+ const inst = await apiFetch(`/api/v1/instances/${instance_id}`);
145
+ if (!inst.vector_token) {
146
+ return (`❌ Semantic search is only available on Speed and Business tiers.\n\n` +
147
+ `Your instance "${inst.name}" is on the **${inst.tier.toUpperCase()}** tier.\n` +
148
+ `Upgrade at https://cachly.dev/instances/${instance_id}`);
149
+ }
150
+ // Compute embedding via configured provider
151
+ const embedding = await computeEmbedding(query);
152
+ // Query cachly vector API
153
+ const vectorUrl = process.env.CACHLY_VECTOR_URL ?? `https://api.cachly.dev/v1/sem/${inst.vector_token}`;
154
+ const searchPayload = { embedding, namespace, threshold, top_k };
155
+ // hybrid BM25+Vector RRF: include query text when requested.
156
+ if (use_hybrid) {
157
+ searchPayload['hybrid'] = true;
158
+ searchPayload['prompt'] = query;
159
+ }
160
+ const searchRes = await fetch(`${vectorUrl}/search`, {
161
+ method: 'POST',
162
+ headers: { 'Content-Type': 'application/json' },
163
+ body: JSON.stringify(searchPayload),
164
+ });
165
+ if (!searchRes.ok) {
166
+ throw new McpError(ErrorCode.InternalError, `Vector search failed: ${searchRes.statusText}`);
167
+ }
168
+ const results = (await searchRes.json());
169
+ if (!results.length || (results.length === 1 && !results[0].found)) {
170
+ return (`🔍 No semantically similar entries found for:\n _"${query}"_\n\n` +
171
+ `Try lowering the threshold (current: ${threshold}) or using different keywords.`);
172
+ }
173
+ const redis = await getConnection(instance_id);
174
+ const lines = [
175
+ `🔍 **Semantic search results** for: _"${query}"_`,
176
+ ` Threshold: ${threshold} · Namespace: \`${namespace}\``,
177
+ ``,
178
+ ];
179
+ for (const hit of results) {
180
+ if (!hit.found || !hit.id)
181
+ continue;
182
+ const value = await redis.get(`${namespace}:val:${hit.id}`);
183
+ lines.push(`**Match** (similarity: ${((hit.similarity ?? 0) * 100).toFixed(1)}%)`, ` Prompt: _"${hit.prompt ?? '(unknown)'}"_`, value ? ` Value: \`${value.slice(0, 200)}${value.length > 200 ? '…' : ''}\`` : ` Value: _(evicted from cache)_`, ``);
184
+ }
185
+ return lines.join('\n');
186
+ }
187
+ // ── Namespace Auto-Detection ──────────────────────────────────────────
188
+ case 'detect_namespace': {
189
+ const { prompt } = args;
190
+ const ns = detectNamespace(prompt);
191
+ const typeLabel = ns.split(':').pop();
192
+ const descriptions = {
193
+ code: '💻 Code — contains programming constructs or syntax',
194
+ translation: '🌐 Translation — asks to translate between languages',
195
+ summary: '📝 Summary — requests a summary or key points (TL;DR)',
196
+ qa: '❓ Q&A — a direct question or query',
197
+ creative: '🎨 Creative — general, creative, or conversational prompt',
198
+ };
199
+ return [
200
+ `**Detected namespace:** \`${ns}\``,
201
+ `**Type:** ${descriptions[typeLabel] ?? typeLabel}`,
202
+ ``,
203
+ `_Prompt: "${prompt.slice(0, 120)}${prompt.length > 120 ? '…' : ''}"_`,
204
+ ``,
205
+ `💡 Use this namespace in \`semantic_search\` or \`cache_warmup\` for better hit rates.`,
206
+ ` Set \`auto_namespace: true\` to apply this detection automatically.`,
207
+ ].join('\n');
208
+ }
209
+ // ── Cache Warmup ───────────────────────────────────────────────────────
210
+ case 'cache_warmup': {
211
+ const { instance_id, entries: rawEntries, namespace: nsArg = 'cachly:sem', ttl, auto_namespace = false, } = args;
212
+ if (!hasEmbedProvider()) {
213
+ return (`❌ cache_warmup requires an embedding provider.\n\n` +
214
+ `Current: ${embedProviderHint()}\n\n` +
215
+ `Supported: openai (default) · mistral · cohere · ollama (local) · gemini\n` +
216
+ `Set CACHLY_EMBED_PROVIDER and the matching API key env var.`);
217
+ }
218
+ const inst = await apiFetch(`/api/v1/instances/${instance_id}`);
219
+ const vectorUrl = process.env.CACHLY_VECTOR_URL ??
220
+ (inst.vector_token ? `https://api.cachly.dev/v1/sem/${inst.vector_token}` : null);
221
+ const redis = await getConnection(instance_id);
222
+ let warmed = 0;
223
+ let skipped = 0;
224
+ const details = [];
225
+ for (const entry of rawEntries) {
226
+ // resolve namespace per entry
227
+ const ns = entry.namespace ?? (auto_namespace ? detectNamespace(entry.prompt) : nsArg);
228
+ // Compute embedding for this prompt
229
+ const embedding = await computeEmbedding(entry.prompt);
230
+ // Check if a very-similar entry already exists (threshold 0.98 → skip to avoid duplicates)
231
+ let alreadyCached = false;
232
+ if (vectorUrl) {
233
+ const checkRes = await fetch(`${vectorUrl}/search`, {
234
+ method: 'POST',
235
+ headers: { 'Content-Type': 'application/json' },
236
+ body: JSON.stringify({ embedding, namespace: ns, threshold: 0.98 }),
237
+ }).catch(() => null);
238
+ if (checkRes?.ok) {
239
+ const results = (await checkRes.json());
240
+ alreadyCached = results[0]?.found ?? false;
241
+ }
242
+ }
243
+ if (alreadyCached) {
244
+ skipped++;
245
+ details.push(` ⏭️ _"${entry.prompt.slice(0, 60)}${entry.prompt.length > 60 ? '…' : ''}"_ → already cached`);
246
+ continue;
247
+ }
248
+ // Write value to Valkey
249
+ const id = randomUUID();
250
+ const vk = `${ns}:val:${id}`;
251
+ if (ttl && ttl > 0) {
252
+ await redis.set(vk, entry.value, 'EX', ttl);
253
+ }
254
+ else {
255
+ await redis.set(vk, entry.value);
256
+ }
257
+ if (vectorUrl) {
258
+ // pgvector path – index embedding in HNSW
259
+ const body = { id, prompt: entry.prompt, namespace: ns, embedding };
260
+ if (ttl && ttl > 0) {
261
+ body['expires_at'] = new Date(Date.now() + ttl * 1000).toISOString();
262
+ }
263
+ await fetch(`${vectorUrl}/entries`, {
264
+ method: 'POST',
265
+ headers: { 'Content-Type': 'application/json' },
266
+ body: JSON.stringify(body),
267
+ }).catch(() => undefined);
268
+ }
269
+ else {
270
+ // Legacy SCAN path – write emb key to Valkey
271
+ const embKey = `${ns}:emb:${id}`;
272
+ const embPayload = JSON.stringify({ embedding, prompt: entry.prompt });
273
+ if (ttl && ttl > 0) {
274
+ await redis.set(embKey, embPayload, 'EX', ttl);
275
+ }
276
+ else {
277
+ await redis.set(embKey, embPayload);
278
+ }
279
+ }
280
+ warmed++;
281
+ details.push(` ✅ _"${entry.prompt.slice(0, 60)}${entry.prompt.length > 60 ? '…' : ''}"_ → \`${ns}\``);
282
+ }
283
+ return [
284
+ `🔥 **Cache Warmup Complete**`,
285
+ ``,
286
+ ` ✅ Warmed: **${warmed}** new entries`,
287
+ ` ⏭️ Skipped: **${skipped}** (already cached at ≥ 0.98 similarity)`,
288
+ ` 📦 Total: ${rawEntries.length}`,
289
+ auto_namespace
290
+ ? ` 🏷️ Namespacing: auto-detected per prompt`
291
+ : ` 🏷️ Namespace: \`${nsArg}\``,
292
+ vectorUrl
293
+ ? ` 🔍 Mode: pgvector HNSW (Speed/Business tier)`
294
+ : ` 🔍 Mode: Valkey SCAN (upgrade to Speed tier for scalable search)`,
295
+ ``,
296
+ ...details,
297
+ ].join('\n');
298
+ }
299
+ // ── index_project – Codebase Indexing ─────────────────────────────────────
300
+ case 'index_project': {
301
+ const { instance_id, dir, extensions: extArg, max_files = 100, ttl = 86400, summary_chars = 1200, namespace: nsArg = 'cachly:sem:code', } = args;
302
+ const ALLOWED_EXT = new Set((extArg ?? ['ts', 'js', 'tsx', 'jsx', 'go', 'py', 'java', 'rs', 'md', 'kt', 'swift']).map((e) => (e.startsWith('.') ? e : `.${e}`)));
303
+ // Recursively collect files up to max_files limit
304
+ const files = [];
305
+ async function walk(d) {
306
+ if (files.length >= max_files)
307
+ return;
308
+ const entries = await readdir(d, { withFileTypes: true }).catch(() => null);
309
+ if (!entries)
310
+ return;
311
+ for (const entry of entries) {
312
+ if (files.length >= max_files)
313
+ break;
314
+ const full = join(d, entry.name);
315
+ if (entry.isDirectory()) {
316
+ if (['.git', 'node_modules', 'dist', 'build', '.next', '__pycache__', 'vendor'].includes(entry.name))
317
+ continue;
318
+ await walk(full);
319
+ }
320
+ else if (entry.isFile() && ALLOWED_EXT.has(extname(entry.name).toLowerCase())) {
321
+ files.push(full);
322
+ }
323
+ }
324
+ }
325
+ await walk(dir);
326
+ if (files.length === 0) {
327
+ return `❌ No matching files found in \`${dir}\`.\nExtensions checked: ${[...ALLOWED_EXT].join(', ')}`;
328
+ }
329
+ const inst = await apiFetch(`/api/v1/instances/${instance_id}`);
330
+ const vectorUrl = process.env.CACHLY_VECTOR_URL ??
331
+ (inst.vector_token ? `https://api.cachly.dev/v1/sem/${inst.vector_token}` : null);
332
+ const canEmbed = vectorUrl && hasEmbedProvider();
333
+ let indexed = 0;
334
+ let skipped = 0;
335
+ let errors = 0;
336
+ let semanticIndexed = 0;
337
+ let unchanged = 0;
338
+ const details = [];
339
+ const expiresAt = new Date(Date.now() + ttl * 1000).toISOString();
340
+ const redis = await getConnection(instance_id);
341
+ for (const filePath of files) {
342
+ const relPath = relative(dir, filePath);
343
+ let content;
344
+ let fileSize;
345
+ try {
346
+ const s = await stat(filePath);
347
+ if (s.size > 200_000) {
348
+ skipped++;
349
+ continue;
350
+ } // skip files >200 KB
351
+ fileSize = s.size;
352
+ content = await readFile(filePath, 'utf-8');
353
+ }
354
+ catch {
355
+ errors++;
356
+ continue;
357
+ }
358
+ // ── Smart invalidation: hash-based change detection ──
359
+ // Compute a simple hash of file content to skip unchanged files
360
+ const hashKey = `cachly:idx:hash:${relPath}`;
361
+ const contentHash = `${fileSize}:${content.length}:${simpleHash(content)}`;
362
+ const existingHash = await redis.get(hashKey);
363
+ if (existingHash === contentHash) {
364
+ // File unchanged — refresh TTL but skip re-indexing
365
+ const idxKey = `cachly:idx:${relPath}`;
366
+ if (ttl > 0)
367
+ await redis.expire(idxKey, ttl);
368
+ if (ttl > 0)
369
+ await redis.expire(hashKey, ttl);
370
+ unchanged++;
371
+ continue;
372
+ }
373
+ const excerpt = content.slice(0, summary_chars).replace(/\s+/g, ' ').trim();
374
+ // ── Layer 1: Keyword index in Valkey (always works, no embedding needed) ──
375
+ const idxKey = `cachly:idx:${relPath}`;
376
+ const idxValue = `File: ${relPath}\n${excerpt}`;
377
+ if (ttl > 0) {
378
+ await redis.set(idxKey, idxValue, 'EX', ttl);
379
+ }
380
+ else {
381
+ await redis.set(idxKey, idxValue);
382
+ }
383
+ // Store content hash for smart invalidation on next run
384
+ if (ttl > 0) {
385
+ await redis.set(hashKey, contentHash, 'EX', ttl);
386
+ }
387
+ else {
388
+ await redis.set(hashKey, contentHash);
389
+ }
390
+ indexed++;
391
+ details.push(` ✅ ${relPath}`);
392
+ // ── Layer 2: Semantic vector index (optional, only if embedding available) ──
393
+ if (canEmbed) {
394
+ try {
395
+ const prompt = `File: ${relPath}\n${excerpt}`;
396
+ const embedding = await computeEmbedding(prompt);
397
+ const id = randomUUID();
398
+ await fetch(`${vectorUrl}/entries`, {
399
+ method: 'POST',
400
+ headers: { 'Content-Type': 'application/json' },
401
+ body: JSON.stringify({ id, prompt, namespace: nsArg, embedding, expires_at: expiresAt }),
402
+ });
403
+ await redis.set(`${nsArg}:val:${id}`, relPath, 'EX', ttl);
404
+ semanticIndexed++;
405
+ }
406
+ catch {
407
+ // Semantic indexing failed — keyword index is enough
408
+ }
409
+ }
410
+ }
411
+ const mode = canEmbed ? '🔍 Keyword + 🎯 Semantic' : '🔍 Keyword only (no embedding provider)';
412
+ return [
413
+ `📂 **index_project Complete** — ${mode}`,
414
+ ``,
415
+ ` 📁 Dir: ${dir}`,
416
+ ` ✅ Indexed: **${indexed}** files (new/changed)`,
417
+ ` ♻️ Unchanged: ${unchanged} files (hash match — skipped)`,
418
+ ...(canEmbed ? [` 🎯 Semantic: **${semanticIndexed}** files (vector-searchable)`] : []),
419
+ ` ⏭️ Skipped: ${skipped} (too large or filtered)`,
420
+ ` ❌ Errors: ${errors}`,
421
+ ` ⏱️ TTL: ${ttl}s (${Math.round(ttl / 3600)}h)`,
422
+ ``,
423
+ `💡 **Next steps:**`,
424
+ ` 1. Use \`smart_recall("how does auth work")\` to find relevant files.`,
425
+ ` 2. Re-run index_project after major refactors.`,
426
+ ...(canEmbed ? [] : [` 3. Set OPENAI_API_KEY (or similar) in .env to also enable semantic search.`]),
427
+ ``,
428
+ ...(details.length <= 20 ? details : [...details.slice(0, 20), ` … and ${details.length - 20} more`]),
429
+ ].join('\n');
430
+ }
431
+ // ── Bulk / Lock / Stream tools ──────────────────────────────────────────
432
+ case 'cache_mset': {
433
+ const { instance_id, items } = args;
434
+ if (!Array.isArray(items) || items.length === 0)
435
+ return '⚠️ No items provided.';
436
+ const redis = await getConnection(instance_id);
437
+ const pipe = redis.pipeline();
438
+ for (const item of items) {
439
+ const serialized = typeof item.value === 'string' ? item.value : JSON.stringify(item.value);
440
+ if (item.ttl && item.ttl > 0) {
441
+ pipe.set(item.key, serialized, 'EX', item.ttl);
442
+ }
443
+ else {
444
+ pipe.set(item.key, serialized);
445
+ }
446
+ }
447
+ await pipe.exec();
448
+ return `✅ **cache_mset** – ${items.length} key(s) written in one pipeline round-trip.\n` +
449
+ items.map(i => ` • \`${i.key}\`${i.ttl ? ` (TTL ${i.ttl}s)` : ''}`).join('\n');
450
+ }
451
+ case 'cache_mget': {
452
+ const { instance_id, keys } = args;
453
+ if (!Array.isArray(keys) || keys.length === 0)
454
+ return '⚠️ No keys provided.';
455
+ const redis = await getConnection(instance_id);
456
+ const raws = await redis.mget(...keys);
457
+ const result = keys.map((k, i) => {
458
+ const raw = raws[i];
459
+ if (raw === null)
460
+ return ` • \`${k}\`: _null (miss)_`;
461
+ return ` • \`${k}\`: ${raw}`;
462
+ });
463
+ return `✅ **cache_mget** – ${keys.length} key(s) fetched in one round-trip.\n` + result.join('\n');
464
+ }
465
+ case 'cache_lock_acquire': {
466
+ const { instance_id, key, ttl_ms = 5000, retries = 3, retry_delay_ms = 50 } = args;
467
+ const redis = await getConnection(instance_id);
468
+ const lockKey = `cachly:lock:${key}`;
469
+ const token = randomUUID();
470
+ for (let attempt = 0; attempt <= retries; attempt++) {
471
+ const result = await redis.set(lockKey, token, 'PX', ttl_ms, 'NX');
472
+ if (result === 'OK') {
473
+ return `🔒 **cache_lock_acquire** – Lock acquired!\n\n Key: \`${key}\`\n Token: \`${token}\`\n TTL: ${ttl_ms} ms\n\n💡 Use **cache_lock_release** with this token to release early.`;
474
+ }
475
+ if (attempt < retries)
476
+ await new Promise(r => setTimeout(r, retry_delay_ms));
477
+ }
478
+ return `❌ **cache_lock_acquire** – Could not acquire lock for \`${key}\` after ${retries + 1} attempts.`;
479
+ }
480
+ case 'cache_lock_release': {
481
+ const { instance_id, key, token } = args;
482
+ const redis = await getConnection(instance_id);
483
+ const script = `if redis.call("get",KEYS[1])==ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end`;
484
+ const released = await redis.eval(script, 1, `cachly:lock:${key}`, token);
485
+ return released === 1
486
+ ? `🔓 **cache_lock_release** – Lock \`${key}\` released.`
487
+ : `⚠️ **cache_lock_release** – Lock \`${key}\` expired or token mismatch.`;
488
+ }
489
+ case 'cache_stream_set': {
490
+ const { instance_id, key, chunks, ttl } = args;
491
+ if (!Array.isArray(chunks) || chunks.length === 0)
492
+ return '⚠️ No chunks provided.';
493
+ const redis = await getConnection(instance_id);
494
+ const listKey = `cachly:stream:${key}`;
495
+ await redis.del(listKey);
496
+ const pipe = redis.pipeline();
497
+ for (const chunk of chunks)
498
+ pipe.rpush(listKey, chunk);
499
+ if (ttl && ttl > 0)
500
+ pipe.expire(listKey, ttl);
501
+ await pipe.exec();
502
+ return `✅ **cache_stream_set** – ${chunks.length} chunk(s) stored.\n Key: \`${key}\`\n${ttl ? ` TTL: ${ttl}s\n` : ''} Total size: ${chunks.reduce((a, c) => a + c.length, 0)} chars`;
503
+ }
504
+ case 'cache_stream_get': {
505
+ const { instance_id, key } = args;
506
+ const redis = await getConnection(instance_id);
507
+ const listKey = `cachly:stream:${key}`;
508
+ const len = await redis.llen(listKey);
509
+ if (len === 0)
510
+ return `⚠️ **cache_stream_get** – Cache miss for key \`${key}\`.`;
511
+ const chunks = await redis.lrange(listKey, 0, -1);
512
+ const full = chunks.join('');
513
+ const preview = full.slice(0, 500);
514
+ return `✅ **cache_stream_get** – ${len} chunk(s) retrieved for \`${key}\`.\n\n**Preview** (first 500 chars):\n\`\`\`\n${preview}${preview.length < full.length ? '…' : ''}\n\`\`\``;
515
+ }
516
+ default:
517
+ return null;
518
+ }
519
+ }
520
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/handlers/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Redis } from 'ioredis';
2
+ type GetConnection = (instanceId: string) => Promise<Redis>;
3
+ type ApiFetch = <T>(path: string, options?: RequestInit) => Promise<T>;
4
+ export declare const CONTEXT_TOOL_NAMES: Set<string>;
5
+ export declare function handleContextTool(name: string, args: Record<string, unknown>, getConnection: GetConnection, apiFetch: ApiFetch): Promise<string | null>;
6
+ export {};