cozo-memory 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.
Files changed (49) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +533 -0
  3. package/dist/api_bridge.js +266 -0
  4. package/dist/benchmark-gpu-cpu.js +188 -0
  5. package/dist/benchmark-heavy.js +230 -0
  6. package/dist/benchmark.js +160 -0
  7. package/dist/clear-cache.js +29 -0
  8. package/dist/db-service.js +228 -0
  9. package/dist/download-model.js +48 -0
  10. package/dist/embedding-service.js +249 -0
  11. package/dist/full-system-test.js +45 -0
  12. package/dist/hybrid-search.js +337 -0
  13. package/dist/index.js +3106 -0
  14. package/dist/inference-engine.js +348 -0
  15. package/dist/memory-service.js +215 -0
  16. package/dist/test-advanced-filters.js +64 -0
  17. package/dist/test-advanced-search.js +82 -0
  18. package/dist/test-advanced-time.js +47 -0
  19. package/dist/test-embedding.js +22 -0
  20. package/dist/test-filter-expr.js +84 -0
  21. package/dist/test-fts.js +58 -0
  22. package/dist/test-functions.js +25 -0
  23. package/dist/test-gpu-check.js +16 -0
  24. package/dist/test-graph-algs-final.js +76 -0
  25. package/dist/test-graph-filters.js +88 -0
  26. package/dist/test-graph-rag.js +124 -0
  27. package/dist/test-graph-walking.js +138 -0
  28. package/dist/test-index.js +35 -0
  29. package/dist/test-int-filter.js +48 -0
  30. package/dist/test-integration.js +69 -0
  31. package/dist/test-lower.js +35 -0
  32. package/dist/test-lsh.js +67 -0
  33. package/dist/test-mcp-tool.js +40 -0
  34. package/dist/test-pagerank.js +31 -0
  35. package/dist/test-semantic-walk.js +145 -0
  36. package/dist/test-time-filter.js +66 -0
  37. package/dist/test-time-functions.js +38 -0
  38. package/dist/test-triggers.js +60 -0
  39. package/dist/test-ts-ort.js +48 -0
  40. package/dist/test-validity-access.js +35 -0
  41. package/dist/test-validity-body.js +42 -0
  42. package/dist/test-validity-decomp.js +37 -0
  43. package/dist/test-validity-extraction.js +45 -0
  44. package/dist/test-validity-json.js +35 -0
  45. package/dist/test-validity.js +38 -0
  46. package/dist/types.js +3 -0
  47. package/dist/verify-gpu.js +30 -0
  48. package/dist/verify_transaction_tool.js +46 -0
  49. package/package.json +75 -0
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const index_1 = require("./index");
7
+ const path_1 = __importDefault(require("path"));
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const perf_hooks_1 = require("perf_hooks");
10
+ const BENCHMARK_DB_PATH = path_1.default.join(process.cwd(), "benchmark_db");
11
+ async function runBenchmark() {
12
+ console.log("🚀 Starting Performance Benchmark...");
13
+ // Cleanup
14
+ if (fs_1.default.existsSync(BENCHMARK_DB_PATH + ".db")) {
15
+ fs_1.default.unlinkSync(BENCHMARK_DB_PATH + ".db");
16
+ }
17
+ // Measure Memory Baseline
18
+ const memStart = process.memoryUsage();
19
+ // Initialize Server
20
+ console.log("• Initializing Server & Loading Embedding Model...");
21
+ const initStart = perf_hooks_1.performance.now();
22
+ const server = new index_1.MemoryServer(BENCHMARK_DB_PATH);
23
+ // Force embedding model load
24
+ await server.embeddingService.embed("warmup");
25
+ const initEnd = perf_hooks_1.performance.now();
26
+ console.log(` -> Init Time: ${(initEnd - initStart).toFixed(2)}ms`);
27
+ const memAfterInit = process.memoryUsage();
28
+ console.log(` -> Memory Increase (Init): ${((memAfterInit.rss - memStart.rss) / 1024 / 1024).toFixed(2)} MB RSS`);
29
+ // Data Generation
30
+ const NUM_ENTITIES = 50;
31
+ const NUM_OBSERVATIONS = 200;
32
+ const NUM_RELATIONS = 100;
33
+ console.log(`\n• Generating Data (${NUM_ENTITIES} Entities, ${NUM_OBSERVATIONS} Observations, ${NUM_RELATIONS} Relations)...`);
34
+ const dataStart = perf_hooks_1.performance.now();
35
+ // Entities
36
+ const entities = [];
37
+ for (let i = 0; i < NUM_ENTITIES; i++) {
38
+ entities.push(await server.createEntity({
39
+ name: `Entity_${i}`,
40
+ type: i % 2 === 0 ? "Person" : "Project",
41
+ metadata: { index: i }
42
+ }));
43
+ }
44
+ // Observations
45
+ for (let i = 0; i < NUM_OBSERVATIONS; i++) {
46
+ const entity = entities[i % NUM_ENTITIES];
47
+ // @ts-ignore
48
+ await server.addObservation({
49
+ // @ts-ignore
50
+ entity_id: entity.id,
51
+ text: `This is observation number ${i} for entity ${ // @ts-ignore
52
+ entity.name}. It contains some random keywords like apple, banana, and cherry.`
53
+ });
54
+ }
55
+ // Relations
56
+ for (let i = 0; i < NUM_RELATIONS; i++) {
57
+ const from = entities[i % NUM_ENTITIES];
58
+ const to = entities[(i + 1) % NUM_ENTITIES];
59
+ // @ts-ignore
60
+ await server.createRelation({
61
+ // @ts-ignore
62
+ from_id: from.id,
63
+ // @ts-ignore
64
+ to_id: to.id,
65
+ relation_type: "related_to",
66
+ strength: 0.5
67
+ });
68
+ }
69
+ const dataEnd = perf_hooks_1.performance.now();
70
+ console.log(` -> Data Ingestion Time: ${(dataEnd - dataStart).toFixed(2)}ms`);
71
+ console.log(` -> Avg Time per Operation: ${((dataEnd - dataStart) / (NUM_ENTITIES + NUM_OBSERVATIONS + NUM_RELATIONS)).toFixed(2)}ms`);
72
+ const memAfterData = process.memoryUsage();
73
+ console.log(` -> Memory Increase (Data): ${((memAfterData.rss - memAfterInit.rss) / 1024 / 1024).toFixed(2)} MB RSS`);
74
+ // Query Benchmark
75
+ console.log("\n• Running Queries (Hybrid Search)...");
76
+ const queries = [
77
+ "observation number 10",
78
+ "apple banana",
79
+ "Entity_0",
80
+ "Project related"
81
+ ];
82
+ const times = [];
83
+ for (const q of queries) {
84
+ const t0 = perf_hooks_1.performance.now();
85
+ await server.hybridSearch.search({
86
+ query: q,
87
+ limit: 10,
88
+ includeEntities: true,
89
+ includeObservations: true
90
+ });
91
+ const t1 = perf_hooks_1.performance.now();
92
+ times.push(t1 - t0);
93
+ process.stdout.write(".");
94
+ }
95
+ console.log("");
96
+ const avgQueryTime = times.reduce((a, b) => a + b, 0) / times.length;
97
+ const minQueryTime = Math.min(...times);
98
+ const maxQueryTime = Math.max(...times);
99
+ console.log(` -> Avg Query Time: ${avgQueryTime.toFixed(2)}ms`);
100
+ console.log(` -> Min Query Time: ${minQueryTime.toFixed(2)}ms`);
101
+ console.log(` -> Max Query Time: ${maxQueryTime.toFixed(2)}ms`);
102
+ // RRF Overhead Estimation (Approximation)
103
+ // We perform a raw vector search (fastest component) and compare with hybrid search
104
+ // This is a rough proxy because hybrid search does 5 parallel searches + RRF
105
+ console.log("\n• Estimating RRF/Combination Overhead...");
106
+ const tVecStart = perf_hooks_1.performance.now();
107
+ // Access private method via any cast or just simulate a similar query
108
+ // Since we can't easily access private methods, we will rely on the fact that
109
+ // Hybrid Search = Promise.all([Vector, Keyword, Graph]) + RRF
110
+ // We'll run a search with ONLY vector enabled (by setting weights of others to 0? No, they still run)
111
+ // We will try to run a pure DB query to simulate vector search time
112
+ const vectorOnlyStart = perf_hooks_1.performance.now();
113
+ const qEmb = await server.embeddingService.embed("apple");
114
+ await server.db.run(`
115
+ ?[id, score] := ~entity:semantic { id | query: vec($qEmb), k: 10, ef: 20 }, score = 1.0
116
+ `, { qEmb });
117
+ const vectorOnlyEnd = perf_hooks_1.performance.now();
118
+ const vectorTime = vectorOnlyEnd - vectorOnlyStart;
119
+ console.log(` -> Raw Vector Search Time: ${vectorTime.toFixed(2)}ms`);
120
+ console.log(` -> Overhead (Hybrid Logic + RRF): ${(avgQueryTime - vectorTime).toFixed(2)}ms`);
121
+ // Graph Benchmark
122
+ console.log("\n• Running Graph Benchmarks (Graph-RAG & Graph-Walking)...");
123
+ // Graph-RAG
124
+ const ragStart = perf_hooks_1.performance.now();
125
+ // @ts-ignore
126
+ await server.hybridSearch.graphRag({
127
+ query: "Entity_0",
128
+ limit: 20,
129
+ graphConstraints: {
130
+ maxDepth: 2
131
+ }
132
+ });
133
+ const ragEnd = perf_hooks_1.performance.now();
134
+ console.log(` -> Graph-RAG (2-Hop) Time: ${(ragEnd - ragStart).toFixed(2)}ms`);
135
+ // Graph-Walking
136
+ const walkStart = perf_hooks_1.performance.now();
137
+ // @ts-ignore
138
+ const startEntityId = entities[0].id;
139
+ // @ts-ignore
140
+ await server.graph_walking({
141
+ query: "related concepts",
142
+ start_entity_id: startEntityId,
143
+ max_depth: 3,
144
+ limit: 10
145
+ });
146
+ const walkEnd = perf_hooks_1.performance.now();
147
+ console.log(` -> Graph-Walking (Recursive) Time: ${(walkEnd - walkStart).toFixed(2)}ms`);
148
+ // Final Memory
149
+ const memFinal = process.memoryUsage();
150
+ console.log("\n• Final Memory Stats:");
151
+ console.log(` -> RSS: ${(memFinal.rss / 1024 / 1024).toFixed(2)} MB`);
152
+ console.log(` -> Heap Used: ${(memFinal.heapUsed / 1024 / 1024).toFixed(2)} MB`);
153
+ // Cleanup
154
+ // @ts-ignore
155
+ server.db.close();
156
+ if (fs_1.default.existsSync(BENCHMARK_DB_PATH + ".db")) {
157
+ fs_1.default.unlinkSync(BENCHMARK_DB_PATH + ".db");
158
+ }
159
+ }
160
+ runBenchmark().catch(console.error);
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const cozo_node_1 = require("cozo-node");
7
+ const path_1 = __importDefault(require("path"));
8
+ async function main() {
9
+ const dbPath = path_1.default.resolve(__dirname, "..", "memory_db.cozo.db");
10
+ console.log("DB Path:", dbPath);
11
+ try {
12
+ const db = new cozo_node_1.CozoDb("sqlite", dbPath);
13
+ const keys = await db.run("?[hash] := *search_cache{query_hash: hash}");
14
+ console.log(`Found ${keys.rows.length} cache entries.`);
15
+ if (keys.rows.length > 0) {
16
+ await db.run("?[hash] <- $hashes :delete search_cache {query_hash: hash}", {
17
+ hashes: keys.rows
18
+ });
19
+ console.log("Cache cleared.");
20
+ }
21
+ else {
22
+ console.log("Cache is already empty.");
23
+ }
24
+ }
25
+ catch (e) {
26
+ console.error("Error:", e.message);
27
+ }
28
+ }
29
+ main();
@@ -0,0 +1,228 @@
1
+ "use strict";
2
+ // Simple in-memory database simulation for CozoDB
3
+ // This will be replaced with actual CozoDB integration
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.DatabaseService = void 0;
6
+ class DatabaseService {
7
+ entities = new Map();
8
+ observations = new Map();
9
+ relationships = new Map();
10
+ snapshots = new Map();
11
+ dbPath;
12
+ engine;
13
+ constructor(dbPath = 'memory_db.cozo.db', engine = 'sqlite') {
14
+ this.dbPath = dbPath;
15
+ this.engine = engine;
16
+ }
17
+ async initialize() {
18
+ console.error('[DatabaseService] Connected to ' + this.engine + ' at ' + this.dbPath);
19
+ console.error('[DatabaseService] Database schema initialized');
20
+ }
21
+ async runQuery(query, params = {}) {
22
+ console.error('[DatabaseService] Query:', query);
23
+ return { rows: [] };
24
+ }
25
+ async exportRelations() {
26
+ const result = {
27
+ entity: [],
28
+ observation: [],
29
+ relationship: [],
30
+ };
31
+ for (const entity of this.entities.values()) {
32
+ result.entity.push([entity.id, entity.name, entity.type, entity.embedding, entity.name_embedding, entity.metadata, entity.created_at]);
33
+ }
34
+ for (const obs of this.observations.values()) {
35
+ result.observation.push([obs.id, obs.entity_id, obs.text, obs.embedding, obs.metadata, obs.created_at]);
36
+ }
37
+ for (const rels of this.relationships.values()) {
38
+ for (const rel of rels) {
39
+ result.relationship.push([rel.from_id, rel.to_id, rel.relation_type, rel.strength, rel.metadata, rel.created_at]);
40
+ }
41
+ }
42
+ return result;
43
+ }
44
+ async backup(path) {
45
+ console.error('[DatabaseService] Backup to:', path);
46
+ }
47
+ async restore(path) {
48
+ console.error('[DatabaseService] Restore from:', path);
49
+ }
50
+ async close() {
51
+ console.error('[DatabaseService] Database closed');
52
+ }
53
+ async createEntity(entity) {
54
+ const dbEntity = {
55
+ id: entity.id,
56
+ name: entity.name,
57
+ type: entity.type,
58
+ embedding: entity.embedding,
59
+ name_embedding: entity.name_embedding,
60
+ metadata: entity.metadata,
61
+ created_at: entity.created_at,
62
+ };
63
+ this.entities.set(entity.id, dbEntity);
64
+ }
65
+ async getEntity(id, asOf) {
66
+ const entity = this.entities.get(id);
67
+ if (!entity)
68
+ return null;
69
+ return {
70
+ id: entity.id,
71
+ name: entity.name,
72
+ type: entity.type,
73
+ embedding: entity.embedding,
74
+ name_embedding: entity.name_embedding,
75
+ metadata: entity.metadata,
76
+ created_at: entity.created_at,
77
+ };
78
+ }
79
+ async updateEntity(id, updates) {
80
+ const entity = this.entities.get(id);
81
+ if (!entity)
82
+ return;
83
+ if (updates.name !== undefined)
84
+ entity.name = updates.name;
85
+ if (updates.type !== undefined)
86
+ entity.type = updates.type;
87
+ if (updates.metadata !== undefined)
88
+ entity.metadata = { ...entity.metadata, ...updates.metadata };
89
+ if (updates.embedding !== undefined)
90
+ entity.embedding = updates.embedding;
91
+ if (updates.name_embedding !== undefined)
92
+ entity.name_embedding = updates.name_embedding;
93
+ }
94
+ async deleteEntity(id) {
95
+ this.entities.delete(id);
96
+ for (const [obsId, obs] of this.observations.entries()) {
97
+ if (obs.entity_id === id) {
98
+ this.observations.delete(obsId);
99
+ }
100
+ }
101
+ this.relationships.delete(id);
102
+ }
103
+ async addObservation(obs) {
104
+ const dbObs = {
105
+ id: obs.id,
106
+ entity_id: obs.entity_id,
107
+ text: obs.text,
108
+ embedding: obs.embedding,
109
+ metadata: obs.metadata,
110
+ created_at: obs.created_at,
111
+ };
112
+ this.observations.set(obs.id, dbObs);
113
+ }
114
+ async getObservationsForEntity(entityId) {
115
+ const result = [];
116
+ for (const obs of this.observations.values()) {
117
+ if (obs.entity_id === entityId) {
118
+ result.push({
119
+ id: obs.id,
120
+ entity_id: obs.entity_id,
121
+ text: obs.text,
122
+ embedding: obs.embedding,
123
+ metadata: obs.metadata,
124
+ created_at: obs.created_at,
125
+ });
126
+ }
127
+ }
128
+ return result;
129
+ }
130
+ async createRelation(rel) {
131
+ const dbRel = {
132
+ from_id: rel.from_id,
133
+ to_id: rel.to_id,
134
+ relation_type: rel.relation_type,
135
+ strength: rel.strength,
136
+ metadata: rel.metadata,
137
+ created_at: rel.created_at,
138
+ };
139
+ const existing = this.relationships.get(rel.from_id) || [];
140
+ existing.push(dbRel);
141
+ this.relationships.set(rel.from_id, existing);
142
+ }
143
+ async getRelations(fromId, toId) {
144
+ const result = [];
145
+ for (const rels of this.relationships.values()) {
146
+ for (const rel of rels) {
147
+ if (fromId && rel.from_id !== fromId)
148
+ continue;
149
+ if (toId && rel.to_id !== toId)
150
+ continue;
151
+ result.push({
152
+ from_id: rel.from_id,
153
+ to_id: rel.to_id,
154
+ relation_type: rel.relation_type,
155
+ strength: rel.strength,
156
+ metadata: rel.metadata,
157
+ created_at: rel.created_at,
158
+ });
159
+ }
160
+ }
161
+ return result;
162
+ }
163
+ async vectorSearchEntity(embedding, limit = 10) {
164
+ const results = [];
165
+ for (const entity of this.entities.values()) {
166
+ const similarity = this.cosineSimilarity(embedding, entity.embedding);
167
+ results.push([entity.id, entity.name, entity.type, entity.metadata, similarity]);
168
+ }
169
+ results.sort((a, b) => b[4] - a[4]);
170
+ return results.slice(0, limit);
171
+ }
172
+ async vectorSearchObservation(embedding, limit = 10) {
173
+ const results = [];
174
+ for (const obs of this.observations.values()) {
175
+ const similarity = this.cosineSimilarity(embedding, obs.embedding);
176
+ results.push([obs.id, obs.entity_id, obs.text, obs.metadata, similarity]);
177
+ }
178
+ results.sort((a, b) => b[4] - a[4]);
179
+ return results.slice(0, limit);
180
+ }
181
+ async fullTextSearchEntity(searchText, limit = 10) {
182
+ const query = searchText.toLowerCase();
183
+ const results = [];
184
+ for (const entity of this.entities.values()) {
185
+ if (entity.name.toLowerCase().includes(query)) {
186
+ results.push([entity.id, entity.name, entity.type, entity.metadata, 1]);
187
+ }
188
+ }
189
+ return results.slice(0, limit);
190
+ }
191
+ async fullTextSearchObservation(searchText, limit = 10) {
192
+ const query = searchText.toLowerCase();
193
+ const results = [];
194
+ for (const obs of this.observations.values()) {
195
+ if (obs.text.toLowerCase().includes(query)) {
196
+ results.push([obs.id, obs.entity_id, obs.text, obs.metadata, 1]);
197
+ }
198
+ }
199
+ return results.slice(0, limit);
200
+ }
201
+ cosineSimilarity(a, b) {
202
+ if (a.length !== b.length)
203
+ return 0;
204
+ let dotProduct = 0;
205
+ let normA = 0;
206
+ let normB = 0;
207
+ for (let i = 0; i < a.length; i++) {
208
+ dotProduct += a[i] * b[i];
209
+ normA += a[i] * a[i];
210
+ normB += b[i] * b[i];
211
+ }
212
+ if (normA === 0 || normB === 0)
213
+ return 0;
214
+ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB));
215
+ }
216
+ async getStats() {
217
+ let relCount = 0;
218
+ for (const rels of this.relationships.values()) {
219
+ relCount += rels.length;
220
+ }
221
+ return {
222
+ entities: this.entities.size,
223
+ observations: this.observations.size,
224
+ relationships: relCount,
225
+ };
226
+ }
227
+ }
228
+ exports.DatabaseService = DatabaseService;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const transformers_1 = require("@xenova/transformers");
37
+ const path = __importStar(require("path"));
38
+ // Configure cache path
39
+ const CACHE_DIR = path.resolve('./.cache');
40
+ transformers_1.env.cacheDir = CACHE_DIR;
41
+ const MODEL_ID = "Xenova/bge-m3";
42
+ async function downloadModel() {
43
+ console.log(`Downloading FP32 model for ${MODEL_ID}...`);
44
+ // quantized: false forces FP32 model download
45
+ await transformers_1.AutoModel.from_pretrained(MODEL_ID, { quantized: false });
46
+ console.log("Download completed.");
47
+ }
48
+ downloadModel();