ahok-skill 1.3.1
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/.prettierrc +8 -0
- package/Dockerfile +59 -0
- package/RAW_SKILL.md +219 -0
- package/README.md +277 -0
- package/SKILL.md +58 -0
- package/bin/opm.js +268 -0
- package/data/openmemory.sqlite +0 -0
- package/data/openmemory.sqlite-shm +0 -0
- package/data/openmemory.sqlite-wal +0 -0
- package/dist/ai/graph.js +293 -0
- package/dist/ai/mcp.js +397 -0
- package/dist/cli.js +78 -0
- package/dist/core/cfg.js +87 -0
- package/dist/core/db.js +636 -0
- package/dist/core/memory.js +116 -0
- package/dist/core/migrate.js +227 -0
- package/dist/core/models.js +105 -0
- package/dist/core/telemetry.js +57 -0
- package/dist/core/types.js +2 -0
- package/dist/core/vector/postgres.js +52 -0
- package/dist/core/vector/valkey.js +246 -0
- package/dist/core/vector_store.js +2 -0
- package/dist/index.js +44 -0
- package/dist/memory/decay.js +301 -0
- package/dist/memory/embed.js +675 -0
- package/dist/memory/hsg.js +959 -0
- package/dist/memory/reflect.js +131 -0
- package/dist/memory/user_summary.js +99 -0
- package/dist/migrate.js +9 -0
- package/dist/ops/compress.js +255 -0
- package/dist/ops/dynamics.js +189 -0
- package/dist/ops/extract.js +333 -0
- package/dist/ops/ingest.js +214 -0
- package/dist/server/index.js +109 -0
- package/dist/server/middleware/auth.js +137 -0
- package/dist/server/routes/auth.js +186 -0
- package/dist/server/routes/compression.js +108 -0
- package/dist/server/routes/dashboard.js +399 -0
- package/dist/server/routes/docs.js +241 -0
- package/dist/server/routes/dynamics.js +312 -0
- package/dist/server/routes/ide.js +280 -0
- package/dist/server/routes/index.js +33 -0
- package/dist/server/routes/keys.js +132 -0
- package/dist/server/routes/langgraph.js +61 -0
- package/dist/server/routes/memory.js +213 -0
- package/dist/server/routes/sources.js +140 -0
- package/dist/server/routes/system.js +63 -0
- package/dist/server/routes/temporal.js +293 -0
- package/dist/server/routes/users.js +101 -0
- package/dist/server/routes/vercel.js +57 -0
- package/dist/server/server.js +211 -0
- package/dist/server.js +3 -0
- package/dist/sources/base.js +223 -0
- package/dist/sources/github.js +171 -0
- package/dist/sources/google_drive.js +166 -0
- package/dist/sources/google_sheets.js +112 -0
- package/dist/sources/google_slides.js +139 -0
- package/dist/sources/index.js +34 -0
- package/dist/sources/notion.js +165 -0
- package/dist/sources/onedrive.js +143 -0
- package/dist/sources/web_crawler.js +166 -0
- package/dist/temporal_graph/index.js +20 -0
- package/dist/temporal_graph/query.js +240 -0
- package/dist/temporal_graph/store.js +116 -0
- package/dist/temporal_graph/timeline.js +241 -0
- package/dist/temporal_graph/types.js +2 -0
- package/dist/utils/chunking.js +60 -0
- package/dist/utils/index.js +31 -0
- package/dist/utils/keyword.js +94 -0
- package/dist/utils/text.js +120 -0
- package/nodemon.json +7 -0
- package/package.json +50 -0
- package/references/api_reference.md +66 -0
- package/references/examples.md +45 -0
- package/src/ai/graph.ts +363 -0
- package/src/ai/mcp.ts +494 -0
- package/src/cli.ts +94 -0
- package/src/core/cfg.ts +110 -0
- package/src/core/db.ts +1052 -0
- package/src/core/memory.ts +99 -0
- package/src/core/migrate.ts +302 -0
- package/src/core/models.ts +107 -0
- package/src/core/telemetry.ts +47 -0
- package/src/core/types.ts +130 -0
- package/src/core/vector/postgres.ts +61 -0
- package/src/core/vector/valkey.ts +261 -0
- package/src/core/vector_store.ts +9 -0
- package/src/index.ts +5 -0
- package/src/memory/decay.ts +427 -0
- package/src/memory/embed.ts +707 -0
- package/src/memory/hsg.ts +1245 -0
- package/src/memory/reflect.ts +158 -0
- package/src/memory/user_summary.ts +110 -0
- package/src/migrate.ts +8 -0
- package/src/ops/compress.ts +296 -0
- package/src/ops/dynamics.ts +272 -0
- package/src/ops/extract.ts +360 -0
- package/src/ops/ingest.ts +286 -0
- package/src/server/index.ts +159 -0
- package/src/server/middleware/auth.ts +156 -0
- package/src/server/routes/auth.ts +223 -0
- package/src/server/routes/compression.ts +106 -0
- package/src/server/routes/dashboard.ts +420 -0
- package/src/server/routes/docs.ts +380 -0
- package/src/server/routes/dynamics.ts +516 -0
- package/src/server/routes/ide.ts +283 -0
- package/src/server/routes/index.ts +32 -0
- package/src/server/routes/keys.ts +131 -0
- package/src/server/routes/langgraph.ts +71 -0
- package/src/server/routes/memory.ts +440 -0
- package/src/server/routes/sources.ts +111 -0
- package/src/server/routes/system.ts +68 -0
- package/src/server/routes/temporal.ts +335 -0
- package/src/server/routes/users.ts +111 -0
- package/src/server/routes/vercel.ts +55 -0
- package/src/server/server.js +215 -0
- package/src/server.ts +1 -0
- package/src/sources/base.ts +257 -0
- package/src/sources/github.ts +156 -0
- package/src/sources/google_drive.ts +144 -0
- package/src/sources/google_sheets.ts +85 -0
- package/src/sources/google_slides.ts +115 -0
- package/src/sources/index.ts +19 -0
- package/src/sources/notion.ts +148 -0
- package/src/sources/onedrive.ts +131 -0
- package/src/sources/web_crawler.ts +161 -0
- package/src/temporal_graph/index.ts +4 -0
- package/src/temporal_graph/query.ts +299 -0
- package/src/temporal_graph/store.ts +156 -0
- package/src/temporal_graph/timeline.ts +319 -0
- package/src/temporal_graph/types.ts +41 -0
- package/src/utils/chunking.ts +66 -0
- package/src/utils/index.ts +25 -0
- package/src/utils/keyword.ts +137 -0
- package/src/utils/text.ts +115 -0
- package/tests/test_api_workspace_management.ts +413 -0
- package/tests/test_bulk_delete.ts +267 -0
- package/tests/test_omnibus.ts +166 -0
- package/tests/test_workspace_management.ts +278 -0
- package/tests/verify.ts +104 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_related_facts = exports.search_facts = exports.get_facts_by_subject = exports.find_conflicting_facts = exports.query_facts_in_range = exports.get_current_fact = exports.query_facts_at_time = void 0;
|
|
4
|
+
const db_1 = require("../core/db");
|
|
5
|
+
const query_facts_at_time = async (subject, predicate, object, at = new Date(), min_confidence = 0.1) => {
|
|
6
|
+
const timestamp = at.getTime();
|
|
7
|
+
const conditions = [];
|
|
8
|
+
const params = [];
|
|
9
|
+
// Build WHERE clause
|
|
10
|
+
conditions.push('(valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?))');
|
|
11
|
+
params.push(timestamp, timestamp);
|
|
12
|
+
if (subject) {
|
|
13
|
+
conditions.push('subject = ?');
|
|
14
|
+
params.push(subject);
|
|
15
|
+
}
|
|
16
|
+
if (predicate) {
|
|
17
|
+
conditions.push('predicate = ?');
|
|
18
|
+
params.push(predicate);
|
|
19
|
+
}
|
|
20
|
+
if (object) {
|
|
21
|
+
conditions.push('object = ?');
|
|
22
|
+
params.push(object);
|
|
23
|
+
}
|
|
24
|
+
if (min_confidence > 0) {
|
|
25
|
+
conditions.push('confidence >= ?');
|
|
26
|
+
params.push(min_confidence);
|
|
27
|
+
}
|
|
28
|
+
const sql = `
|
|
29
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
30
|
+
FROM temporal_facts
|
|
31
|
+
WHERE ${conditions.join(' AND ')}
|
|
32
|
+
ORDER BY confidence DESC, valid_from DESC
|
|
33
|
+
`;
|
|
34
|
+
const rows = await (0, db_1.all_async)(sql, params);
|
|
35
|
+
return rows.map(row => ({
|
|
36
|
+
id: row.id,
|
|
37
|
+
subject: row.subject,
|
|
38
|
+
predicate: row.predicate,
|
|
39
|
+
object: row.object,
|
|
40
|
+
valid_from: new Date(row.valid_from),
|
|
41
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
42
|
+
confidence: row.confidence,
|
|
43
|
+
last_updated: new Date(row.last_updated),
|
|
44
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
45
|
+
}));
|
|
46
|
+
};
|
|
47
|
+
exports.query_facts_at_time = query_facts_at_time;
|
|
48
|
+
const get_current_fact = async (subject, predicate) => {
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
const row = await (0, db_1.get_async)(`
|
|
51
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
52
|
+
FROM temporal_facts
|
|
53
|
+
WHERE subject = ? AND predicate = ? AND valid_to IS NULL
|
|
54
|
+
ORDER BY valid_from DESC
|
|
55
|
+
LIMIT 1
|
|
56
|
+
`, [subject, predicate]);
|
|
57
|
+
if (!row)
|
|
58
|
+
return null;
|
|
59
|
+
return {
|
|
60
|
+
id: row.id,
|
|
61
|
+
subject: row.subject,
|
|
62
|
+
predicate: row.predicate,
|
|
63
|
+
object: row.object,
|
|
64
|
+
valid_from: new Date(row.valid_from),
|
|
65
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
66
|
+
confidence: row.confidence,
|
|
67
|
+
last_updated: new Date(row.last_updated),
|
|
68
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
exports.get_current_fact = get_current_fact;
|
|
72
|
+
const query_facts_in_range = async (subject, predicate, from, to, min_confidence = 0.1) => {
|
|
73
|
+
const conditions = [];
|
|
74
|
+
const params = [];
|
|
75
|
+
if (from && to) {
|
|
76
|
+
const from_ts = from.getTime();
|
|
77
|
+
const to_ts = to.getTime();
|
|
78
|
+
conditions.push('((valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?)) OR (valid_from >= ? AND valid_from <= ?))');
|
|
79
|
+
params.push(to_ts, from_ts, from_ts, to_ts);
|
|
80
|
+
}
|
|
81
|
+
else if (from) {
|
|
82
|
+
conditions.push('valid_from >= ?');
|
|
83
|
+
params.push(from.getTime());
|
|
84
|
+
}
|
|
85
|
+
else if (to) {
|
|
86
|
+
conditions.push('valid_from <= ?');
|
|
87
|
+
params.push(to.getTime());
|
|
88
|
+
}
|
|
89
|
+
if (subject) {
|
|
90
|
+
conditions.push('subject = ?');
|
|
91
|
+
params.push(subject);
|
|
92
|
+
}
|
|
93
|
+
if (predicate) {
|
|
94
|
+
conditions.push('predicate = ?');
|
|
95
|
+
params.push(predicate);
|
|
96
|
+
}
|
|
97
|
+
if (min_confidence > 0) {
|
|
98
|
+
conditions.push('confidence >= ?');
|
|
99
|
+
params.push(min_confidence);
|
|
100
|
+
}
|
|
101
|
+
const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
|
|
102
|
+
const sql = `
|
|
103
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
104
|
+
FROM temporal_facts
|
|
105
|
+
${where}
|
|
106
|
+
ORDER BY valid_from DESC
|
|
107
|
+
`;
|
|
108
|
+
const rows = await (0, db_1.all_async)(sql, params);
|
|
109
|
+
return rows.map(row => ({
|
|
110
|
+
id: row.id,
|
|
111
|
+
subject: row.subject,
|
|
112
|
+
predicate: row.predicate,
|
|
113
|
+
object: row.object,
|
|
114
|
+
valid_from: new Date(row.valid_from),
|
|
115
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
116
|
+
confidence: row.confidence,
|
|
117
|
+
last_updated: new Date(row.last_updated),
|
|
118
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
119
|
+
}));
|
|
120
|
+
};
|
|
121
|
+
exports.query_facts_in_range = query_facts_in_range;
|
|
122
|
+
const find_conflicting_facts = async (subject, predicate, at) => {
|
|
123
|
+
const timestamp = at ? at.getTime() : Date.now();
|
|
124
|
+
const rows = await (0, db_1.all_async)(`
|
|
125
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
126
|
+
FROM temporal_facts
|
|
127
|
+
WHERE subject = ? AND predicate = ?
|
|
128
|
+
AND (valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?))
|
|
129
|
+
ORDER BY confidence DESC
|
|
130
|
+
`, [subject, predicate, timestamp, timestamp]);
|
|
131
|
+
return rows.map(row => ({
|
|
132
|
+
id: row.id,
|
|
133
|
+
subject: row.subject,
|
|
134
|
+
predicate: row.predicate,
|
|
135
|
+
object: row.object,
|
|
136
|
+
valid_from: new Date(row.valid_from),
|
|
137
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
138
|
+
confidence: row.confidence,
|
|
139
|
+
last_updated: new Date(row.last_updated),
|
|
140
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
141
|
+
}));
|
|
142
|
+
};
|
|
143
|
+
exports.find_conflicting_facts = find_conflicting_facts;
|
|
144
|
+
const get_facts_by_subject = async (subject, at, include_historical = false) => {
|
|
145
|
+
let sql;
|
|
146
|
+
let params;
|
|
147
|
+
if (include_historical) {
|
|
148
|
+
sql = `
|
|
149
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
150
|
+
FROM temporal_facts
|
|
151
|
+
WHERE subject = ?
|
|
152
|
+
ORDER BY predicate ASC, valid_from DESC
|
|
153
|
+
`;
|
|
154
|
+
params = [subject];
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const timestamp = at ? at.getTime() : Date.now();
|
|
158
|
+
sql = `
|
|
159
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
160
|
+
FROM temporal_facts
|
|
161
|
+
WHERE subject = ?
|
|
162
|
+
AND (valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?))
|
|
163
|
+
ORDER BY predicate ASC, confidence DESC
|
|
164
|
+
`;
|
|
165
|
+
params = [subject, timestamp, timestamp];
|
|
166
|
+
}
|
|
167
|
+
const rows = await (0, db_1.all_async)(sql, params);
|
|
168
|
+
return rows.map(row => ({
|
|
169
|
+
id: row.id,
|
|
170
|
+
subject: row.subject,
|
|
171
|
+
predicate: row.predicate,
|
|
172
|
+
object: row.object,
|
|
173
|
+
valid_from: new Date(row.valid_from),
|
|
174
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
175
|
+
confidence: row.confidence,
|
|
176
|
+
last_updated: new Date(row.last_updated),
|
|
177
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
178
|
+
}));
|
|
179
|
+
};
|
|
180
|
+
exports.get_facts_by_subject = get_facts_by_subject;
|
|
181
|
+
const search_facts = async (pattern, field = 'subject', at) => {
|
|
182
|
+
const timestamp = at ? at.getTime() : Date.now();
|
|
183
|
+
const search_pattern = `%${pattern}%`;
|
|
184
|
+
const sql = `
|
|
185
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
186
|
+
FROM temporal_facts
|
|
187
|
+
WHERE ${field} LIKE ?
|
|
188
|
+
AND (valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?))
|
|
189
|
+
ORDER BY confidence DESC, valid_from DESC
|
|
190
|
+
LIMIT 100
|
|
191
|
+
`;
|
|
192
|
+
const rows = await (0, db_1.all_async)(sql, [search_pattern, timestamp, timestamp]);
|
|
193
|
+
return rows.map(row => ({
|
|
194
|
+
id: row.id,
|
|
195
|
+
subject: row.subject,
|
|
196
|
+
predicate: row.predicate,
|
|
197
|
+
object: row.object,
|
|
198
|
+
valid_from: new Date(row.valid_from),
|
|
199
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
200
|
+
confidence: row.confidence,
|
|
201
|
+
last_updated: new Date(row.last_updated),
|
|
202
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
203
|
+
}));
|
|
204
|
+
};
|
|
205
|
+
exports.search_facts = search_facts;
|
|
206
|
+
const get_related_facts = async (fact_id, relation_type, at) => {
|
|
207
|
+
const timestamp = at ? at.getTime() : Date.now();
|
|
208
|
+
const conditions = ['(e.valid_from <= ? AND (e.valid_to IS NULL OR e.valid_to >= ?))'];
|
|
209
|
+
const params = [timestamp, timestamp];
|
|
210
|
+
if (relation_type) {
|
|
211
|
+
conditions.push('e.relation_type = ?');
|
|
212
|
+
params.push(relation_type);
|
|
213
|
+
}
|
|
214
|
+
const sql = `
|
|
215
|
+
SELECT f.*, e.relation_type, e.weight
|
|
216
|
+
FROM temporal_edges e
|
|
217
|
+
JOIN temporal_facts f ON e.target_id = f.id
|
|
218
|
+
WHERE e.source_id = ?
|
|
219
|
+
AND ${conditions.join(' AND ')}
|
|
220
|
+
AND (f.valid_from <= ? AND (f.valid_to IS NULL OR f.valid_to >= ?))
|
|
221
|
+
ORDER BY e.weight DESC, f.confidence DESC
|
|
222
|
+
`;
|
|
223
|
+
const rows = await (0, db_1.all_async)(sql, [fact_id, ...params, timestamp, timestamp]);
|
|
224
|
+
return rows.map(row => ({
|
|
225
|
+
fact: {
|
|
226
|
+
id: row.id,
|
|
227
|
+
subject: row.subject,
|
|
228
|
+
predicate: row.predicate,
|
|
229
|
+
object: row.object,
|
|
230
|
+
valid_from: new Date(row.valid_from),
|
|
231
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
232
|
+
confidence: row.confidence,
|
|
233
|
+
last_updated: new Date(row.last_updated),
|
|
234
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
235
|
+
},
|
|
236
|
+
relation: row.relation_type,
|
|
237
|
+
weight: row.weight
|
|
238
|
+
}));
|
|
239
|
+
};
|
|
240
|
+
exports.get_related_facts = get_related_facts;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_total_facts_count = exports.get_active_facts_count = exports.apply_confidence_decay = exports.batch_insert_facts = exports.invalidate_edge = exports.insert_edge = exports.delete_fact = exports.invalidate_fact = exports.update_fact = exports.insert_fact = void 0;
|
|
4
|
+
const db_1 = require("../core/db");
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const insert_fact = async (subject, predicate, object, valid_from = new Date(), confidence = 1.0, metadata) => {
|
|
7
|
+
const id = (0, crypto_1.randomUUID)();
|
|
8
|
+
const now = Date.now();
|
|
9
|
+
const valid_from_ts = valid_from.getTime();
|
|
10
|
+
const existing = await (0, db_1.all_async)(`
|
|
11
|
+
SELECT id, valid_from FROM temporal_facts
|
|
12
|
+
WHERE subject = ? AND predicate = ? AND valid_to IS NULL
|
|
13
|
+
ORDER BY valid_from DESC
|
|
14
|
+
`, [subject, predicate]);
|
|
15
|
+
for (const old of existing) {
|
|
16
|
+
if (old.valid_from < valid_from_ts) {
|
|
17
|
+
await (0, db_1.run_async)(`UPDATE temporal_facts SET valid_to = ? WHERE id = ?`, [valid_from_ts - 1, old.id]);
|
|
18
|
+
console.error(`[TEMPORAL] Closed fact ${old.id} at ${new Date(valid_from_ts - 1).toISOString()}`); // Use stderr for MCP compatibility
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
await (0, db_1.run_async)(`
|
|
22
|
+
INSERT INTO temporal_facts (id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata)
|
|
23
|
+
VALUES (?, ?, ?, ?, ?, NULL, ?, ?, ?)
|
|
24
|
+
`, [id, subject, predicate, object, valid_from_ts, confidence, now, metadata ? JSON.stringify(metadata) : null]);
|
|
25
|
+
console.error(`[TEMPORAL] Inserted fact: ${subject} ${predicate} ${object} (from ${valid_from.toISOString()}, confidence=${confidence})`); // Use stderr for MCP compatibility
|
|
26
|
+
return id;
|
|
27
|
+
};
|
|
28
|
+
exports.insert_fact = insert_fact;
|
|
29
|
+
const update_fact = async (id, confidence, metadata) => {
|
|
30
|
+
const updates = [];
|
|
31
|
+
const params = [];
|
|
32
|
+
if (confidence !== undefined) {
|
|
33
|
+
updates.push('confidence = ?');
|
|
34
|
+
params.push(confidence);
|
|
35
|
+
}
|
|
36
|
+
if (metadata !== undefined) {
|
|
37
|
+
updates.push('metadata = ?');
|
|
38
|
+
params.push(JSON.stringify(metadata));
|
|
39
|
+
}
|
|
40
|
+
updates.push('last_updated = ?');
|
|
41
|
+
params.push(Date.now());
|
|
42
|
+
params.push(id);
|
|
43
|
+
if (updates.length > 0) {
|
|
44
|
+
await (0, db_1.run_async)(`UPDATE temporal_facts SET ${updates.join(', ')} WHERE id = ?`, params);
|
|
45
|
+
console.error(`[TEMPORAL] Updated fact ${id}`); // Use stderr for MCP compatibility
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.update_fact = update_fact;
|
|
49
|
+
const invalidate_fact = async (id, valid_to = new Date()) => {
|
|
50
|
+
await (0, db_1.run_async)(`UPDATE temporal_facts SET valid_to = ?, last_updated = ? WHERE id = ?`, [valid_to.getTime(), Date.now(), id]);
|
|
51
|
+
console.error(`[TEMPORAL] Invalidated fact ${id} at ${valid_to.toISOString()}`); // Use stderr for MCP compatibility
|
|
52
|
+
};
|
|
53
|
+
exports.invalidate_fact = invalidate_fact;
|
|
54
|
+
const delete_fact = async (id) => {
|
|
55
|
+
await (0, db_1.run_async)(`DELETE FROM temporal_facts WHERE id = ?`, [id]);
|
|
56
|
+
console.error(`[TEMPORAL] Deleted fact ${id}`); // Use stderr for MCP compatibility
|
|
57
|
+
};
|
|
58
|
+
exports.delete_fact = delete_fact;
|
|
59
|
+
const insert_edge = async (source_id, target_id, relation_type, valid_from = new Date(), weight = 1.0, metadata) => {
|
|
60
|
+
const id = (0, crypto_1.randomUUID)();
|
|
61
|
+
const valid_from_ts = valid_from.getTime();
|
|
62
|
+
await (0, db_1.run_async)(`
|
|
63
|
+
INSERT INTO temporal_edges (id, source_id, target_id, relation_type, valid_from, valid_to, weight, metadata)
|
|
64
|
+
VALUES (?, ?, ?, ?, ?, NULL, ?, ?)
|
|
65
|
+
`, [id, source_id, target_id, relation_type, valid_from_ts, weight, metadata ? JSON.stringify(metadata) : null]);
|
|
66
|
+
console.log(`[TEMPORAL] Created edge: ${source_id} --[${relation_type}]--> ${target_id}`);
|
|
67
|
+
return id;
|
|
68
|
+
};
|
|
69
|
+
exports.insert_edge = insert_edge;
|
|
70
|
+
const invalidate_edge = async (id, valid_to = new Date()) => {
|
|
71
|
+
await (0, db_1.run_async)(`UPDATE temporal_edges SET valid_to = ? WHERE id = ?`, [valid_to.getTime(), id]);
|
|
72
|
+
console.log(`[TEMPORAL] Invalidated edge ${id}`);
|
|
73
|
+
};
|
|
74
|
+
exports.invalidate_edge = invalidate_edge;
|
|
75
|
+
const batch_insert_facts = async (facts) => {
|
|
76
|
+
const ids = [];
|
|
77
|
+
await (0, db_1.run_async)('BEGIN TRANSACTION');
|
|
78
|
+
try {
|
|
79
|
+
for (const fact of facts) {
|
|
80
|
+
const id = await (0, exports.insert_fact)(fact.subject, fact.predicate, fact.object, fact.valid_from, fact.confidence, fact.metadata);
|
|
81
|
+
ids.push(id);
|
|
82
|
+
}
|
|
83
|
+
await (0, db_1.run_async)('COMMIT');
|
|
84
|
+
console.log(`[TEMPORAL] Batch inserted ${ids.length} facts`);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
await (0, db_1.run_async)('ROLLBACK');
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
return ids;
|
|
91
|
+
};
|
|
92
|
+
exports.batch_insert_facts = batch_insert_facts;
|
|
93
|
+
const apply_confidence_decay = async (decay_rate = 0.01) => {
|
|
94
|
+
const now = Date.now();
|
|
95
|
+
const one_day = 86400000;
|
|
96
|
+
await (0, db_1.run_async)(`
|
|
97
|
+
UPDATE temporal_facts
|
|
98
|
+
SET confidence = MAX(0.1, confidence * (1 - ? * ((? - valid_from) / ?)))
|
|
99
|
+
WHERE valid_to IS NULL AND confidence > 0.1
|
|
100
|
+
`, [decay_rate, now, one_day]);
|
|
101
|
+
const result = await (0, db_1.get_async)(`SELECT changes() as changes`);
|
|
102
|
+
const changes = result?.changes || 0;
|
|
103
|
+
console.log(`[TEMPORAL] Applied confidence decay to ${changes} facts`);
|
|
104
|
+
return changes;
|
|
105
|
+
};
|
|
106
|
+
exports.apply_confidence_decay = apply_confidence_decay;
|
|
107
|
+
const get_active_facts_count = async () => {
|
|
108
|
+
const result = await (0, db_1.get_async)(`SELECT COUNT(*) as count FROM temporal_facts WHERE valid_to IS NULL`);
|
|
109
|
+
return result?.count || 0;
|
|
110
|
+
};
|
|
111
|
+
exports.get_active_facts_count = get_active_facts_count;
|
|
112
|
+
const get_total_facts_count = async () => {
|
|
113
|
+
const result = await (0, db_1.get_async)(`SELECT COUNT(*) as count FROM temporal_facts`);
|
|
114
|
+
return result?.count || 0;
|
|
115
|
+
};
|
|
116
|
+
exports.get_total_facts_count = get_total_facts_count;
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_volatile_facts = exports.get_change_frequency = exports.compare_time_points = exports.get_changes_in_window = exports.get_predicate_timeline = exports.get_subject_timeline = void 0;
|
|
4
|
+
const db_1 = require("../core/db");
|
|
5
|
+
const get_subject_timeline = async (subject, predicate) => {
|
|
6
|
+
const conditions = ['subject = ?'];
|
|
7
|
+
const params = [subject];
|
|
8
|
+
if (predicate) {
|
|
9
|
+
conditions.push('predicate = ?');
|
|
10
|
+
params.push(predicate);
|
|
11
|
+
}
|
|
12
|
+
const sql = `
|
|
13
|
+
SELECT subject, predicate, object, confidence, valid_from, valid_to
|
|
14
|
+
FROM temporal_facts
|
|
15
|
+
WHERE ${conditions.join(' AND ')}
|
|
16
|
+
ORDER BY valid_from ASC
|
|
17
|
+
`;
|
|
18
|
+
const rows = await (0, db_1.all_async)(sql, params);
|
|
19
|
+
const timeline = [];
|
|
20
|
+
for (const row of rows) {
|
|
21
|
+
// Creation event
|
|
22
|
+
timeline.push({
|
|
23
|
+
timestamp: new Date(row.valid_from),
|
|
24
|
+
subject: row.subject,
|
|
25
|
+
predicate: row.predicate,
|
|
26
|
+
object: row.object,
|
|
27
|
+
confidence: row.confidence,
|
|
28
|
+
change_type: 'created'
|
|
29
|
+
});
|
|
30
|
+
// Invalidation event (if applicable)
|
|
31
|
+
if (row.valid_to) {
|
|
32
|
+
timeline.push({
|
|
33
|
+
timestamp: new Date(row.valid_to),
|
|
34
|
+
subject: row.subject,
|
|
35
|
+
predicate: row.predicate,
|
|
36
|
+
object: row.object,
|
|
37
|
+
confidence: row.confidence,
|
|
38
|
+
change_type: 'invalidated'
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return timeline.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
43
|
+
};
|
|
44
|
+
exports.get_subject_timeline = get_subject_timeline;
|
|
45
|
+
const get_predicate_timeline = async (predicate, from, to) => {
|
|
46
|
+
const conditions = ['predicate = ?'];
|
|
47
|
+
const params = [predicate];
|
|
48
|
+
if (from) {
|
|
49
|
+
conditions.push('valid_from >= ?');
|
|
50
|
+
params.push(from.getTime());
|
|
51
|
+
}
|
|
52
|
+
if (to) {
|
|
53
|
+
conditions.push('valid_from <= ?');
|
|
54
|
+
params.push(to.getTime());
|
|
55
|
+
}
|
|
56
|
+
const sql = `
|
|
57
|
+
SELECT subject, predicate, object, confidence, valid_from, valid_to
|
|
58
|
+
FROM temporal_facts
|
|
59
|
+
WHERE ${conditions.join(' AND ')}
|
|
60
|
+
ORDER BY valid_from ASC
|
|
61
|
+
`;
|
|
62
|
+
const rows = await (0, db_1.all_async)(sql, params);
|
|
63
|
+
const timeline = [];
|
|
64
|
+
for (const row of rows) {
|
|
65
|
+
timeline.push({
|
|
66
|
+
timestamp: new Date(row.valid_from),
|
|
67
|
+
subject: row.subject,
|
|
68
|
+
predicate: row.predicate,
|
|
69
|
+
object: row.object,
|
|
70
|
+
confidence: row.confidence,
|
|
71
|
+
change_type: 'created'
|
|
72
|
+
});
|
|
73
|
+
if (row.valid_to) {
|
|
74
|
+
timeline.push({
|
|
75
|
+
timestamp: new Date(row.valid_to),
|
|
76
|
+
subject: row.subject,
|
|
77
|
+
predicate: row.predicate,
|
|
78
|
+
object: row.object,
|
|
79
|
+
confidence: row.confidence,
|
|
80
|
+
change_type: 'invalidated'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return timeline.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
85
|
+
};
|
|
86
|
+
exports.get_predicate_timeline = get_predicate_timeline;
|
|
87
|
+
const get_changes_in_window = async (from, to, subject) => {
|
|
88
|
+
const from_ts = from.getTime();
|
|
89
|
+
const to_ts = to.getTime();
|
|
90
|
+
const conditions = [];
|
|
91
|
+
const params = [];
|
|
92
|
+
if (subject) {
|
|
93
|
+
conditions.push('subject = ?');
|
|
94
|
+
params.push(subject);
|
|
95
|
+
}
|
|
96
|
+
const where = conditions.length > 0 ? `AND ${conditions.join(' AND ')}` : '';
|
|
97
|
+
const sql = `
|
|
98
|
+
SELECT subject, predicate, object, confidence, valid_from, valid_to
|
|
99
|
+
FROM temporal_facts
|
|
100
|
+
WHERE ((valid_from >= ? AND valid_from <= ?) OR (valid_to >= ? AND valid_to <= ?))
|
|
101
|
+
${where}
|
|
102
|
+
ORDER BY valid_from ASC
|
|
103
|
+
`;
|
|
104
|
+
const rows = await (0, db_1.all_async)(sql, [from_ts, to_ts, from_ts, to_ts, ...params]);
|
|
105
|
+
const timeline = [];
|
|
106
|
+
for (const row of rows) {
|
|
107
|
+
if (row.valid_from >= from_ts && row.valid_from <= to_ts) {
|
|
108
|
+
timeline.push({
|
|
109
|
+
timestamp: new Date(row.valid_from),
|
|
110
|
+
subject: row.subject,
|
|
111
|
+
predicate: row.predicate,
|
|
112
|
+
object: row.object,
|
|
113
|
+
confidence: row.confidence,
|
|
114
|
+
change_type: 'created'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (row.valid_to && row.valid_to >= from_ts && row.valid_to <= to_ts) {
|
|
118
|
+
timeline.push({
|
|
119
|
+
timestamp: new Date(row.valid_to),
|
|
120
|
+
subject: row.subject,
|
|
121
|
+
predicate: row.predicate,
|
|
122
|
+
object: row.object,
|
|
123
|
+
confidence: row.confidence,
|
|
124
|
+
change_type: 'invalidated'
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return timeline.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
|
|
129
|
+
};
|
|
130
|
+
exports.get_changes_in_window = get_changes_in_window;
|
|
131
|
+
const compare_time_points = async (subject, time1, time2) => {
|
|
132
|
+
const t1_ts = time1.getTime();
|
|
133
|
+
const t2_ts = time2.getTime();
|
|
134
|
+
// Get all facts for subject at both times
|
|
135
|
+
const facts_t1 = await (0, db_1.all_async)(`
|
|
136
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
137
|
+
FROM temporal_facts
|
|
138
|
+
WHERE subject = ?
|
|
139
|
+
AND valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?)
|
|
140
|
+
`, [subject, t1_ts, t1_ts]);
|
|
141
|
+
const facts_t2 = await (0, db_1.all_async)(`
|
|
142
|
+
SELECT id, subject, predicate, object, valid_from, valid_to, confidence, last_updated, metadata
|
|
143
|
+
FROM temporal_facts
|
|
144
|
+
WHERE subject = ?
|
|
145
|
+
AND valid_from <= ? AND (valid_to IS NULL OR valid_to >= ?)
|
|
146
|
+
`, [subject, t2_ts, t2_ts]);
|
|
147
|
+
const map_t1 = new Map();
|
|
148
|
+
const map_t2 = new Map();
|
|
149
|
+
for (const f of facts_t1) {
|
|
150
|
+
map_t1.set(f.predicate, f);
|
|
151
|
+
}
|
|
152
|
+
for (const f of facts_t2) {
|
|
153
|
+
map_t2.set(f.predicate, f);
|
|
154
|
+
}
|
|
155
|
+
const added = [];
|
|
156
|
+
const removed = [];
|
|
157
|
+
const changed = [];
|
|
158
|
+
const unchanged = [];
|
|
159
|
+
// Find added and changed
|
|
160
|
+
for (const [pred, fact2] of map_t2) {
|
|
161
|
+
const fact1 = map_t1.get(pred);
|
|
162
|
+
if (!fact1) {
|
|
163
|
+
added.push(row_to_fact(fact2));
|
|
164
|
+
}
|
|
165
|
+
else if (fact1.object !== fact2.object || fact1.id !== fact2.id) {
|
|
166
|
+
changed.push({
|
|
167
|
+
before: row_to_fact(fact1),
|
|
168
|
+
after: row_to_fact(fact2)
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
unchanged.push(row_to_fact(fact2));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Find removed
|
|
176
|
+
for (const [pred, fact1] of map_t1) {
|
|
177
|
+
if (!map_t2.has(pred)) {
|
|
178
|
+
removed.push(row_to_fact(fact1));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return { added, removed, changed, unchanged };
|
|
182
|
+
};
|
|
183
|
+
exports.compare_time_points = compare_time_points;
|
|
184
|
+
const get_change_frequency = async (subject, predicate, window_days = 30) => {
|
|
185
|
+
const now = Date.now();
|
|
186
|
+
const window_start = now - (window_days * 86400000);
|
|
187
|
+
const rows = await (0, db_1.all_async)(`
|
|
188
|
+
SELECT valid_from, valid_to
|
|
189
|
+
FROM temporal_facts
|
|
190
|
+
WHERE subject = ? AND predicate = ?
|
|
191
|
+
AND valid_from >= ?
|
|
192
|
+
ORDER BY valid_from ASC
|
|
193
|
+
`, [subject, predicate, window_start]);
|
|
194
|
+
const total_changes = rows.length;
|
|
195
|
+
let total_duration = 0;
|
|
196
|
+
let valid_durations = 0;
|
|
197
|
+
for (const row of rows) {
|
|
198
|
+
if (row.valid_to) {
|
|
199
|
+
total_duration += row.valid_to - row.valid_from;
|
|
200
|
+
valid_durations++;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const avg_duration_ms = valid_durations > 0 ? total_duration / valid_durations : 0;
|
|
204
|
+
const change_rate_per_day = total_changes / window_days;
|
|
205
|
+
return {
|
|
206
|
+
predicate,
|
|
207
|
+
total_changes,
|
|
208
|
+
avg_duration_ms,
|
|
209
|
+
change_rate_per_day
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
exports.get_change_frequency = get_change_frequency;
|
|
213
|
+
const get_volatile_facts = async (subject, limit = 10) => {
|
|
214
|
+
const where = subject ? 'WHERE subject = ?' : '';
|
|
215
|
+
const params = subject ? [subject] : [];
|
|
216
|
+
const sql = `
|
|
217
|
+
SELECT subject, predicate, COUNT(*) as change_count, AVG(confidence) as avg_confidence
|
|
218
|
+
FROM temporal_facts
|
|
219
|
+
${where}
|
|
220
|
+
GROUP BY subject, predicate
|
|
221
|
+
HAVING change_count > 1
|
|
222
|
+
ORDER BY change_count DESC, avg_confidence ASC
|
|
223
|
+
LIMIT ?
|
|
224
|
+
`;
|
|
225
|
+
return await (0, db_1.all_async)(sql, [...params, limit]);
|
|
226
|
+
};
|
|
227
|
+
exports.get_volatile_facts = get_volatile_facts;
|
|
228
|
+
// Helper function
|
|
229
|
+
function row_to_fact(row) {
|
|
230
|
+
return {
|
|
231
|
+
id: row.id,
|
|
232
|
+
subject: row.subject,
|
|
233
|
+
predicate: row.predicate,
|
|
234
|
+
object: row.object,
|
|
235
|
+
valid_from: new Date(row.valid_from),
|
|
236
|
+
valid_to: row.valid_to ? new Date(row.valid_to) : null,
|
|
237
|
+
confidence: row.confidence,
|
|
238
|
+
last_updated: new Date(row.last_updated),
|
|
239
|
+
metadata: row.metadata ? JSON.parse(row.metadata) : undefined
|
|
240
|
+
};
|
|
241
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.join_chunks = exports.agg_vec = exports.chunk_text = void 0;
|
|
4
|
+
const cpt = 4;
|
|
5
|
+
const est = (t) => Math.ceil(t.length / cpt);
|
|
6
|
+
const chunk_text = (txt, tgt = 768, ovr = 0.1) => {
|
|
7
|
+
const tot = est(txt);
|
|
8
|
+
if (tot <= tgt)
|
|
9
|
+
return [{ text: txt, start: 0, end: txt.length, tokens: tot }];
|
|
10
|
+
const tch = tgt * cpt, och = Math.floor(tch * ovr);
|
|
11
|
+
const paras = txt.split(/\n\n+/);
|
|
12
|
+
const chks = [];
|
|
13
|
+
let cur = "", cs = 0;
|
|
14
|
+
for (const p of paras) {
|
|
15
|
+
const sents = p.split(/(?<=[.!?])\s+/);
|
|
16
|
+
for (const s of sents) {
|
|
17
|
+
const pot = cur + (cur ? " " : "") + s;
|
|
18
|
+
if (pot.length > tch && cur.length > 0) {
|
|
19
|
+
chks.push({
|
|
20
|
+
text: cur,
|
|
21
|
+
start: cs,
|
|
22
|
+
end: cs + cur.length,
|
|
23
|
+
tokens: est(cur),
|
|
24
|
+
});
|
|
25
|
+
const ovt = cur.slice(-och);
|
|
26
|
+
cur = ovt + " " + s;
|
|
27
|
+
cs = cs + cur.length - ovt.length - 1;
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
cur = pot;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (cur.length > 0)
|
|
34
|
+
chks.push({
|
|
35
|
+
text: cur,
|
|
36
|
+
start: cs,
|
|
37
|
+
end: cs + cur.length,
|
|
38
|
+
tokens: est(cur),
|
|
39
|
+
});
|
|
40
|
+
return chks;
|
|
41
|
+
};
|
|
42
|
+
exports.chunk_text = chunk_text;
|
|
43
|
+
const agg_vec = (vecs) => {
|
|
44
|
+
const n = vecs.length;
|
|
45
|
+
if (!n)
|
|
46
|
+
throw new Error("no vecs");
|
|
47
|
+
if (n === 1)
|
|
48
|
+
return vecs[0].slice();
|
|
49
|
+
const d = vecs[0].length, r = new Array(d).fill(0);
|
|
50
|
+
for (const v of vecs)
|
|
51
|
+
for (let i = 0; i < d; i++)
|
|
52
|
+
r[i] += v[i];
|
|
53
|
+
const rc = 1 / n;
|
|
54
|
+
for (let i = 0; i < d; i++)
|
|
55
|
+
r[i] *= rc;
|
|
56
|
+
return r;
|
|
57
|
+
};
|
|
58
|
+
exports.agg_vec = agg_vec;
|
|
59
|
+
const join_chunks = (cks) => cks.length ? cks.map((c) => c.text).join(" ") : "";
|
|
60
|
+
exports.join_chunks = join_chunks;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buf_to_vec = exports.vec_to_buf = exports.p = exports.j = exports.cos_sim = exports.rid = exports.now = void 0;
|
|
4
|
+
const now = () => Date.now();
|
|
5
|
+
exports.now = now;
|
|
6
|
+
const rid = () => crypto.randomUUID();
|
|
7
|
+
exports.rid = rid;
|
|
8
|
+
const cos_sim = (a, b) => {
|
|
9
|
+
let dot = 0, na = 0, nb = 0;
|
|
10
|
+
for (let i = 0; i < a.length; i++) {
|
|
11
|
+
const x = a[i], y = b[i];
|
|
12
|
+
dot += x * y;
|
|
13
|
+
na += x * x;
|
|
14
|
+
nb += y * y;
|
|
15
|
+
}
|
|
16
|
+
const d = Math.sqrt(na) * Math.sqrt(nb);
|
|
17
|
+
return d ? dot / d : 0;
|
|
18
|
+
};
|
|
19
|
+
exports.cos_sim = cos_sim;
|
|
20
|
+
exports.j = JSON.stringify;
|
|
21
|
+
const p = (x) => JSON.parse(x);
|
|
22
|
+
exports.p = p;
|
|
23
|
+
const vec_to_buf = (v) => {
|
|
24
|
+
const f32 = new Float32Array(v);
|
|
25
|
+
return Buffer.from(f32.buffer);
|
|
26
|
+
};
|
|
27
|
+
exports.vec_to_buf = vec_to_buf;
|
|
28
|
+
const buf_to_vec = (buf) => {
|
|
29
|
+
return new Float32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);
|
|
30
|
+
};
|
|
31
|
+
exports.buf_to_vec = buf_to_vec;
|