@claude-flow/cli 3.5.66 → 3.5.68
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/dist/src/init/claudemd-generator.d.ts.map +1 -1
- package/dist/src/init/claudemd-generator.js +93 -32
- package/dist/src/init/claudemd-generator.js.map +1 -1
- package/dist/src/ruvector/diskann-backend.d.ts +78 -0
- package/dist/src/ruvector/diskann-backend.d.ts.map +1 -0
- package/dist/src/ruvector/diskann-backend.js +310 -0
- package/dist/src/ruvector/diskann-backend.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudemd-generator.d.ts","sourceRoot":"","sources":["../../../src/init/claudemd-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claudemd-generator.d.ts","sourceRoot":"","sources":["../../../src/init/claudemd-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA0hBhE;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAQ1F;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAEpE;AAED,8CAA8C;AAC9C,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAOtF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -161,7 +161,7 @@ npx @claude-flow/cli@latest doctor --fix
|
|
|
161
161
|
\`\`\``;
|
|
162
162
|
}
|
|
163
163
|
function agentTypes() {
|
|
164
|
-
return `## Available Agents (
|
|
164
|
+
return `## Available Agents (16 Roles + Custom)
|
|
165
165
|
|
|
166
166
|
### Core Development
|
|
167
167
|
\`coder\`, \`reviewer\`, \`tester\`, \`planner\`, \`researcher\`
|
|
@@ -169,14 +169,13 @@ function agentTypes() {
|
|
|
169
169
|
### Specialized
|
|
170
170
|
\`security-architect\`, \`security-auditor\`, \`memory-specialist\`, \`performance-engineer\`
|
|
171
171
|
|
|
172
|
-
###
|
|
172
|
+
### Coordination
|
|
173
173
|
\`hierarchical-coordinator\`, \`mesh-coordinator\`, \`adaptive-coordinator\`
|
|
174
174
|
|
|
175
175
|
### GitHub & Repository
|
|
176
176
|
\`pr-manager\`, \`code-review-swarm\`, \`issue-tracker\`, \`release-manager\`
|
|
177
177
|
|
|
178
|
-
|
|
179
|
-
\`sparc-coord\`, \`sparc-coder\`, \`specification\`, \`pseudocode\`, \`architecture\``;
|
|
178
|
+
Any string can be used as a custom agent type — these are the typed roles with specialized behavior.`;
|
|
180
179
|
}
|
|
181
180
|
function hooksSystem() {
|
|
182
181
|
return `## Hooks System (27 Hooks + 12 Workers)
|
|
@@ -228,21 +227,37 @@ npx @claude-flow/cli@latest hooks post-task --task-id "[id]" --success true --st
|
|
|
228
227
|
- ALWAYS store patterns in memory after solving bugs, completing features, or finding optimizations`;
|
|
229
228
|
}
|
|
230
229
|
function memoryCommands() {
|
|
231
|
-
return `## Memory
|
|
230
|
+
return `## Memory & Vector Search
|
|
231
|
+
|
|
232
|
+
### MCP Tools (use via ToolSearch to discover)
|
|
233
|
+
|
|
234
|
+
| Tool | Description |
|
|
235
|
+
|------|-------------|
|
|
236
|
+
| \`memory_store\` | Store value with ONNX 384-dim vector embedding |
|
|
237
|
+
| \`memory_search\` | Semantic vector search by query |
|
|
238
|
+
| \`memory_retrieve\` | Get entry by key |
|
|
239
|
+
| \`memory_list\` | List entries in namespace |
|
|
240
|
+
| \`memory_delete\` | Delete entry |
|
|
241
|
+
| \`memory_import_claude\` | Import Claude Code memories into AgentDB (allProjects=true for all) |
|
|
242
|
+
| \`memory_search_unified\` | Search across ALL namespaces (Claude + AgentDB + patterns) |
|
|
243
|
+
| \`memory_bridge_status\` | Show bridge health, vectors, SONA, intelligence |
|
|
244
|
+
|
|
245
|
+
### CLI Commands
|
|
232
246
|
|
|
233
247
|
\`\`\`bash
|
|
234
|
-
# Store
|
|
248
|
+
# Store with vector embedding
|
|
235
249
|
npx @claude-flow/cli@latest memory store --key "pattern-auth" --value "JWT with refresh" --namespace patterns
|
|
236
250
|
|
|
237
|
-
#
|
|
251
|
+
# Semantic search
|
|
238
252
|
npx @claude-flow/cli@latest memory search --query "authentication patterns"
|
|
239
253
|
|
|
240
|
-
#
|
|
241
|
-
|
|
254
|
+
# Import all Claude Code memories into AgentDB
|
|
255
|
+
node .claude/helpers/auto-memory-hook.mjs import-all
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
### Claude Code ↔ AgentDB Bridge
|
|
242
259
|
|
|
243
|
-
|
|
244
|
-
npx @claude-flow/cli@latest memory retrieve --key "pattern-auth" --namespace patterns
|
|
245
|
-
\`\`\``;
|
|
260
|
+
Claude Code auto-memory files (\`~/.claude/projects/*/memory/*.md\`) are automatically imported into AgentDB with ONNX vector embeddings on session start. Use \`memory_search_unified\` to search across both stores.`;
|
|
246
261
|
}
|
|
247
262
|
function securityRulesLight() {
|
|
248
263
|
return `## Security Rules
|
|
@@ -298,8 +313,8 @@ function performanceSection() {
|
|
|
298
313
|
- Always run benchmarks before and after performance changes
|
|
299
314
|
- Always profile before optimizing — never guess at bottlenecks
|
|
300
315
|
- Prefer algorithmic improvements over micro-optimizations
|
|
301
|
-
-
|
|
302
|
-
-
|
|
316
|
+
- Use DiskANN or HNSW for vector search (auto-selected by dataset size)
|
|
317
|
+
- Use Int8 quantization for ~4x memory reduction when needed
|
|
303
318
|
|
|
304
319
|
### Performance Tooling
|
|
305
320
|
\`\`\`bash
|
|
@@ -314,18 +329,18 @@ npx @claude-flow/cli@latest performance metrics --format table
|
|
|
314
329
|
- Use agent routing code 7 (hierarchical/specialized) for performance tasks`;
|
|
315
330
|
}
|
|
316
331
|
function intelligenceSystem() {
|
|
317
|
-
return `## Intelligence System
|
|
318
|
-
|
|
319
|
-
- **SONA**: Self-Optimizing
|
|
320
|
-
- **HNSW**:
|
|
321
|
-
- **
|
|
322
|
-
- **
|
|
323
|
-
|
|
324
|
-
The
|
|
325
|
-
1. **RETRIEVE**
|
|
326
|
-
2. **JUDGE**
|
|
327
|
-
3. **DISTILL**
|
|
328
|
-
4. **CONSOLIDATE**
|
|
332
|
+
return `## Intelligence System
|
|
333
|
+
|
|
334
|
+
- **SONA**: Self-Optimizing Pattern Learning (sub-millisecond pattern matching)
|
|
335
|
+
- **HNSW/DiskANN**: HNSW-indexed vector search with DiskANN SSD-friendly fallback
|
|
336
|
+
- **ONNX Embeddings**: all-MiniLM-L6-v2, 384 dimensions, real neural vectors
|
|
337
|
+
- **ReasoningBank**: Pattern storage with file persistence
|
|
338
|
+
|
|
339
|
+
The learning pipeline:
|
|
340
|
+
1. **RETRIEVE** — Fetch relevant patterns via HNSW/DiskANN vector search
|
|
341
|
+
2. **JUDGE** — Evaluate with verdicts (success/failure) from post-task hooks
|
|
342
|
+
3. **DISTILL** — Extract key learnings, store as patterns with embeddings
|
|
343
|
+
4. **CONSOLIDATE** — Persist patterns to disk across sessions`;
|
|
329
344
|
}
|
|
330
345
|
function envVars() {
|
|
331
346
|
return `## Environment Variables
|
|
@@ -338,6 +353,49 @@ CLAUDE_FLOW_MEMORY_BACKEND=hybrid
|
|
|
338
353
|
CLAUDE_FLOW_MEMORY_PATH=./data/memory
|
|
339
354
|
\`\`\``;
|
|
340
355
|
}
|
|
356
|
+
function mcpToolDiscovery() {
|
|
357
|
+
return `## Key MCP Tools (314 available — use ToolSearch to discover)
|
|
358
|
+
|
|
359
|
+
### Most Used Tools
|
|
360
|
+
|
|
361
|
+
| Category | Tools | What They Do |
|
|
362
|
+
|----------|-------|-------------|
|
|
363
|
+
| **Memory** | \`memory_store\`, \`memory_search\`, \`memory_search_unified\` | Store/search with ONNX vector embeddings |
|
|
364
|
+
| **Claude Bridge** | \`memory_import_claude\`, \`memory_bridge_status\` | Import Claude memories into AgentDB |
|
|
365
|
+
| **Swarm** | \`swarm_init\`, \`swarm_status\`, \`swarm_health\` | Multi-agent coordination |
|
|
366
|
+
| **Agents** | \`agent_spawn\`, \`agent_list\`, \`agent_status\` | Agent lifecycle |
|
|
367
|
+
| **Hive-Mind** | \`hive-mind_init\`, \`hive-mind_spawn\`, \`hive-mind_consensus\` | Byzantine/Raft consensus |
|
|
368
|
+
| **Hooks** | \`hooks_route\`, \`hooks_session-start\`, \`hooks_post-task\` | Task routing + learning |
|
|
369
|
+
| **Workers** | \`hooks_worker-list\`, \`hooks_worker-dispatch\` | 12 background workers |
|
|
370
|
+
| **Security** | \`aidefence_scan\`, \`aidefence_is_safe\` | Prompt injection detection |
|
|
371
|
+
| **Intelligence** | \`hooks_intelligence\`, \`neural_status\` | Pattern learning + SONA |
|
|
372
|
+
|
|
373
|
+
### Swarm Capabilities
|
|
374
|
+
|
|
375
|
+
- **Topologies**: hierarchical (anti-drift), mesh, ring, star, adaptive
|
|
376
|
+
- **Consensus**: Raft (leader-based), Byzantine (PBFT), Gossip (eventual)
|
|
377
|
+
- **Hive-Mind**: Queen-led coordination with spawn, broadcast, consensus voting, shared memory
|
|
378
|
+
- **12 Background Workers**: audit, optimize, testgaps, map, deepdive, document, refactor, benchmark, ultralearn, consolidate, predict, preload
|
|
379
|
+
|
|
380
|
+
### Memory Capabilities
|
|
381
|
+
|
|
382
|
+
- **ONNX Embeddings**: all-MiniLM-L6-v2, 384 dimensions — real neural vectors
|
|
383
|
+
- **DiskANN**: SSD-friendly vector search (8,000x faster insert than HNSW, perfect recall at 1K)
|
|
384
|
+
- **sql.js**: Cross-platform SQLite (WASM, no native compilation)
|
|
385
|
+
- **Claude Code Bridge**: Auto-imports MEMORY.md files into AgentDB on session start
|
|
386
|
+
- **Unified Search**: \`memory_search_unified\` searches Claude memories + AgentDB + patterns
|
|
387
|
+
- **SONA Learning**: Trajectory recording → pattern extraction → file persistence
|
|
388
|
+
|
|
389
|
+
### How to Discover Tools
|
|
390
|
+
|
|
391
|
+
Use ToolSearch to find specific tools:
|
|
392
|
+
\`\`\`
|
|
393
|
+
ToolSearch("memory search") → memory_store, memory_search, memory_search_unified
|
|
394
|
+
ToolSearch("swarm") → swarm_init, swarm_status, swarm_health, swarm_shutdown
|
|
395
|
+
ToolSearch("hive consensus") → hive-mind_consensus, hive-mind_status
|
|
396
|
+
ToolSearch("+aidefence") → aidefence_scan, aidefence_is_safe, aidefence_has_pii
|
|
397
|
+
\`\`\``;
|
|
398
|
+
}
|
|
341
399
|
function setupAndBoundary() {
|
|
342
400
|
return `## Quick Setup
|
|
343
401
|
|
|
@@ -347,16 +405,17 @@ npx @claude-flow/cli@latest daemon start
|
|
|
347
405
|
npx @claude-flow/cli@latest doctor --fix
|
|
348
406
|
\`\`\`
|
|
349
407
|
|
|
350
|
-
## Claude Code vs
|
|
408
|
+
## Claude Code vs MCP Tools
|
|
351
409
|
|
|
352
|
-
- Claude Code
|
|
353
|
-
-
|
|
354
|
-
-
|
|
410
|
+
- **Claude Code Task tool** handles execution: agents, file ops, code generation, git
|
|
411
|
+
- **MCP tools** (via ToolSearch) handle coordination: swarm, memory, hooks, routing, hive-mind
|
|
412
|
+
- **CLI commands** (via Bash) are the same tools with terminal output
|
|
413
|
+
- Use \`ToolSearch("keyword")\` to discover available MCP tools
|
|
355
414
|
|
|
356
415
|
## Support
|
|
357
416
|
|
|
358
|
-
- Documentation: https://github.com/ruvnet/
|
|
359
|
-
- Issues: https://github.com/ruvnet/
|
|
417
|
+
- Documentation: https://github.com/ruvnet/ruflo
|
|
418
|
+
- Issues: https://github.com/ruvnet/ruflo/issues`;
|
|
360
419
|
}
|
|
361
420
|
// --- Template Composers ---
|
|
362
421
|
/**
|
|
@@ -388,6 +447,7 @@ const TEMPLATE_SECTIONS = {
|
|
|
388
447
|
(_opts) => cliCommandsTable(),
|
|
389
448
|
(_opts) => agentTypes(),
|
|
390
449
|
(_opts) => memoryCommands(),
|
|
450
|
+
(_opts) => mcpToolDiscovery(),
|
|
391
451
|
(_opts) => setupAndBoundary(),
|
|
392
452
|
],
|
|
393
453
|
full: [
|
|
@@ -406,6 +466,7 @@ const TEMPLATE_SECTIONS = {
|
|
|
406
466
|
(_opts) => hooksSystem(),
|
|
407
467
|
(_opts) => learningProtocol(),
|
|
408
468
|
(_opts) => memoryCommands(),
|
|
469
|
+
(_opts) => mcpToolDiscovery(),
|
|
409
470
|
(_opts) => intelligenceSystem(),
|
|
410
471
|
(_opts) => envVars(),
|
|
411
472
|
(_opts) => setupAndBoundary(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudemd-generator.js","sourceRoot":"","sources":["../../../src/init/claudemd-generator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,iEAAiE;AAEjE,SAAS,eAAe;IACtB,OAAO;;;;;;;;;mDAS0C,CAAC;AACpD,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO;;;;;;;;qCAQ4B,CAAC;AACtC,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAoB;IAC/C,OAAO;;;;;;;;;;;kBAWS,OAAO,CAAC,OAAO,CAAC,QAAQ;oBACtB,OAAO,CAAC,OAAO,CAAC,SAAS;gBAC7B,OAAO,CAAC,OAAO,CAAC,aAAa;cAC/B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU;gBACjD,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO;;;;;;;gDAOuC,CAAC;AACjD,CAAC;AAED,SAAS,kBAAkB;IACzB,OAAO;;;;;;;;;;;;;;;;4DAgBmD,CAAC;AAC7D,CAAC;AAED,SAAS,eAAe;IACtB,OAAO;;;;;;;;;;;OAWF,CAAC;AACR,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gHA+BuG,CAAC;AACjH,CAAC;AAED,SAAS,cAAc;IACrB,OAAO;;;;;;kEAMyD,CAAC;AACnE,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO;;;;;;;;;;;;;;;;;;;;;;;OAuBF,CAAC;AACR,CAAC;AAED,SAAS,UAAU;IACjB,OAAO
|
|
1
|
+
{"version":3,"file":"claudemd-generator.js","sourceRoot":"","sources":["../../../src/init/claudemd-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiskANN Vector Search Backend
|
|
3
|
+
*
|
|
4
|
+
* SSD-friendly approximate nearest neighbor search using Vamana graph.
|
|
5
|
+
* Falls back gracefully to HNSW (@ruvector/router VectorDb) or
|
|
6
|
+
* pure-JS cosine similarity when DiskANN is unavailable.
|
|
7
|
+
*
|
|
8
|
+
* @module v3/cli/ruvector/diskann-backend
|
|
9
|
+
*/
|
|
10
|
+
export interface DiskAnnConfig {
|
|
11
|
+
dim: number;
|
|
12
|
+
maxDegree?: number;
|
|
13
|
+
buildBeam?: number;
|
|
14
|
+
searchBeam?: number;
|
|
15
|
+
alpha?: number;
|
|
16
|
+
pqSubspaces?: number;
|
|
17
|
+
storagePath?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface SearchResult {
|
|
20
|
+
id: string;
|
|
21
|
+
distance: number;
|
|
22
|
+
score: number;
|
|
23
|
+
}
|
|
24
|
+
export type VectorBackend = 'diskann' | 'hnsw' | 'cosine-js';
|
|
25
|
+
/**
|
|
26
|
+
* Check if @ruvector/diskann is available
|
|
27
|
+
*/
|
|
28
|
+
export declare function isDiskAnnAvailable(): Promise<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* Create or get a DiskANN index instance
|
|
31
|
+
*/
|
|
32
|
+
export declare function getDiskAnnIndex(config: DiskAnnConfig): Promise<{
|
|
33
|
+
index: any;
|
|
34
|
+
backend: VectorBackend;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Get the active backend name
|
|
38
|
+
*/
|
|
39
|
+
export declare function getActiveBackend(): VectorBackend;
|
|
40
|
+
/**
|
|
41
|
+
* Reset the index (for testing)
|
|
42
|
+
*/
|
|
43
|
+
export declare function resetIndex(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Insert a vector into the active backend
|
|
46
|
+
*/
|
|
47
|
+
export declare function insertVector(id: string, vector: Float32Array, config?: DiskAnnConfig): Promise<{
|
|
48
|
+
backend: VectorBackend;
|
|
49
|
+
}>;
|
|
50
|
+
/**
|
|
51
|
+
* Build the index (required for DiskANN before search)
|
|
52
|
+
*/
|
|
53
|
+
export declare function buildIndex(config?: DiskAnnConfig): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Search for k nearest neighbors
|
|
56
|
+
*/
|
|
57
|
+
export declare function searchVectors(query: Float32Array, k: number, config?: DiskAnnConfig): Promise<SearchResult[]>;
|
|
58
|
+
export interface BenchmarkResult {
|
|
59
|
+
backend: VectorBackend;
|
|
60
|
+
dim: number;
|
|
61
|
+
vectorCount: number;
|
|
62
|
+
insertTimeMs: number;
|
|
63
|
+
buildTimeMs: number;
|
|
64
|
+
searchTimeMs: number;
|
|
65
|
+
searchesPerSecond: number;
|
|
66
|
+
recall: number;
|
|
67
|
+
memoryMB: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run a benchmark comparing available backends
|
|
71
|
+
*/
|
|
72
|
+
export declare function benchmark(opts?: {
|
|
73
|
+
dim?: number;
|
|
74
|
+
vectorCount?: number;
|
|
75
|
+
k?: number;
|
|
76
|
+
queries?: number;
|
|
77
|
+
}): Promise<BenchmarkResult[]>;
|
|
78
|
+
//# sourceMappingURL=diskann-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diskann-backend.d.ts","sourceRoot":"","sources":["../../../src/ruvector/diskann-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAQ7D;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAY3D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC;IACpE,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,aAAa,CAAC;CACxB,CAAC,CAsDD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAIjC;AAID;;GAEG;AACH,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,YAAY,EACpB,MAAM,GAAE,aAA4B,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,aAAa,CAAA;CAAE,CAAC,CAYrC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,GAAE,aAA4B,GAAG,OAAO,CAAC,IAAI,CAAC,CAMpF;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,YAAY,EACnB,CAAC,EAAE,MAAM,EACT,MAAM,GAAE,aAA4B,GACnC,OAAO,CAAC,YAAY,EAAE,CAAC,CAuBzB;AAkCD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,aAAa,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,IAAI,GAAE;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA6HlC"}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiskANN Vector Search Backend
|
|
3
|
+
*
|
|
4
|
+
* SSD-friendly approximate nearest neighbor search using Vamana graph.
|
|
5
|
+
* Falls back gracefully to HNSW (@ruvector/router VectorDb) or
|
|
6
|
+
* pure-JS cosine similarity when DiskANN is unavailable.
|
|
7
|
+
*
|
|
8
|
+
* @module v3/cli/ruvector/diskann-backend
|
|
9
|
+
*/
|
|
10
|
+
// ===== Lazy loading =====
|
|
11
|
+
let diskannInstance = null;
|
|
12
|
+
let diskannAvailable = null;
|
|
13
|
+
let activeBackend = 'cosine-js';
|
|
14
|
+
/**
|
|
15
|
+
* Check if @ruvector/diskann is available
|
|
16
|
+
*/
|
|
17
|
+
export async function isDiskAnnAvailable() {
|
|
18
|
+
if (diskannAvailable !== null)
|
|
19
|
+
return diskannAvailable;
|
|
20
|
+
try {
|
|
21
|
+
const { createRequire } = await import('module');
|
|
22
|
+
const require2 = createRequire(import.meta.url);
|
|
23
|
+
const mod = require2('@ruvector/diskann');
|
|
24
|
+
diskannAvailable = typeof mod.DiskAnn === 'function';
|
|
25
|
+
return diskannAvailable;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
diskannAvailable = false;
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create or get a DiskANN index instance
|
|
34
|
+
*/
|
|
35
|
+
export async function getDiskAnnIndex(config) {
|
|
36
|
+
if (diskannInstance)
|
|
37
|
+
return { index: diskannInstance, backend: activeBackend };
|
|
38
|
+
// Try DiskANN first
|
|
39
|
+
if (await isDiskAnnAvailable()) {
|
|
40
|
+
try {
|
|
41
|
+
const { createRequire } = await import('module');
|
|
42
|
+
const require2 = createRequire(import.meta.url);
|
|
43
|
+
const { DiskAnn } = require2('@ruvector/diskann');
|
|
44
|
+
const index = new DiskAnn({
|
|
45
|
+
dim: config.dim,
|
|
46
|
+
maxDegree: config.maxDegree ?? 64,
|
|
47
|
+
buildBeam: config.buildBeam ?? 128,
|
|
48
|
+
searchBeam: config.searchBeam ?? 64,
|
|
49
|
+
alpha: config.alpha ?? 1.2,
|
|
50
|
+
pqSubspaces: config.pqSubspaces ?? 0,
|
|
51
|
+
storagePath: config.storagePath,
|
|
52
|
+
});
|
|
53
|
+
diskannInstance = index;
|
|
54
|
+
activeBackend = 'diskann';
|
|
55
|
+
return { index, backend: 'diskann' };
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// Fall through
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Try HNSW (@ruvector/router VectorDb) as fallback
|
|
62
|
+
try {
|
|
63
|
+
const { createRequire } = await import('module');
|
|
64
|
+
const require2 = createRequire(import.meta.url);
|
|
65
|
+
const router = require2('@ruvector/router');
|
|
66
|
+
if (router.VectorDb && router.DistanceMetric) {
|
|
67
|
+
const index = new router.VectorDb({
|
|
68
|
+
dimensions: config.dim,
|
|
69
|
+
distanceMetric: router.DistanceMetric.Cosine,
|
|
70
|
+
hnswM: 16,
|
|
71
|
+
hnswEfConstruction: 200,
|
|
72
|
+
hnswEfSearch: 100,
|
|
73
|
+
});
|
|
74
|
+
diskannInstance = index;
|
|
75
|
+
activeBackend = 'hnsw';
|
|
76
|
+
return { index, backend: 'hnsw' };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// Fall through
|
|
81
|
+
}
|
|
82
|
+
// Pure JS fallback
|
|
83
|
+
const jsIndex = createJsFallbackIndex(config.dim);
|
|
84
|
+
diskannInstance = jsIndex;
|
|
85
|
+
activeBackend = 'cosine-js';
|
|
86
|
+
return { index: jsIndex, backend: 'cosine-js' };
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get the active backend name
|
|
90
|
+
*/
|
|
91
|
+
export function getActiveBackend() {
|
|
92
|
+
return activeBackend;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Reset the index (for testing)
|
|
96
|
+
*/
|
|
97
|
+
export function resetIndex() {
|
|
98
|
+
diskannInstance = null;
|
|
99
|
+
diskannAvailable = null;
|
|
100
|
+
activeBackend = 'cosine-js';
|
|
101
|
+
}
|
|
102
|
+
// ===== Unified search interface =====
|
|
103
|
+
/**
|
|
104
|
+
* Insert a vector into the active backend
|
|
105
|
+
*/
|
|
106
|
+
export async function insertVector(id, vector, config = { dim: 384 }) {
|
|
107
|
+
const { index, backend } = await getDiskAnnIndex(config);
|
|
108
|
+
if (backend === 'diskann') {
|
|
109
|
+
index.insert(id, vector);
|
|
110
|
+
}
|
|
111
|
+
else if (backend === 'hnsw') {
|
|
112
|
+
index.insert(id, vector);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
index.insert(id, vector);
|
|
116
|
+
}
|
|
117
|
+
return { backend };
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Build the index (required for DiskANN before search)
|
|
121
|
+
*/
|
|
122
|
+
export async function buildIndex(config = { dim: 384 }) {
|
|
123
|
+
const { index, backend } = await getDiskAnnIndex(config);
|
|
124
|
+
if (backend === 'diskann' && typeof index.build === 'function') {
|
|
125
|
+
index.build();
|
|
126
|
+
}
|
|
127
|
+
// HNSW and JS fallback don't need explicit build
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Search for k nearest neighbors
|
|
131
|
+
*/
|
|
132
|
+
export async function searchVectors(query, k, config = { dim: 384 }) {
|
|
133
|
+
const { index, backend } = await getDiskAnnIndex(config);
|
|
134
|
+
if (backend === 'diskann') {
|
|
135
|
+
const results = index.search(query, k);
|
|
136
|
+
return results.map((r) => ({
|
|
137
|
+
id: r.id,
|
|
138
|
+
distance: r.distance,
|
|
139
|
+
score: 1 / (1 + r.distance), // Convert L2 distance to similarity
|
|
140
|
+
}));
|
|
141
|
+
}
|
|
142
|
+
if (backend === 'hnsw') {
|
|
143
|
+
const results = index.search(query, k);
|
|
144
|
+
return results.map((r) => ({
|
|
145
|
+
id: r.id,
|
|
146
|
+
distance: r.score, // VectorDb returns distance as 'score'
|
|
147
|
+
score: 1 / (1 + r.score),
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
// JS fallback
|
|
151
|
+
return index.search(query, k);
|
|
152
|
+
}
|
|
153
|
+
// ===== Pure JS fallback =====
|
|
154
|
+
function createJsFallbackIndex(dim) {
|
|
155
|
+
const vectors = new Map();
|
|
156
|
+
return {
|
|
157
|
+
insert(id, vector) {
|
|
158
|
+
vectors.set(id, new Float32Array(vector));
|
|
159
|
+
},
|
|
160
|
+
search(query, k) {
|
|
161
|
+
const results = [];
|
|
162
|
+
for (const [id, vec] of vectors) {
|
|
163
|
+
let dot = 0, normQ = 0, normV = 0;
|
|
164
|
+
for (let i = 0; i < dim; i++) {
|
|
165
|
+
dot += query[i] * vec[i];
|
|
166
|
+
normQ += query[i] * query[i];
|
|
167
|
+
normV += vec[i] * vec[i];
|
|
168
|
+
}
|
|
169
|
+
const cosine = dot / (Math.sqrt(normQ) * Math.sqrt(normV) || 1);
|
|
170
|
+
const distance = 1 - cosine;
|
|
171
|
+
results.push({ id, distance, score: cosine });
|
|
172
|
+
}
|
|
173
|
+
return results.sort((a, b) => a.distance - b.distance).slice(0, k);
|
|
174
|
+
},
|
|
175
|
+
count() { return vectors.size; },
|
|
176
|
+
delete(id) { return vectors.delete(id); },
|
|
177
|
+
build() { },
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Run a benchmark comparing available backends
|
|
182
|
+
*/
|
|
183
|
+
export async function benchmark(opts = {}) {
|
|
184
|
+
const dim = opts.dim ?? 384;
|
|
185
|
+
const n = opts.vectorCount ?? 1000;
|
|
186
|
+
const k = opts.k ?? 10;
|
|
187
|
+
const queryCount = opts.queries ?? 100;
|
|
188
|
+
const results = [];
|
|
189
|
+
// Generate random vectors
|
|
190
|
+
const vectors = [];
|
|
191
|
+
for (let i = 0; i < n; i++) {
|
|
192
|
+
const v = new Float32Array(dim);
|
|
193
|
+
for (let j = 0; j < dim; j++)
|
|
194
|
+
v[j] = Math.random() * 2 - 1;
|
|
195
|
+
// Normalize
|
|
196
|
+
let norm = 0;
|
|
197
|
+
for (let j = 0; j < dim; j++)
|
|
198
|
+
norm += v[j] * v[j];
|
|
199
|
+
norm = Math.sqrt(norm);
|
|
200
|
+
for (let j = 0; j < dim; j++)
|
|
201
|
+
v[j] /= norm;
|
|
202
|
+
vectors.push([`vec-${i}`, v]);
|
|
203
|
+
}
|
|
204
|
+
// Generate query vectors
|
|
205
|
+
const queries = [];
|
|
206
|
+
for (let i = 0; i < queryCount; i++) {
|
|
207
|
+
const q = new Float32Array(dim);
|
|
208
|
+
for (let j = 0; j < dim; j++)
|
|
209
|
+
q[j] = Math.random() * 2 - 1;
|
|
210
|
+
let norm = 0;
|
|
211
|
+
for (let j = 0; j < dim; j++)
|
|
212
|
+
norm += q[j] * q[j];
|
|
213
|
+
norm = Math.sqrt(norm);
|
|
214
|
+
for (let j = 0; j < dim; j++)
|
|
215
|
+
q[j] /= norm;
|
|
216
|
+
queries.push(q);
|
|
217
|
+
}
|
|
218
|
+
// Brute force ground truth
|
|
219
|
+
function bruteForceSearch(query) {
|
|
220
|
+
const scores = [];
|
|
221
|
+
for (const [id, vec] of vectors) {
|
|
222
|
+
let dist = 0;
|
|
223
|
+
for (let j = 0; j < dim; j++) {
|
|
224
|
+
const d = query[j] - vec[j];
|
|
225
|
+
dist += d * d;
|
|
226
|
+
}
|
|
227
|
+
scores.push({ id, dist });
|
|
228
|
+
}
|
|
229
|
+
scores.sort((a, b) => a.dist - b.dist);
|
|
230
|
+
return scores.slice(0, k).map(s => s.id);
|
|
231
|
+
}
|
|
232
|
+
const groundTruth = queries.map(q => bruteForceSearch(q));
|
|
233
|
+
// Test each available backend
|
|
234
|
+
for (const backendName of ['diskann', 'hnsw', 'cosine-js']) {
|
|
235
|
+
resetIndex();
|
|
236
|
+
try {
|
|
237
|
+
let index;
|
|
238
|
+
const memBefore = process.memoryUsage().heapUsed;
|
|
239
|
+
if (backendName === 'diskann') {
|
|
240
|
+
if (!(await isDiskAnnAvailable()))
|
|
241
|
+
continue;
|
|
242
|
+
const { createRequire } = await import('module');
|
|
243
|
+
const require2 = createRequire(import.meta.url);
|
|
244
|
+
const { DiskAnn } = require2('@ruvector/diskann');
|
|
245
|
+
index = new DiskAnn({ dim, maxDegree: 64, buildBeam: 128, searchBeam: 64 });
|
|
246
|
+
}
|
|
247
|
+
else if (backendName === 'hnsw') {
|
|
248
|
+
try {
|
|
249
|
+
const { createRequire } = await import('module');
|
|
250
|
+
const require2 = createRequire(import.meta.url);
|
|
251
|
+
const router = require2('@ruvector/router');
|
|
252
|
+
if (!router.VectorDb)
|
|
253
|
+
continue;
|
|
254
|
+
index = new router.VectorDb({ dimensions: dim, distanceMetric: router.DistanceMetric.Cosine });
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
index = createJsFallbackIndex(dim);
|
|
262
|
+
}
|
|
263
|
+
// Insert
|
|
264
|
+
const insertStart = performance.now();
|
|
265
|
+
for (const [id, vec] of vectors) {
|
|
266
|
+
index.insert(id, vec);
|
|
267
|
+
}
|
|
268
|
+
const insertTime = performance.now() - insertStart;
|
|
269
|
+
// Build
|
|
270
|
+
const buildStart = performance.now();
|
|
271
|
+
if (typeof index.build === 'function')
|
|
272
|
+
index.build();
|
|
273
|
+
const buildTime = performance.now() - buildStart;
|
|
274
|
+
// Search
|
|
275
|
+
const searchStart = performance.now();
|
|
276
|
+
const searchResults = [];
|
|
277
|
+
for (const q of queries) {
|
|
278
|
+
const r = index.search(q, k);
|
|
279
|
+
searchResults.push(r.map((x) => x.id));
|
|
280
|
+
}
|
|
281
|
+
const searchTime = performance.now() - searchStart;
|
|
282
|
+
// Recall vs ground truth
|
|
283
|
+
let totalRecall = 0;
|
|
284
|
+
for (let i = 0; i < queryCount; i++) {
|
|
285
|
+
const truth = new Set(groundTruth[i]);
|
|
286
|
+
const found = searchResults[i].filter(id => truth.has(id)).length;
|
|
287
|
+
totalRecall += found / k;
|
|
288
|
+
}
|
|
289
|
+
const recall = totalRecall / queryCount;
|
|
290
|
+
const memAfter = process.memoryUsage().heapUsed;
|
|
291
|
+
results.push({
|
|
292
|
+
backend: backendName,
|
|
293
|
+
dim,
|
|
294
|
+
vectorCount: n,
|
|
295
|
+
insertTimeMs: Math.round(insertTime * 100) / 100,
|
|
296
|
+
buildTimeMs: Math.round(buildTime * 100) / 100,
|
|
297
|
+
searchTimeMs: Math.round(searchTime * 100) / 100,
|
|
298
|
+
searchesPerSecond: Math.round(queryCount / (searchTime / 1000)),
|
|
299
|
+
recall: Math.round(recall * 1000) / 1000,
|
|
300
|
+
memoryMB: Math.round((memAfter - memBefore) / 1024 / 1024 * 100) / 100,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
// Backend failed, skip
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
resetIndex();
|
|
308
|
+
return results;
|
|
309
|
+
}
|
|
310
|
+
//# sourceMappingURL=diskann-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diskann-backend.js","sourceRoot":"","sources":["../../../src/ruvector/diskann-backend.ts"],"names":[],"mappings":"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"}
|