agentdb 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/LICENSE +38 -0
- package/LICENSE-APACHE +190 -0
- package/LICENSE-MIT +21 -0
- package/README.md +953 -0
- package/bin/agentdb.js +485 -0
- package/bin/plugin-cli-wrapper.mjs +21 -0
- package/dist/cache/query-cache.d.ts +105 -0
- package/dist/cache/query-cache.d.ts.map +1 -0
- package/dist/cache/query-cache.js +224 -0
- package/dist/cache/query-cache.js.map +1 -0
- package/dist/cache/query-cache.mjs +219 -0
- package/dist/cli/cache/query-cache.d.ts +104 -0
- package/dist/cli/cache/query-cache.js +244 -0
- package/dist/cli/cli/db-commands.d.ts +48 -0
- package/dist/cli/cli/db-commands.js +613 -0
- package/dist/cli/commands.d.ts +7 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +113 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/commands.mjs +104 -0
- package/dist/cli/core/backend-interface.d.ts +70 -0
- package/dist/cli/core/backend-interface.js +15 -0
- package/dist/cli/core/native-backend.d.ts +140 -0
- package/dist/cli/core/native-backend.js +432 -0
- package/dist/cli/core/vector-db.d.ts +126 -0
- package/dist/cli/core/vector-db.js +338 -0
- package/dist/cli/core/wasm-backend.d.ts +95 -0
- package/dist/cli/core/wasm-backend.js +418 -0
- package/dist/cli/db-commands.d.ts +49 -0
- package/dist/cli/db-commands.d.ts.map +1 -0
- package/dist/cli/db-commands.js +533 -0
- package/dist/cli/db-commands.js.map +1 -0
- package/dist/cli/db-commands.mjs +522 -0
- package/dist/cli/generator.d.ts +11 -0
- package/dist/cli/generator.d.ts.map +1 -0
- package/dist/cli/generator.js +567 -0
- package/dist/cli/generator.js.map +1 -0
- package/dist/cli/generator.mjs +527 -0
- package/dist/cli/help.d.ts +18 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +676 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/help.mjs +667 -0
- package/dist/cli/index/hnsw.d.ts +164 -0
- package/dist/cli/index/hnsw.js +558 -0
- package/dist/cli/plugin-cli.d.ts +7 -0
- package/dist/cli/plugin-cli.d.ts.map +1 -0
- package/dist/cli/plugin-cli.js +295 -0
- package/dist/cli/plugin-cli.js.map +1 -0
- package/dist/cli/plugin-cli.mjs +289 -0
- package/dist/cli/quantization/product-quantization.d.ts +108 -0
- package/dist/cli/quantization/product-quantization.js +350 -0
- package/dist/cli/query/query-builder.d.ts +322 -0
- package/dist/cli/query/query-builder.js +600 -0
- package/dist/cli/templates.d.ts +14 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +182 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/templates.mjs +176 -0
- package/dist/cli/types/index.d.ts +116 -0
- package/dist/cli/types/index.js +5 -0
- package/dist/cli/types.d.ts +91 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +6 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/types.mjs +4 -0
- package/dist/cli/wizard/index.d.ts +6 -0
- package/dist/cli/wizard/index.d.ts.map +1 -0
- package/dist/cli/wizard/index.js +138 -0
- package/dist/cli/wizard/index.js.map +1 -0
- package/dist/cli/wizard/index.mjs +131 -0
- package/dist/cli/wizard/prompts.d.ts +11 -0
- package/dist/cli/wizard/prompts.d.ts.map +1 -0
- package/dist/cli/wizard/prompts.js +482 -0
- package/dist/cli/wizard/prompts.js.map +1 -0
- package/dist/cli/wizard/prompts.mjs +470 -0
- package/dist/cli/wizard/validator.d.ts +13 -0
- package/dist/cli/wizard/validator.d.ts.map +1 -0
- package/dist/cli/wizard/validator.js +234 -0
- package/dist/cli/wizard/validator.js.map +1 -0
- package/dist/cli/wizard/validator.mjs +224 -0
- package/dist/core/backend-interface.d.ts +71 -0
- package/dist/core/backend-interface.d.ts.map +1 -0
- package/dist/core/backend-interface.js +16 -0
- package/dist/core/backend-interface.js.map +1 -0
- package/dist/core/backend-interface.mjs +12 -0
- package/dist/core/native-backend.d.ts +141 -0
- package/dist/core/native-backend.d.ts.map +1 -0
- package/dist/core/native-backend.js +457 -0
- package/dist/core/native-backend.js.map +1 -0
- package/dist/core/native-backend.mjs +449 -0
- package/dist/core/vector-db.d.ts +127 -0
- package/dist/core/vector-db.d.ts.map +1 -0
- package/dist/core/vector-db.js +266 -0
- package/dist/core/vector-db.js.map +1 -0
- package/dist/core/vector-db.mjs +261 -0
- package/dist/core/wasm-backend.d.ts +96 -0
- package/dist/core/wasm-backend.d.ts.map +1 -0
- package/dist/core/wasm-backend.js +393 -0
- package/dist/core/wasm-backend.js.map +1 -0
- package/dist/core/wasm-backend.mjs +385 -0
- package/dist/index/hnsw-optimized.d.ts +75 -0
- package/dist/index/hnsw-optimized.d.ts.map +1 -0
- package/dist/index/hnsw-optimized.js +412 -0
- package/dist/index/hnsw-optimized.js.map +1 -0
- package/dist/index/hnsw-optimized.mjs +407 -0
- package/dist/index/hnsw.d.ts +165 -0
- package/dist/index/hnsw.d.ts.map +1 -0
- package/dist/index/hnsw.js +521 -0
- package/dist/index/hnsw.js.map +1 -0
- package/dist/index/hnsw.mjs +516 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +63 -0
- package/dist/mcp-server.d.ts +27 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +789 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp-server.mjs +784 -0
- package/dist/plugins/base-plugin.d.ts +114 -0
- package/dist/plugins/base-plugin.d.ts.map +1 -0
- package/dist/plugins/base-plugin.js +313 -0
- package/dist/plugins/base-plugin.js.map +1 -0
- package/dist/plugins/base-plugin.mjs +275 -0
- package/dist/plugins/implementations/active-learning.d.ts +135 -0
- package/dist/plugins/implementations/active-learning.d.ts.map +1 -0
- package/dist/plugins/implementations/active-learning.js +372 -0
- package/dist/plugins/implementations/active-learning.js.map +1 -0
- package/dist/plugins/implementations/active-learning.mjs +367 -0
- package/dist/plugins/implementations/actor-critic.d.ts +64 -0
- package/dist/plugins/implementations/actor-critic.d.ts.map +1 -0
- package/dist/plugins/implementations/actor-critic.js +363 -0
- package/dist/plugins/implementations/actor-critic.js.map +1 -0
- package/dist/plugins/implementations/actor-critic.mjs +358 -0
- package/dist/plugins/implementations/adversarial-training.d.ts +133 -0
- package/dist/plugins/implementations/adversarial-training.d.ts.map +1 -0
- package/dist/plugins/implementations/adversarial-training.js +409 -0
- package/dist/plugins/implementations/adversarial-training.js.map +1 -0
- package/dist/plugins/implementations/adversarial-training.mjs +404 -0
- package/dist/plugins/implementations/curriculum-learning.d.ts +132 -0
- package/dist/plugins/implementations/curriculum-learning.d.ts.map +1 -0
- package/dist/plugins/implementations/curriculum-learning.js +354 -0
- package/dist/plugins/implementations/curriculum-learning.js.map +1 -0
- package/dist/plugins/implementations/curriculum-learning.mjs +349 -0
- package/dist/plugins/implementations/decision-transformer.d.ts +77 -0
- package/dist/plugins/implementations/decision-transformer.d.ts.map +1 -0
- package/dist/plugins/implementations/decision-transformer.js +422 -0
- package/dist/plugins/implementations/decision-transformer.js.map +1 -0
- package/dist/plugins/implementations/decision-transformer.mjs +417 -0
- package/dist/plugins/implementations/federated-learning.d.ts +126 -0
- package/dist/plugins/implementations/federated-learning.d.ts.map +1 -0
- package/dist/plugins/implementations/federated-learning.js +436 -0
- package/dist/plugins/implementations/federated-learning.js.map +1 -0
- package/dist/plugins/implementations/federated-learning.mjs +431 -0
- package/dist/plugins/implementations/index.d.ts +30 -0
- package/dist/plugins/implementations/index.d.ts.map +1 -0
- package/dist/plugins/implementations/index.js +45 -0
- package/dist/plugins/implementations/index.js.map +1 -0
- package/dist/plugins/implementations/index.mjs +31 -0
- package/dist/plugins/implementations/multi-task-learning.d.ts +115 -0
- package/dist/plugins/implementations/multi-task-learning.d.ts.map +1 -0
- package/dist/plugins/implementations/multi-task-learning.js +369 -0
- package/dist/plugins/implementations/multi-task-learning.js.map +1 -0
- package/dist/plugins/implementations/multi-task-learning.mjs +364 -0
- package/dist/plugins/implementations/neural-architecture-search.d.ts +148 -0
- package/dist/plugins/implementations/neural-architecture-search.d.ts.map +1 -0
- package/dist/plugins/implementations/neural-architecture-search.js +379 -0
- package/dist/plugins/implementations/neural-architecture-search.js.map +1 -0
- package/dist/plugins/implementations/neural-architecture-search.mjs +374 -0
- package/dist/plugins/implementations/q-learning.d.ts +98 -0
- package/dist/plugins/implementations/q-learning.d.ts.map +1 -0
- package/dist/plugins/implementations/q-learning.js +435 -0
- package/dist/plugins/implementations/q-learning.js.map +1 -0
- package/dist/plugins/implementations/q-learning.mjs +430 -0
- package/dist/plugins/implementations/sarsa.d.ts +103 -0
- package/dist/plugins/implementations/sarsa.d.ts.map +1 -0
- package/dist/plugins/implementations/sarsa.js +347 -0
- package/dist/plugins/implementations/sarsa.js.map +1 -0
- package/dist/plugins/implementations/sarsa.mjs +342 -0
- package/dist/plugins/index.d.ts +107 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +179 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/index.mjs +168 -0
- package/dist/plugins/interface.d.ts +439 -0
- package/dist/plugins/interface.d.ts.map +1 -0
- package/dist/plugins/interface.js +12 -0
- package/dist/plugins/interface.js.map +1 -0
- package/dist/plugins/interface.mjs +10 -0
- package/dist/plugins/learning-plugin.interface.d.ts +257 -0
- package/dist/plugins/learning-plugin.interface.d.ts.map +1 -0
- package/dist/plugins/learning-plugin.interface.js +7 -0
- package/dist/plugins/learning-plugin.interface.js.map +1 -0
- package/dist/plugins/learning-plugin.interface.mjs +5 -0
- package/dist/plugins/plugin-exports.d.ts +71 -0
- package/dist/plugins/plugin-exports.d.ts.map +1 -0
- package/dist/plugins/plugin-exports.js +78 -0
- package/dist/plugins/plugin-exports.js.map +1 -0
- package/dist/plugins/plugin-exports.mjs +69 -0
- package/dist/plugins/registry.d.ts +206 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +365 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/registry.mjs +356 -0
- package/dist/plugins/validator.d.ts +63 -0
- package/dist/plugins/validator.d.ts.map +1 -0
- package/dist/plugins/validator.js +464 -0
- package/dist/plugins/validator.js.map +1 -0
- package/dist/plugins/validator.mjs +458 -0
- package/dist/quantization/binary-quantization.d.ts +104 -0
- package/dist/quantization/binary-quantization.d.ts.map +1 -0
- package/dist/quantization/binary-quantization.js +246 -0
- package/dist/quantization/binary-quantization.js.map +1 -0
- package/dist/quantization/binary-quantization.mjs +240 -0
- package/dist/quantization/optimized-pq.d.ts +138 -0
- package/dist/quantization/optimized-pq.d.ts.map +1 -0
- package/dist/quantization/optimized-pq.js +320 -0
- package/dist/quantization/optimized-pq.js.map +1 -0
- package/dist/quantization/optimized-pq.mjs +313 -0
- package/dist/quantization/product-quantization.d.ts +109 -0
- package/dist/quantization/product-quantization.d.ts.map +1 -0
- package/dist/quantization/product-quantization.js +287 -0
- package/dist/quantization/product-quantization.js.map +1 -0
- package/dist/quantization/product-quantization.mjs +282 -0
- package/dist/quantization/scalar-quantization.d.ts +100 -0
- package/dist/quantization/scalar-quantization.d.ts.map +1 -0
- package/dist/quantization/scalar-quantization.js +324 -0
- package/dist/quantization/scalar-quantization.js.map +1 -0
- package/dist/quantization/scalar-quantization.mjs +319 -0
- package/dist/query/index.d.ts +6 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +9 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/index.mjs +4 -0
- package/dist/query/query-builder.d.ts +323 -0
- package/dist/query/query-builder.d.ts.map +1 -0
- package/dist/query/query-builder.js +524 -0
- package/dist/query/query-builder.js.map +1 -0
- package/dist/query/query-builder.mjs +519 -0
- package/dist/reasoning/context-synthesizer.d.ts +57 -0
- package/dist/reasoning/context-synthesizer.d.ts.map +1 -0
- package/dist/reasoning/context-synthesizer.js +224 -0
- package/dist/reasoning/context-synthesizer.js.map +1 -0
- package/dist/reasoning/context-synthesizer.mjs +219 -0
- package/dist/reasoning/experience-curator.d.ts +66 -0
- package/dist/reasoning/experience-curator.d.ts.map +1 -0
- package/dist/reasoning/experience-curator.js +288 -0
- package/dist/reasoning/experience-curator.js.map +1 -0
- package/dist/reasoning/experience-curator.mjs +283 -0
- package/dist/reasoning/memory-optimizer.d.ts +69 -0
- package/dist/reasoning/memory-optimizer.d.ts.map +1 -0
- package/dist/reasoning/memory-optimizer.js +331 -0
- package/dist/reasoning/memory-optimizer.js.map +1 -0
- package/dist/reasoning/memory-optimizer.mjs +326 -0
- package/dist/reasoning/pattern-matcher.d.ts +59 -0
- package/dist/reasoning/pattern-matcher.d.ts.map +1 -0
- package/dist/reasoning/pattern-matcher.js +229 -0
- package/dist/reasoning/pattern-matcher.js.map +1 -0
- package/dist/reasoning/pattern-matcher.mjs +224 -0
- package/dist/reasoningbank/adapter/agentdb-adapter.d.ts +118 -0
- package/dist/reasoningbank/adapter/agentdb-adapter.d.ts.map +1 -0
- package/dist/reasoningbank/adapter/agentdb-adapter.js +477 -0
- package/dist/reasoningbank/adapter/agentdb-adapter.js.map +1 -0
- package/dist/reasoningbank/adapter/types.d.ts +113 -0
- package/dist/reasoningbank/adapter/types.d.ts.map +1 -0
- package/dist/reasoningbank/adapter/types.js +9 -0
- package/dist/reasoningbank/adapter/types.js.map +1 -0
- package/dist/reasoningbank/cli/commands.d.ts +16 -0
- package/dist/reasoningbank/cli/commands.d.ts.map +1 -0
- package/dist/reasoningbank/cli/commands.js +272 -0
- package/dist/reasoningbank/cli/commands.js.map +1 -0
- package/dist/reasoningbank/mcp/agentdb-tools.d.ts +319 -0
- package/dist/reasoningbank/mcp/agentdb-tools.d.ts.map +1 -0
- package/dist/reasoningbank/mcp/agentdb-tools.js +301 -0
- package/dist/reasoningbank/mcp/agentdb-tools.js.map +1 -0
- package/dist/reasoningbank/migration/migrate.d.ts +25 -0
- package/dist/reasoningbank/migration/migrate.d.ts.map +1 -0
- package/dist/reasoningbank/migration/migrate.js +178 -0
- package/dist/reasoningbank/migration/migrate.js.map +1 -0
- package/dist/reasoningbank/reasoning/context-synthesizer.d.ts +37 -0
- package/dist/reasoningbank/reasoning/context-synthesizer.d.ts.map +1 -0
- package/dist/reasoningbank/reasoning/context-synthesizer.js +114 -0
- package/dist/reasoningbank/reasoning/context-synthesizer.js.map +1 -0
- package/dist/reasoningbank/reasoning/experience-curator.d.ts +39 -0
- package/dist/reasoningbank/reasoning/experience-curator.d.ts.map +1 -0
- package/dist/reasoningbank/reasoning/experience-curator.js +98 -0
- package/dist/reasoningbank/reasoning/experience-curator.js.map +1 -0
- package/dist/reasoningbank/reasoning/memory-optimizer.d.ts +44 -0
- package/dist/reasoningbank/reasoning/memory-optimizer.d.ts.map +1 -0
- package/dist/reasoningbank/reasoning/memory-optimizer.js +184 -0
- package/dist/reasoningbank/reasoning/memory-optimizer.js.map +1 -0
- package/dist/reasoningbank/reasoning/pattern-matcher.d.ts +40 -0
- package/dist/reasoningbank/reasoning/pattern-matcher.d.ts.map +1 -0
- package/dist/reasoningbank/reasoning/pattern-matcher.js +87 -0
- package/dist/reasoningbank/reasoning/pattern-matcher.js.map +1 -0
- package/dist/reasoningbank/sync/quic-sync.d.ts +77 -0
- package/dist/reasoningbank/sync/quic-sync.d.ts.map +1 -0
- package/dist/reasoningbank/sync/quic-sync.js +165 -0
- package/dist/reasoningbank/sync/quic-sync.js.map +1 -0
- package/dist/sync/conflict.d.ts +78 -0
- package/dist/sync/conflict.d.ts.map +1 -0
- package/dist/sync/conflict.js +202 -0
- package/dist/sync/conflict.js.map +1 -0
- package/dist/sync/conflict.mjs +196 -0
- package/dist/sync/coordinator.d.ts +111 -0
- package/dist/sync/coordinator.d.ts.map +1 -0
- package/dist/sync/coordinator.js +256 -0
- package/dist/sync/coordinator.js.map +1 -0
- package/dist/sync/coordinator.mjs +250 -0
- package/dist/sync/delta.d.ts +81 -0
- package/dist/sync/delta.d.ts.map +1 -0
- package/dist/sync/delta.js +245 -0
- package/dist/sync/delta.js.map +1 -0
- package/dist/sync/delta.mjs +238 -0
- package/dist/sync/index.d.ts +11 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/index.js +22 -0
- package/dist/sync/index.js.map +1 -0
- package/dist/sync/index.mjs +9 -0
- package/dist/sync/quic-sync.d.ts +81 -0
- package/dist/sync/quic-sync.d.ts.map +1 -0
- package/dist/sync/quic-sync.js +329 -0
- package/dist/sync/quic-sync.js.map +1 -0
- package/dist/sync/quic-sync.mjs +323 -0
- package/dist/sync/types.d.ts +168 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/sync/types.js +8 -0
- package/dist/sync/types.js.map +1 -0
- package/dist/sync/types.mjs +6 -0
- package/dist/types/index.d.ts +117 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/index.mjs +4 -0
- package/dist/wasm-loader.d.ts +32 -0
- package/dist/wasm-loader.d.ts.map +1 -0
- package/dist/wasm-loader.js +75 -0
- package/dist/wasm-loader.js.map +1 -0
- package/dist/wasm-loader.mjs +64 -0
- package/examples/adaptive-learning.ts +284 -0
- package/examples/browser/README.md +732 -0
- package/examples/browser/adaptive-recommendations/index.html +427 -0
- package/examples/browser/collaborative-filtering/index.html +310 -0
- package/examples/browser/continual-learning/index.html +736 -0
- package/examples/browser/experience-replay/index.html +616 -0
- package/examples/browser/index.html +369 -0
- package/examples/browser/meta-learning/index.html +789 -0
- package/examples/browser/neuro-symbolic/index.html +692 -0
- package/examples/browser/pattern-learning/index.html +620 -0
- package/examples/browser/quantum-inspired/index.html +728 -0
- package/examples/browser/rag/index.html +624 -0
- package/examples/browser/swarm-intelligence/index.html +811 -0
- package/examples/browser-basic.html +170 -0
- package/examples/hnsw-example.ts +148 -0
- package/examples/node-basic.js +70 -0
- package/examples/quic-sync-example.ts +310 -0
- package/examples/quick-start.js +68 -0
- package/examples/wasm-example.ts +222 -0
- package/package.json +118 -0
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optimized HNSW Implementation with In-Memory Build Cache
|
|
3
|
+
*
|
|
4
|
+
* Key optimizations:
|
|
5
|
+
* 1. In-memory graph during build (avoid DB queries)
|
|
6
|
+
* 2. Bulk database writes (batch all edges at once)
|
|
7
|
+
* 3. Lazy persistence (write to DB only after build complete)
|
|
8
|
+
* 4. Distance calculation caching
|
|
9
|
+
* 5. Optimized neighbor selection
|
|
10
|
+
*
|
|
11
|
+
* Target: <10ms per vector build time
|
|
12
|
+
*/
|
|
13
|
+
import { DEFAULT_HNSW_CONFIG } from './hnsw.mjs';
|
|
14
|
+
/**
|
|
15
|
+
* Optimized HNSW Index with in-memory build cache
|
|
16
|
+
*/
|
|
17
|
+
export class OptimizedHNSWIndex {
|
|
18
|
+
constructor(db, config = {}) {
|
|
19
|
+
this.entryPoint = null;
|
|
20
|
+
this.maxLevel = 0;
|
|
21
|
+
this.isBuilt = false;
|
|
22
|
+
// In-memory graph cache (only during build)
|
|
23
|
+
this.nodeCache = new Map();
|
|
24
|
+
this.edgeCache = new Map();
|
|
25
|
+
this.buildMode = false;
|
|
26
|
+
this.db = db;
|
|
27
|
+
this.config = { ...DEFAULT_HNSW_CONFIG, ...config };
|
|
28
|
+
this.initializeSchema();
|
|
29
|
+
this.prepareStatements();
|
|
30
|
+
this.loadMetadata();
|
|
31
|
+
}
|
|
32
|
+
initializeSchema() {
|
|
33
|
+
this.db.exec(`
|
|
34
|
+
CREATE TABLE IF NOT EXISTS hnsw_nodes (
|
|
35
|
+
id TEXT PRIMARY KEY,
|
|
36
|
+
vector_id TEXT NOT NULL,
|
|
37
|
+
level INTEGER NOT NULL,
|
|
38
|
+
embedding BLOB NOT NULL,
|
|
39
|
+
FOREIGN KEY (vector_id) REFERENCES vectors(id) ON DELETE CASCADE
|
|
40
|
+
);
|
|
41
|
+
CREATE INDEX IF NOT EXISTS idx_hnsw_nodes_vector ON hnsw_nodes(vector_id);
|
|
42
|
+
CREATE INDEX IF NOT EXISTS idx_hnsw_nodes_level ON hnsw_nodes(level);
|
|
43
|
+
|
|
44
|
+
CREATE TABLE IF NOT EXISTS hnsw_edges (
|
|
45
|
+
from_id TEXT NOT NULL,
|
|
46
|
+
to_id TEXT NOT NULL,
|
|
47
|
+
level INTEGER NOT NULL,
|
|
48
|
+
distance REAL NOT NULL,
|
|
49
|
+
PRIMARY KEY (from_id, to_id, level),
|
|
50
|
+
FOREIGN KEY (from_id) REFERENCES hnsw_nodes(id) ON DELETE CASCADE,
|
|
51
|
+
FOREIGN KEY (to_id) REFERENCES hnsw_nodes(id) ON DELETE CASCADE
|
|
52
|
+
);
|
|
53
|
+
CREATE INDEX IF NOT EXISTS idx_hnsw_edges_from ON hnsw_edges(from_id, level);
|
|
54
|
+
|
|
55
|
+
CREATE TABLE IF NOT EXISTS hnsw_metadata (
|
|
56
|
+
key TEXT PRIMARY KEY,
|
|
57
|
+
value TEXT NOT NULL
|
|
58
|
+
);
|
|
59
|
+
`);
|
|
60
|
+
}
|
|
61
|
+
prepareStatements() {
|
|
62
|
+
this.insertNodeStmt = this.db.prepare(`
|
|
63
|
+
INSERT OR REPLACE INTO hnsw_nodes (id, vector_id, level, embedding)
|
|
64
|
+
VALUES (?, ?, ?, ?)
|
|
65
|
+
`);
|
|
66
|
+
this.insertEdgeStmt = this.db.prepare(`
|
|
67
|
+
INSERT OR REPLACE INTO hnsw_edges (from_id, to_id, level, distance)
|
|
68
|
+
VALUES (?, ?, ?, ?)
|
|
69
|
+
`);
|
|
70
|
+
this.getNodeStmt = this.db.prepare(`
|
|
71
|
+
SELECT id, vector_id, level, embedding
|
|
72
|
+
FROM hnsw_nodes
|
|
73
|
+
WHERE id = ?
|
|
74
|
+
`);
|
|
75
|
+
this.getNeighborsStmt = this.db.prepare(`
|
|
76
|
+
SELECT to_id, distance
|
|
77
|
+
FROM hnsw_edges
|
|
78
|
+
WHERE from_id = ? AND level = ?
|
|
79
|
+
ORDER BY distance ASC
|
|
80
|
+
`);
|
|
81
|
+
}
|
|
82
|
+
loadMetadata() {
|
|
83
|
+
const stmt = this.db.prepare('SELECT value FROM hnsw_metadata WHERE key = ?');
|
|
84
|
+
const entryPointRow = stmt.get('entry_point');
|
|
85
|
+
if (entryPointRow)
|
|
86
|
+
this.entryPoint = entryPointRow.value;
|
|
87
|
+
const maxLevelRow = stmt.get('max_level');
|
|
88
|
+
if (maxLevelRow)
|
|
89
|
+
this.maxLevel = parseInt(maxLevelRow.value, 10);
|
|
90
|
+
const isBuiltRow = stmt.get('is_built');
|
|
91
|
+
if (isBuiltRow)
|
|
92
|
+
this.isBuilt = isBuiltRow.value === 'true';
|
|
93
|
+
}
|
|
94
|
+
saveMetadata() {
|
|
95
|
+
const stmt = this.db.prepare('INSERT OR REPLACE INTO hnsw_metadata (key, value) VALUES (?, ?)');
|
|
96
|
+
if (this.entryPoint)
|
|
97
|
+
stmt.run('entry_point', this.entryPoint);
|
|
98
|
+
stmt.run('max_level', this.maxLevel.toString());
|
|
99
|
+
stmt.run('is_built', this.isBuilt.toString());
|
|
100
|
+
}
|
|
101
|
+
randomLevel() {
|
|
102
|
+
let level = 0;
|
|
103
|
+
while (Math.random() < this.config.mL && level < 16)
|
|
104
|
+
level++;
|
|
105
|
+
return level;
|
|
106
|
+
}
|
|
107
|
+
calculateDistance(a, b) {
|
|
108
|
+
let sum = 0;
|
|
109
|
+
for (let i = 0; i < a.length; i++) {
|
|
110
|
+
const diff = a[i] - b[i];
|
|
111
|
+
sum += diff * diff;
|
|
112
|
+
}
|
|
113
|
+
return Math.sqrt(sum);
|
|
114
|
+
}
|
|
115
|
+
serializeEmbedding(embedding) {
|
|
116
|
+
const buffer = Buffer.allocUnsafe(embedding.length * 4);
|
|
117
|
+
const view = new Float32Array(buffer.buffer, buffer.byteOffset, embedding.length);
|
|
118
|
+
view.set(embedding);
|
|
119
|
+
return buffer;
|
|
120
|
+
}
|
|
121
|
+
deserializeEmbedding(buffer) {
|
|
122
|
+
const view = new Float32Array(buffer.buffer, buffer.byteOffset, buffer.byteLength / 4);
|
|
123
|
+
return Array.from(view);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Get node from cache (build mode) or database
|
|
127
|
+
*/
|
|
128
|
+
getNode(id) {
|
|
129
|
+
if (this.buildMode && this.nodeCache.has(id)) {
|
|
130
|
+
return this.nodeCache.get(id);
|
|
131
|
+
}
|
|
132
|
+
const row = this.getNodeStmt.get(id);
|
|
133
|
+
if (!row)
|
|
134
|
+
return null;
|
|
135
|
+
return {
|
|
136
|
+
id: row.id,
|
|
137
|
+
vectorId: row.vector_id,
|
|
138
|
+
level: row.level,
|
|
139
|
+
embedding: this.deserializeEmbedding(row.embedding)
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Get neighbors from cache (build mode) or database
|
|
144
|
+
*/
|
|
145
|
+
getNeighbors(nodeId, level) {
|
|
146
|
+
if (this.buildMode) {
|
|
147
|
+
const nodeLevels = this.edgeCache.get(nodeId);
|
|
148
|
+
return nodeLevels?.get(level) ?? [];
|
|
149
|
+
}
|
|
150
|
+
const rows = this.getNeighborsStmt.all(nodeId, level);
|
|
151
|
+
return rows.map(row => ({ id: row.to_id, distance: row.distance }));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Add edge to cache (build mode) or database
|
|
155
|
+
*/
|
|
156
|
+
addEdge(fromId, toId, level, distance) {
|
|
157
|
+
if (this.buildMode) {
|
|
158
|
+
// Add to in-memory cache
|
|
159
|
+
if (!this.edgeCache.has(fromId)) {
|
|
160
|
+
this.edgeCache.set(fromId, new Map());
|
|
161
|
+
}
|
|
162
|
+
if (!this.edgeCache.has(toId)) {
|
|
163
|
+
this.edgeCache.set(toId, new Map());
|
|
164
|
+
}
|
|
165
|
+
const fromLevels = this.edgeCache.get(fromId);
|
|
166
|
+
const toLevels = this.edgeCache.get(toId);
|
|
167
|
+
if (!fromLevels.has(level))
|
|
168
|
+
fromLevels.set(level, []);
|
|
169
|
+
if (!toLevels.has(level))
|
|
170
|
+
toLevels.set(level, []);
|
|
171
|
+
fromLevels.get(level).push({ id: toId, distance });
|
|
172
|
+
toLevels.get(level).push({ id: fromId, distance });
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Write directly to database
|
|
176
|
+
this.insertEdgeStmt.run(fromId, toId, level, distance);
|
|
177
|
+
this.insertEdgeStmt.run(toId, fromId, level, distance);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
searchLayer(query, entryPoints, ef, level) {
|
|
181
|
+
const visited = new Set();
|
|
182
|
+
const candidates = [];
|
|
183
|
+
const results = [];
|
|
184
|
+
// Initialize with entry points
|
|
185
|
+
for (const ep of entryPoints) {
|
|
186
|
+
const node = this.getNode(ep);
|
|
187
|
+
if (!node)
|
|
188
|
+
continue;
|
|
189
|
+
const distance = this.calculateDistance(query, node.embedding);
|
|
190
|
+
candidates.push({ id: ep, distance });
|
|
191
|
+
results.push({ id: ep, distance });
|
|
192
|
+
visited.add(ep);
|
|
193
|
+
}
|
|
194
|
+
candidates.sort((a, b) => a.distance - b.distance);
|
|
195
|
+
results.sort((a, b) => a.distance - b.distance);
|
|
196
|
+
while (candidates.length > 0) {
|
|
197
|
+
const current = candidates.shift();
|
|
198
|
+
if (results.length >= ef && current.distance > results[results.length - 1].distance) {
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
201
|
+
const neighbors = this.getNeighbors(current.id, level);
|
|
202
|
+
for (const neighbor of neighbors) {
|
|
203
|
+
if (visited.has(neighbor.id))
|
|
204
|
+
continue;
|
|
205
|
+
visited.add(neighbor.id);
|
|
206
|
+
const node = this.getNode(neighbor.id);
|
|
207
|
+
if (!node)
|
|
208
|
+
continue;
|
|
209
|
+
const distance = this.calculateDistance(query, node.embedding);
|
|
210
|
+
if (results.length < ef || distance < results[results.length - 1].distance) {
|
|
211
|
+
candidates.push({ id: neighbor.id, distance });
|
|
212
|
+
results.push({ id: neighbor.id, distance });
|
|
213
|
+
results.sort((a, b) => a.distance - b.distance);
|
|
214
|
+
if (results.length > ef)
|
|
215
|
+
results.pop();
|
|
216
|
+
candidates.sort((a, b) => a.distance - b.distance);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return results;
|
|
221
|
+
}
|
|
222
|
+
selectNeighborsHeuristic(candidates, M) {
|
|
223
|
+
candidates.sort((a, b) => a.distance - b.distance);
|
|
224
|
+
return candidates.slice(0, M);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Insert node into in-memory graph (build mode only)
|
|
228
|
+
*/
|
|
229
|
+
insertToMemory(vectorId, embedding) {
|
|
230
|
+
const nodeId = `hnsw_${vectorId}`;
|
|
231
|
+
const level = this.randomLevel();
|
|
232
|
+
// Add to node cache
|
|
233
|
+
const node = { id: nodeId, vectorId, level, embedding };
|
|
234
|
+
this.nodeCache.set(nodeId, node);
|
|
235
|
+
if (level > this.maxLevel)
|
|
236
|
+
this.maxLevel = level;
|
|
237
|
+
if (!this.entryPoint) {
|
|
238
|
+
this.entryPoint = nodeId;
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
let entryPoints = [this.entryPoint];
|
|
242
|
+
// Navigate to target level
|
|
243
|
+
for (let lc = this.maxLevel; lc > level; lc--) {
|
|
244
|
+
const nearest = this.searchLayer(embedding, entryPoints, 1, lc);
|
|
245
|
+
if (nearest.length > 0)
|
|
246
|
+
entryPoints = [nearest[0].id];
|
|
247
|
+
}
|
|
248
|
+
// Insert at all levels
|
|
249
|
+
for (let lc = level; lc >= 0; lc--) {
|
|
250
|
+
const M = lc === 0 ? this.config.M0 : this.config.M;
|
|
251
|
+
const candidates = this.searchLayer(embedding, entryPoints, this.config.efConstruction, lc);
|
|
252
|
+
const neighbors = this.selectNeighborsHeuristic(candidates, M);
|
|
253
|
+
for (const neighbor of neighbors) {
|
|
254
|
+
this.addEdge(nodeId, neighbor.id, lc, neighbor.distance);
|
|
255
|
+
}
|
|
256
|
+
// Prune neighbors if needed
|
|
257
|
+
for (const neighbor of neighbors) {
|
|
258
|
+
const neighborConnections = this.getNeighbors(neighbor.id, lc);
|
|
259
|
+
if (neighborConnections.length > M) {
|
|
260
|
+
// Remove old edges
|
|
261
|
+
const nodeLevels = this.edgeCache.get(neighbor.id);
|
|
262
|
+
if (nodeLevels)
|
|
263
|
+
nodeLevels.set(lc, []);
|
|
264
|
+
const node = this.getNode(neighbor.id);
|
|
265
|
+
if (node) {
|
|
266
|
+
const newCandidates = [];
|
|
267
|
+
for (const nc of neighborConnections) {
|
|
268
|
+
const n = this.getNode(nc.id);
|
|
269
|
+
if (n) {
|
|
270
|
+
newCandidates.push({
|
|
271
|
+
id: nc.id,
|
|
272
|
+
distance: this.calculateDistance(node.embedding, n.embedding)
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const selected = this.selectNeighborsHeuristic(newCandidates, M);
|
|
277
|
+
for (const sel of selected) {
|
|
278
|
+
this.addEdge(neighbor.id, sel.id, lc, sel.distance);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
entryPoints = neighbors.map(n => n.id);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Flush in-memory graph to database (bulk write)
|
|
288
|
+
*/
|
|
289
|
+
flushToDatabase() {
|
|
290
|
+
console.log('Flushing in-memory graph to database...');
|
|
291
|
+
const startTime = Date.now();
|
|
292
|
+
const transaction = this.db.transaction(() => {
|
|
293
|
+
// Write all nodes
|
|
294
|
+
for (const node of this.nodeCache.values()) {
|
|
295
|
+
this.insertNodeStmt.run(node.id, node.vectorId, node.level, this.serializeEmbedding(node.embedding));
|
|
296
|
+
}
|
|
297
|
+
// Write all edges (deduplicated)
|
|
298
|
+
const writtenEdges = new Set();
|
|
299
|
+
for (const [fromId, levels] of this.edgeCache) {
|
|
300
|
+
for (const [level, neighbors] of levels) {
|
|
301
|
+
for (const neighbor of neighbors) {
|
|
302
|
+
const edgeKey = `${fromId}:${neighbor.id}:${level}`;
|
|
303
|
+
const reverseKey = `${neighbor.id}:${fromId}:${level}`;
|
|
304
|
+
if (!writtenEdges.has(edgeKey) && !writtenEdges.has(reverseKey)) {
|
|
305
|
+
this.insertEdgeStmt.run(fromId, neighbor.id, level, neighbor.distance);
|
|
306
|
+
this.insertEdgeStmt.run(neighbor.id, fromId, level, neighbor.distance);
|
|
307
|
+
writtenEdges.add(edgeKey);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
transaction();
|
|
314
|
+
const duration = Date.now() - startTime;
|
|
315
|
+
console.log(`Flushed ${this.nodeCache.size} nodes and ${this.edgeCache.size} edge groups in ${duration}ms`);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Build index with in-memory optimization
|
|
319
|
+
*/
|
|
320
|
+
buildOptimized() {
|
|
321
|
+
console.log('Building optimized HNSW index...');
|
|
322
|
+
this.clear();
|
|
323
|
+
const stmt = this.db.prepare('SELECT id, embedding FROM vectors ORDER BY id');
|
|
324
|
+
const rows = stmt.all();
|
|
325
|
+
if (rows.length === 0) {
|
|
326
|
+
console.log('No vectors to index');
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
console.log(`Building in-memory graph for ${rows.length} vectors...`);
|
|
330
|
+
const startBuild = Date.now();
|
|
331
|
+
// Enable build mode (use in-memory cache)
|
|
332
|
+
this.buildMode = true;
|
|
333
|
+
this.nodeCache.clear();
|
|
334
|
+
this.edgeCache.clear();
|
|
335
|
+
// Build graph in memory
|
|
336
|
+
for (const row of rows) {
|
|
337
|
+
const embedding = this.deserializeEmbedding(row.embedding);
|
|
338
|
+
this.insertToMemory(row.id, embedding);
|
|
339
|
+
}
|
|
340
|
+
const buildDuration = Date.now() - startBuild;
|
|
341
|
+
const perVector = buildDuration / rows.length;
|
|
342
|
+
console.log(`In-memory graph built in ${buildDuration}ms (${perVector.toFixed(2)}ms per vector)`);
|
|
343
|
+
// Flush to database
|
|
344
|
+
this.flushToDatabase();
|
|
345
|
+
// Disable build mode
|
|
346
|
+
this.buildMode = false;
|
|
347
|
+
this.nodeCache.clear();
|
|
348
|
+
this.edgeCache.clear();
|
|
349
|
+
const totalDuration = Date.now() - startBuild;
|
|
350
|
+
console.log(`Total build time: ${totalDuration}ms (${(totalDuration / rows.length).toFixed(2)}ms per vector)`);
|
|
351
|
+
this.isBuilt = true;
|
|
352
|
+
this.saveMetadata();
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Search using HNSW index
|
|
356
|
+
*/
|
|
357
|
+
search(query, k) {
|
|
358
|
+
if (!this.entryPoint || !this.isBuilt)
|
|
359
|
+
return [];
|
|
360
|
+
let entryPoints = [this.entryPoint];
|
|
361
|
+
for (let lc = this.maxLevel; lc > 0; lc--) {
|
|
362
|
+
const nearest = this.searchLayer(query, entryPoints, 1, lc);
|
|
363
|
+
if (nearest.length > 0)
|
|
364
|
+
entryPoints = [nearest[0].id];
|
|
365
|
+
}
|
|
366
|
+
const ef = Math.max(this.config.efSearch, k);
|
|
367
|
+
const results = this.searchLayer(query, entryPoints, ef, 0);
|
|
368
|
+
return results.slice(0, k).map(result => {
|
|
369
|
+
const node = this.getNode(result.id);
|
|
370
|
+
return {
|
|
371
|
+
id: result.id,
|
|
372
|
+
vectorId: node.vectorId,
|
|
373
|
+
distance: result.distance,
|
|
374
|
+
embedding: node.embedding
|
|
375
|
+
};
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
clear() {
|
|
379
|
+
this.db.exec('DELETE FROM hnsw_edges');
|
|
380
|
+
this.db.exec('DELETE FROM hnsw_nodes');
|
|
381
|
+
this.db.exec('DELETE FROM hnsw_metadata');
|
|
382
|
+
this.entryPoint = null;
|
|
383
|
+
this.maxLevel = 0;
|
|
384
|
+
this.isBuilt = false;
|
|
385
|
+
this.nodeCache.clear();
|
|
386
|
+
this.edgeCache.clear();
|
|
387
|
+
}
|
|
388
|
+
getStats() {
|
|
389
|
+
const nodeCountStmt = this.db.prepare('SELECT COUNT(*) as count FROM hnsw_nodes');
|
|
390
|
+
const edgeCountStmt = this.db.prepare('SELECT COUNT(*) as count FROM hnsw_edges');
|
|
391
|
+
const nodeCount = nodeCountStmt.get().count;
|
|
392
|
+
const edgeCount = edgeCountStmt.get().count;
|
|
393
|
+
return {
|
|
394
|
+
nodeCount,
|
|
395
|
+
edgeCount,
|
|
396
|
+
maxLevel: this.maxLevel,
|
|
397
|
+
isBuilt: this.isBuilt,
|
|
398
|
+
avgDegree: nodeCount > 0 ? edgeCount / nodeCount : 0
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
isReady() {
|
|
402
|
+
return this.isBuilt && this.entryPoint !== null;
|
|
403
|
+
}
|
|
404
|
+
getConfig() {
|
|
405
|
+
return { ...this.config };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HNSW (Hierarchical Navigable Small World) Index Implementation
|
|
3
|
+
* High-performance approximate nearest neighbor search with O(log n) complexity
|
|
4
|
+
*
|
|
5
|
+
* Algorithm: Hierarchical graph structure with multiple layers
|
|
6
|
+
* - Layer 0: All vectors with dense connections
|
|
7
|
+
* - Higher layers: Sparse long-range connections for efficient navigation
|
|
8
|
+
*
|
|
9
|
+
* Performance targets:
|
|
10
|
+
* - Search: <10ms for 10K vectors
|
|
11
|
+
* - Build: <5s for 10K vectors
|
|
12
|
+
* - Recall: >95% accuracy
|
|
13
|
+
*/
|
|
14
|
+
import Database from 'better-sqlite3';
|
|
15
|
+
/**
|
|
16
|
+
* HNSW configuration parameters
|
|
17
|
+
*/
|
|
18
|
+
export interface HNSWConfig {
|
|
19
|
+
/** Maximum number of bi-directional links per element (default: 16) */
|
|
20
|
+
M: number;
|
|
21
|
+
/** Maximum connections for layer 0 (default: M * 2) */
|
|
22
|
+
M0: number;
|
|
23
|
+
/** Size of dynamic candidate list during construction (default: 200) */
|
|
24
|
+
efConstruction: number;
|
|
25
|
+
/** Size of dynamic candidate list during search (default: 50) */
|
|
26
|
+
efSearch: number;
|
|
27
|
+
/** Random level generation parameter (default: 1 / ln(M)) */
|
|
28
|
+
mL: number;
|
|
29
|
+
/** Minimum vectors to enable index (default: 1000) */
|
|
30
|
+
minVectorsForIndex: number;
|
|
31
|
+
/** Auto-rebuild index on updates (default: false) */
|
|
32
|
+
autoRebuild: boolean;
|
|
33
|
+
/** Enable index usage (default: true) */
|
|
34
|
+
enabled: boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Default HNSW configuration optimized for most use cases
|
|
38
|
+
*/
|
|
39
|
+
export declare const DEFAULT_HNSW_CONFIG: HNSWConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Search result with distance
|
|
42
|
+
*/
|
|
43
|
+
interface HNSWSearchResult {
|
|
44
|
+
id: string;
|
|
45
|
+
vectorId: string;
|
|
46
|
+
distance: number;
|
|
47
|
+
embedding: number[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* HNSW Index implementation
|
|
51
|
+
*/
|
|
52
|
+
export declare class HNSWIndex {
|
|
53
|
+
private db;
|
|
54
|
+
private config;
|
|
55
|
+
private entryPoint;
|
|
56
|
+
private maxLevel;
|
|
57
|
+
private isBuilt;
|
|
58
|
+
private insertNodeStmt;
|
|
59
|
+
private insertEdgeStmt;
|
|
60
|
+
private getNodeStmt;
|
|
61
|
+
private getNeighborsStmt;
|
|
62
|
+
private deleteNodeStmt;
|
|
63
|
+
private deleteEdgesStmt;
|
|
64
|
+
constructor(db: Database.Database, config?: Partial<HNSWConfig>);
|
|
65
|
+
/**
|
|
66
|
+
* Initialize HNSW schema in SQLite
|
|
67
|
+
*/
|
|
68
|
+
private initializeSchema;
|
|
69
|
+
/**
|
|
70
|
+
* Prepare frequently used SQL statements
|
|
71
|
+
*/
|
|
72
|
+
private prepareStatements;
|
|
73
|
+
/**
|
|
74
|
+
* Load metadata from database
|
|
75
|
+
*/
|
|
76
|
+
private loadMetadata;
|
|
77
|
+
/**
|
|
78
|
+
* Save metadata to database
|
|
79
|
+
*/
|
|
80
|
+
private saveMetadata;
|
|
81
|
+
/**
|
|
82
|
+
* Calculate random level for new node using exponential decay
|
|
83
|
+
*/
|
|
84
|
+
private randomLevel;
|
|
85
|
+
/**
|
|
86
|
+
* Calculate Euclidean distance between two vectors
|
|
87
|
+
*/
|
|
88
|
+
private calculateDistance;
|
|
89
|
+
/**
|
|
90
|
+
* Serialize embedding to Buffer
|
|
91
|
+
*/
|
|
92
|
+
private serializeEmbedding;
|
|
93
|
+
/**
|
|
94
|
+
* Deserialize embedding from Buffer
|
|
95
|
+
*/
|
|
96
|
+
private deserializeEmbedding;
|
|
97
|
+
/**
|
|
98
|
+
* Get node by ID
|
|
99
|
+
*/
|
|
100
|
+
private getNode;
|
|
101
|
+
/**
|
|
102
|
+
* Get neighbors of a node at a specific level
|
|
103
|
+
*/
|
|
104
|
+
private getNeighbors;
|
|
105
|
+
/**
|
|
106
|
+
* Search for k nearest neighbors at a specific layer
|
|
107
|
+
*/
|
|
108
|
+
private searchLayer;
|
|
109
|
+
/**
|
|
110
|
+
* Select neighbors using heuristic (Alg 4 from HNSW paper)
|
|
111
|
+
*/
|
|
112
|
+
private selectNeighborsHeuristic;
|
|
113
|
+
/**
|
|
114
|
+
* Add bidirectional link between nodes
|
|
115
|
+
*/
|
|
116
|
+
private addEdge;
|
|
117
|
+
/**
|
|
118
|
+
* Insert a new node into the HNSW index (optimized version)
|
|
119
|
+
*/
|
|
120
|
+
insert(vectorId: string, embedding: number[]): void;
|
|
121
|
+
/**
|
|
122
|
+
* Search for k nearest neighbors using HNSW index
|
|
123
|
+
*/
|
|
124
|
+
search(query: number[], k: number): HNSWSearchResult[];
|
|
125
|
+
/**
|
|
126
|
+
* Build HNSW index from all vectors in database with optimizations
|
|
127
|
+
*/
|
|
128
|
+
build(): void;
|
|
129
|
+
/**
|
|
130
|
+
* Build index incrementally (non-blocking for large datasets)
|
|
131
|
+
*/
|
|
132
|
+
buildAsync(onProgress?: (current: number, total: number, timeMs: number) => void): Promise<void>;
|
|
133
|
+
/**
|
|
134
|
+
* Clear the entire index
|
|
135
|
+
*/
|
|
136
|
+
clear(): void;
|
|
137
|
+
/**
|
|
138
|
+
* Delete a node from the index
|
|
139
|
+
*/
|
|
140
|
+
delete(vectorId: string): void;
|
|
141
|
+
/**
|
|
142
|
+
* Get index statistics
|
|
143
|
+
*/
|
|
144
|
+
getStats(): {
|
|
145
|
+
nodeCount: number;
|
|
146
|
+
edgeCount: number;
|
|
147
|
+
maxLevel: number;
|
|
148
|
+
isBuilt: boolean;
|
|
149
|
+
avgDegree: number;
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Check if index is ready to use
|
|
153
|
+
*/
|
|
154
|
+
isReady(): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Get configuration
|
|
157
|
+
*/
|
|
158
|
+
getConfig(): HNSWConfig;
|
|
159
|
+
/**
|
|
160
|
+
* Update configuration (requires rebuild)
|
|
161
|
+
*/
|
|
162
|
+
updateConfig(config: Partial<HNSWConfig>): void;
|
|
163
|
+
}
|
|
164
|
+
export {};
|
|
165
|
+
//# sourceMappingURL=hnsw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hnsw.d.ts","sourceRoot":"","sources":["../../src/index/hnsw.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,CAAC,EAAE,MAAM,CAAC;IAEV,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAC;IAEX,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;IAEvB,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IAEjB,6DAA6D;IAC7D,EAAE,EAAE,MAAM,CAAC;IAEX,sDAAsD;IACtD,kBAAkB,EAAE,MAAM,CAAC;IAE3B,qDAAqD;IACrD,WAAW,EAAE,OAAO,CAAC;IAErB,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,UASjC,CAAC;AAsBF;;GAEG;AACH,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAUD;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAuB;IACzC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,OAAO,CAAkB;IAGjC,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,eAAe,CAAsB;gBAEjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAE,OAAO,CAAC,UAAU,CAAM;IAQnE;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAyCxB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAiCzB;;OAEG;IACH,OAAO,CAAC,YAAY;IAmBpB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;OAEG;IACH,OAAO,CAAC,OAAO;IAYf;;OAEG;IACH,OAAO,CAAC,YAAY;IAQpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAiEnB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAShC;;OAEG;IACH,OAAO,CAAC,OAAO;IAKf;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IA2FnD;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE;IA+BtD;;OAEG;IACH,KAAK,IAAI,IAAI;IAmCb;;OAEG;IACG,UAAU,CACd,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GACpE,OAAO,CAAC,IAAI,CAAC;IAkDhB;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IA4B9B;;OAEG;IACH,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;KACnB;IAiBD;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,SAAS,IAAI,UAAU;IAIvB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI;CAGhD"}
|