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.
- package/LICENSE +201 -0
- package/README.md +533 -0
- package/dist/api_bridge.js +266 -0
- package/dist/benchmark-gpu-cpu.js +188 -0
- package/dist/benchmark-heavy.js +230 -0
- package/dist/benchmark.js +160 -0
- package/dist/clear-cache.js +29 -0
- package/dist/db-service.js +228 -0
- package/dist/download-model.js +48 -0
- package/dist/embedding-service.js +249 -0
- package/dist/full-system-test.js +45 -0
- package/dist/hybrid-search.js +337 -0
- package/dist/index.js +3106 -0
- package/dist/inference-engine.js +348 -0
- package/dist/memory-service.js +215 -0
- package/dist/test-advanced-filters.js +64 -0
- package/dist/test-advanced-search.js +82 -0
- package/dist/test-advanced-time.js +47 -0
- package/dist/test-embedding.js +22 -0
- package/dist/test-filter-expr.js +84 -0
- package/dist/test-fts.js +58 -0
- package/dist/test-functions.js +25 -0
- package/dist/test-gpu-check.js +16 -0
- package/dist/test-graph-algs-final.js +76 -0
- package/dist/test-graph-filters.js +88 -0
- package/dist/test-graph-rag.js +124 -0
- package/dist/test-graph-walking.js +138 -0
- package/dist/test-index.js +35 -0
- package/dist/test-int-filter.js +48 -0
- package/dist/test-integration.js +69 -0
- package/dist/test-lower.js +35 -0
- package/dist/test-lsh.js +67 -0
- package/dist/test-mcp-tool.js +40 -0
- package/dist/test-pagerank.js +31 -0
- package/dist/test-semantic-walk.js +145 -0
- package/dist/test-time-filter.js +66 -0
- package/dist/test-time-functions.js +38 -0
- package/dist/test-triggers.js +60 -0
- package/dist/test-ts-ort.js +48 -0
- package/dist/test-validity-access.js +35 -0
- package/dist/test-validity-body.js +42 -0
- package/dist/test-validity-decomp.js +37 -0
- package/dist/test-validity-extraction.js +45 -0
- package/dist/test-validity-json.js +35 -0
- package/dist/test-validity.js +38 -0
- package/dist/types.js +3 -0
- package/dist/verify-gpu.js +30 -0
- package/dist/verify_transaction_tool.js +46 -0
- 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();
|