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,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.get_most_volatile = exports.compare_facts = exports.apply_decay = exports.get_temporal_stats = exports.search_temporal_facts = exports.get_subject_facts = exports.invalidate_temporal_fact = exports.update_temporal_fact = exports.get_predicate_history = exports.get_entity_timeline = exports.get_current_temporal_fact = exports.get_temporal_fact = exports.create_temporal_fact = void 0;
|
|
4
|
+
exports.temporal = temporal;
|
|
5
|
+
const store_1 = require("../../temporal_graph/store");
|
|
6
|
+
const query_1 = require("../../temporal_graph/query");
|
|
7
|
+
const timeline_1 = require("../../temporal_graph/timeline");
|
|
8
|
+
const create_temporal_fact = async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const { subject, predicate, object, valid_from, confidence, metadata } = req.body;
|
|
11
|
+
if (!subject || !predicate || !object) {
|
|
12
|
+
return res.status(400).json({ error: 'Missing required fields: subject, predicate, object' });
|
|
13
|
+
}
|
|
14
|
+
const valid_from_date = valid_from ? new Date(valid_from) : new Date();
|
|
15
|
+
const conf = confidence !== undefined ? Math.max(0, Math.min(1, confidence)) : 1.0;
|
|
16
|
+
const id = await (0, store_1.insert_fact)(subject, predicate, object, valid_from_date, conf, metadata);
|
|
17
|
+
res.json({
|
|
18
|
+
id,
|
|
19
|
+
subject,
|
|
20
|
+
predicate,
|
|
21
|
+
object,
|
|
22
|
+
valid_from: valid_from_date.toISOString(),
|
|
23
|
+
confidence: conf,
|
|
24
|
+
message: 'Fact created successfully'
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
console.error('[TEMPORAL API] Error creating fact:', error);
|
|
29
|
+
res.status(500).json({ error: 'Failed to create fact' });
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.create_temporal_fact = create_temporal_fact;
|
|
33
|
+
const get_temporal_fact = async (req, res) => {
|
|
34
|
+
try {
|
|
35
|
+
const { subject, predicate, object, at, min_confidence } = req.query;
|
|
36
|
+
if (!subject && !predicate && !object) {
|
|
37
|
+
return res.status(400).json({ error: 'At least one of subject, predicate, or object is required' });
|
|
38
|
+
}
|
|
39
|
+
const at_date = at ? new Date(at) : new Date();
|
|
40
|
+
const min_conf = min_confidence ? parseFloat(min_confidence) : 0.1;
|
|
41
|
+
const facts = await (0, query_1.query_facts_at_time)(subject, predicate, object, at_date, min_conf);
|
|
42
|
+
res.json({
|
|
43
|
+
facts,
|
|
44
|
+
query: { subject, predicate, object, at: at_date.toISOString(), min_confidence: min_conf },
|
|
45
|
+
count: facts.length
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('[TEMPORAL API] Error querying facts:', error);
|
|
50
|
+
res.status(500).json({ error: 'Failed to query facts' });
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.get_temporal_fact = get_temporal_fact;
|
|
54
|
+
const get_current_temporal_fact = async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
const { subject, predicate } = req.query;
|
|
57
|
+
if (!subject || !predicate) {
|
|
58
|
+
return res.status(400).json({ error: 'Both subject and predicate are required' });
|
|
59
|
+
}
|
|
60
|
+
const fact = await (0, query_1.get_current_fact)(subject, predicate);
|
|
61
|
+
if (!fact) {
|
|
62
|
+
return res.status(404).json({ error: 'No current fact found', subject, predicate });
|
|
63
|
+
}
|
|
64
|
+
res.json({ fact });
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error('[TEMPORAL API] Error getting current fact:', error);
|
|
68
|
+
res.status(500).json({ error: 'Failed to get current fact' });
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
exports.get_current_temporal_fact = get_current_temporal_fact;
|
|
72
|
+
const get_entity_timeline = async (req, res) => {
|
|
73
|
+
try {
|
|
74
|
+
const { subject, predicate } = req.query;
|
|
75
|
+
if (!subject) {
|
|
76
|
+
return res.status(400).json({ error: 'Subject parameter is required' });
|
|
77
|
+
}
|
|
78
|
+
const timeline = await (0, timeline_1.get_subject_timeline)(subject, predicate);
|
|
79
|
+
res.json({
|
|
80
|
+
subject,
|
|
81
|
+
predicate,
|
|
82
|
+
timeline,
|
|
83
|
+
count: timeline.length
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
console.error('[TEMPORAL API] Error getting timeline:', error);
|
|
88
|
+
res.status(500).json({ error: 'Failed to get timeline' });
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
exports.get_entity_timeline = get_entity_timeline;
|
|
92
|
+
const get_predicate_history = async (req, res) => {
|
|
93
|
+
try {
|
|
94
|
+
const { predicate, from, to } = req.query;
|
|
95
|
+
if (!predicate) {
|
|
96
|
+
return res.status(400).json({ error: 'Predicate parameter is required' });
|
|
97
|
+
}
|
|
98
|
+
const from_date = from ? new Date(from) : undefined;
|
|
99
|
+
const to_date = to ? new Date(to) : undefined;
|
|
100
|
+
const timeline = await (0, timeline_1.get_predicate_timeline)(predicate, from_date, to_date);
|
|
101
|
+
res.json({
|
|
102
|
+
predicate,
|
|
103
|
+
from: from_date?.toISOString(),
|
|
104
|
+
to: to_date?.toISOString(),
|
|
105
|
+
timeline,
|
|
106
|
+
count: timeline.length
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error('[TEMPORAL API] Error getting predicate timeline:', error);
|
|
111
|
+
res.status(500).json({ error: 'Failed to get predicate timeline' });
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.get_predicate_history = get_predicate_history;
|
|
115
|
+
const update_temporal_fact = async (req, res) => {
|
|
116
|
+
try {
|
|
117
|
+
const { id } = req.params;
|
|
118
|
+
const { confidence, metadata } = req.body;
|
|
119
|
+
if (!id) {
|
|
120
|
+
return res.status(400).json({ error: 'Fact ID is required' });
|
|
121
|
+
}
|
|
122
|
+
if (confidence === undefined && metadata === undefined) {
|
|
123
|
+
return res.status(400).json({ error: 'At least one of confidence or metadata must be provided' });
|
|
124
|
+
}
|
|
125
|
+
const conf = confidence !== undefined ? Math.max(0, Math.min(1, confidence)) : undefined;
|
|
126
|
+
await (0, store_1.update_fact)(id, conf, metadata);
|
|
127
|
+
res.json({ id, confidence: conf, metadata, message: 'Fact updated successfully' });
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error('[TEMPORAL API] Error updating fact:', error);
|
|
131
|
+
res.status(500).json({ error: 'Failed to update fact' });
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
exports.update_temporal_fact = update_temporal_fact;
|
|
135
|
+
const invalidate_temporal_fact = async (req, res) => {
|
|
136
|
+
try {
|
|
137
|
+
const { id } = req.params;
|
|
138
|
+
const { valid_to } = req.body;
|
|
139
|
+
if (!id) {
|
|
140
|
+
return res.status(400).json({ error: 'Fact ID is required' });
|
|
141
|
+
}
|
|
142
|
+
const valid_to_date = valid_to ? new Date(valid_to) : new Date();
|
|
143
|
+
await (0, store_1.invalidate_fact)(id, valid_to_date);
|
|
144
|
+
res.json({ id, valid_to: valid_to_date.toISOString(), message: 'Fact invalidated successfully' });
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.error('[TEMPORAL API] Error invalidating fact:', error);
|
|
148
|
+
res.status(500).json({ error: 'Failed to invalidate fact' });
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
exports.invalidate_temporal_fact = invalidate_temporal_fact;
|
|
152
|
+
const get_subject_facts = async (req, res) => {
|
|
153
|
+
try {
|
|
154
|
+
const { subject } = req.params;
|
|
155
|
+
const { at, include_historical } = req.query;
|
|
156
|
+
if (!subject) {
|
|
157
|
+
return res.status(400).json({ error: 'Subject parameter is required' });
|
|
158
|
+
}
|
|
159
|
+
const at_date = at ? new Date(at) : undefined;
|
|
160
|
+
const include_hist = include_historical === 'true';
|
|
161
|
+
const facts = await (0, query_1.get_facts_by_subject)(subject, at_date, include_hist);
|
|
162
|
+
res.json({
|
|
163
|
+
subject,
|
|
164
|
+
at: at_date?.toISOString(),
|
|
165
|
+
include_historical: include_hist,
|
|
166
|
+
facts,
|
|
167
|
+
count: facts.length
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error('[TEMPORAL API] Error getting subject facts:', error);
|
|
172
|
+
res.status(500).json({ error: 'Failed to get subject facts' });
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
exports.get_subject_facts = get_subject_facts;
|
|
176
|
+
const search_temporal_facts = async (req, res) => {
|
|
177
|
+
try {
|
|
178
|
+
const { pattern, field = 'subject', at } = req.query;
|
|
179
|
+
if (!pattern) {
|
|
180
|
+
return res.status(400).json({ error: 'Pattern parameter is required' });
|
|
181
|
+
}
|
|
182
|
+
if (!['subject', 'predicate', 'object'].includes(field)) {
|
|
183
|
+
return res.status(400).json({ error: 'Field must be one of: subject, predicate, object' });
|
|
184
|
+
}
|
|
185
|
+
const at_date = at ? new Date(at) : undefined;
|
|
186
|
+
const facts = await (0, query_1.search_facts)(pattern, field, at_date);
|
|
187
|
+
res.json({
|
|
188
|
+
pattern,
|
|
189
|
+
field,
|
|
190
|
+
at: at_date?.toISOString(),
|
|
191
|
+
facts,
|
|
192
|
+
count: facts.length
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
console.error('[TEMPORAL API] Error searching facts:', error);
|
|
197
|
+
res.status(500).json({ error: 'Failed to search facts' });
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
exports.search_temporal_facts = search_temporal_facts;
|
|
201
|
+
const get_temporal_stats = async (req, res) => {
|
|
202
|
+
try {
|
|
203
|
+
const active_facts = await (0, store_1.get_active_facts_count)();
|
|
204
|
+
const total_facts = await (0, store_1.get_total_facts_count)();
|
|
205
|
+
const historical_facts = total_facts - active_facts;
|
|
206
|
+
res.json({
|
|
207
|
+
active_facts,
|
|
208
|
+
historical_facts,
|
|
209
|
+
total_facts,
|
|
210
|
+
historical_percentage: total_facts > 0 ? ((historical_facts / total_facts) * 100).toFixed(2) + '%' : '0%'
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
console.error('[TEMPORAL API] Error getting stats:', error);
|
|
215
|
+
res.status(500).json({ error: 'Failed to get statistics' });
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
exports.get_temporal_stats = get_temporal_stats;
|
|
219
|
+
const apply_decay = async (req, res) => {
|
|
220
|
+
try {
|
|
221
|
+
const { decay_rate = 0.01 } = req.body;
|
|
222
|
+
const updated = await (0, store_1.apply_confidence_decay)(decay_rate);
|
|
223
|
+
res.json({
|
|
224
|
+
decay_rate,
|
|
225
|
+
facts_updated: updated,
|
|
226
|
+
message: 'Confidence decay applied successfully'
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
console.error('[TEMPORAL API] Error applying decay:', error);
|
|
231
|
+
res.status(500).json({ error: 'Failed to apply confidence decay' });
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
exports.apply_decay = apply_decay;
|
|
235
|
+
const compare_facts = async (req, res) => {
|
|
236
|
+
try {
|
|
237
|
+
const { subject, time1, time2 } = req.query;
|
|
238
|
+
if (!subject || !time1 || !time2) {
|
|
239
|
+
return res.status(400).json({ error: 'subject, time1, and time2 parameters are required' });
|
|
240
|
+
}
|
|
241
|
+
const t1 = new Date(time1);
|
|
242
|
+
const t2 = new Date(time2);
|
|
243
|
+
const comparison = await (0, timeline_1.compare_time_points)(subject, t1, t2);
|
|
244
|
+
res.json({
|
|
245
|
+
subject,
|
|
246
|
+
time1: t1.toISOString(),
|
|
247
|
+
time2: t2.toISOString(),
|
|
248
|
+
...comparison,
|
|
249
|
+
summary: {
|
|
250
|
+
added: comparison.added.length,
|
|
251
|
+
removed: comparison.removed.length,
|
|
252
|
+
changed: comparison.changed.length,
|
|
253
|
+
unchanged: comparison.unchanged.length
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
console.error('[TEMPORAL API] Error comparing facts:', error);
|
|
259
|
+
res.status(500).json({ error: 'Failed to compare facts' });
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
exports.compare_facts = compare_facts;
|
|
263
|
+
const get_most_volatile = async (req, res) => {
|
|
264
|
+
try {
|
|
265
|
+
const { subject, limit = 10 } = req.query;
|
|
266
|
+
const volatile = await (0, timeline_1.get_volatile_facts)(subject, parseInt(limit));
|
|
267
|
+
res.json({
|
|
268
|
+
subject,
|
|
269
|
+
limit: parseInt(limit),
|
|
270
|
+
volatile_facts: volatile,
|
|
271
|
+
count: volatile.length
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
console.error('[TEMPORAL API] Error getting volatile facts:', error);
|
|
276
|
+
res.status(500).json({ error: 'Failed to get volatile facts' });
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
exports.get_most_volatile = get_most_volatile;
|
|
280
|
+
function temporal(app) {
|
|
281
|
+
app.post('/api/temporal/fact', exports.create_temporal_fact);
|
|
282
|
+
app.get('/api/temporal/fact', exports.get_temporal_fact);
|
|
283
|
+
app.get('/api/temporal/fact/current', exports.get_current_temporal_fact);
|
|
284
|
+
app.patch('/api/temporal/fact/:id', exports.update_temporal_fact);
|
|
285
|
+
app.delete('/api/temporal/fact/:id', exports.invalidate_temporal_fact);
|
|
286
|
+
app.get('/api/temporal/timeline', exports.get_entity_timeline);
|
|
287
|
+
app.get('/api/temporal/subject/:subject', exports.get_subject_facts);
|
|
288
|
+
app.get('/api/temporal/search', exports.search_temporal_facts);
|
|
289
|
+
app.get('/api/temporal/compare', exports.compare_facts);
|
|
290
|
+
app.get('/api/temporal/stats', exports.get_temporal_stats);
|
|
291
|
+
app.post('/api/temporal/decay', exports.apply_decay);
|
|
292
|
+
app.get('/api/temporal/volatile', exports.get_most_volatile);
|
|
293
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.usr = void 0;
|
|
4
|
+
const db_1 = require("../../core/db");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
const user_summary_1 = require("../../memory/user_summary");
|
|
7
|
+
const usr = (app) => {
|
|
8
|
+
app.get("/users/:user_id/summary", async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const { user_id } = req.params;
|
|
11
|
+
if (!user_id)
|
|
12
|
+
return res.status(400).json({ error: "user_id required" });
|
|
13
|
+
const user = await db_1.q.get_user.get(user_id);
|
|
14
|
+
if (!user)
|
|
15
|
+
return res.status(404).json({ error: "user not found" });
|
|
16
|
+
res.json({
|
|
17
|
+
user_id: user.user_id,
|
|
18
|
+
summary: user.summary,
|
|
19
|
+
reflection_count: user.reflection_count,
|
|
20
|
+
updated_at: user.updated_at,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
res.status(500).json({ error: err.message });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
app.post("/users/:user_id/summary/regenerate", async (req, res) => {
|
|
28
|
+
try {
|
|
29
|
+
const { user_id } = req.params;
|
|
30
|
+
if (!user_id)
|
|
31
|
+
return res.status(400).json({ err: "user_id required" });
|
|
32
|
+
await (0, user_summary_1.update_user_summary)(user_id);
|
|
33
|
+
const user = await db_1.q.get_user.get(user_id);
|
|
34
|
+
res.json({
|
|
35
|
+
ok: true,
|
|
36
|
+
user_id,
|
|
37
|
+
summary: user?.summary,
|
|
38
|
+
reflection_count: user?.reflection_count,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
res.status(500).json({ err: err.message });
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
app.post("/users/summaries/regenerate-all", async (req, res) => {
|
|
46
|
+
try {
|
|
47
|
+
const result = await (0, user_summary_1.auto_update_user_summaries)();
|
|
48
|
+
res.json({ ok: true, updated: result.updated });
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
res.status(500).json({ err: err.message });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
app.get("/users/:user_id/memories", async (req, res) => {
|
|
55
|
+
try {
|
|
56
|
+
const { user_id } = req.params;
|
|
57
|
+
if (!user_id)
|
|
58
|
+
return res.status(400).json({ err: "user_id required" });
|
|
59
|
+
const l = req.query.l ? parseInt(req.query.l) : 100;
|
|
60
|
+
const u = req.query.u ? parseInt(req.query.u) : 0;
|
|
61
|
+
const r = await db_1.q.all_mem_by_user.all(user_id, l, u);
|
|
62
|
+
const i = r.map((x) => ({
|
|
63
|
+
id: x.id,
|
|
64
|
+
content: x.content,
|
|
65
|
+
tags: (0, utils_1.p)(x.tags),
|
|
66
|
+
metadata: (0, utils_1.p)(x.meta),
|
|
67
|
+
created_at: x.created_at,
|
|
68
|
+
updated_at: x.updated_at,
|
|
69
|
+
last_seen_at: x.last_seen_at,
|
|
70
|
+
salience: x.salience,
|
|
71
|
+
decay_lambda: x.decay_lambda,
|
|
72
|
+
primary_sector: x.primary_sector,
|
|
73
|
+
version: x.version,
|
|
74
|
+
}));
|
|
75
|
+
res.json({ user_id, items: i });
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
res.status(500).json({ err: err.message });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
app.delete("/users/:user_id/memories", async (req, res) => {
|
|
82
|
+
try {
|
|
83
|
+
const { user_id } = req.params;
|
|
84
|
+
if (!user_id)
|
|
85
|
+
return res.status(400).json({ err: "user_id required" });
|
|
86
|
+
const mems = await db_1.q.all_mem_by_user.all(user_id, 10000, 0);
|
|
87
|
+
let deleted = 0;
|
|
88
|
+
for (const m of mems) {
|
|
89
|
+
await db_1.q.del_mem.run(m.id);
|
|
90
|
+
await db_1.vector_store.deleteVectors(m.id);
|
|
91
|
+
await db_1.q.del_waypoints.run(m.id, m.id);
|
|
92
|
+
deleted++;
|
|
93
|
+
}
|
|
94
|
+
res.json({ ok: true, deleted });
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
res.status(500).json({ err: err.message });
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
exports.usr = usr;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.vercel = vercel;
|
|
4
|
+
const hsg_1 = require("../../memory/hsg");
|
|
5
|
+
const utils_1 = require("../../utils");
|
|
6
|
+
function vercel(app) {
|
|
7
|
+
// Simple memory query endpoint for Vercel AI SDK adapters
|
|
8
|
+
app.post("/query", async (req, res) => {
|
|
9
|
+
try {
|
|
10
|
+
const b = req.body || {};
|
|
11
|
+
const query = String(b.query || "").slice(0, 4000);
|
|
12
|
+
const user_id = b.user_id || req.query.user_id;
|
|
13
|
+
const k = Math.max(1, Math.min(32, Number(b.k) || 8));
|
|
14
|
+
if (!query)
|
|
15
|
+
return res.status(400).json({ err: "query" });
|
|
16
|
+
const startTime = b.startTime ? Number(b.startTime) : undefined;
|
|
17
|
+
const endTime = b.endTime ? Number(b.endTime) : undefined;
|
|
18
|
+
const matches = await (0, hsg_1.hsg_query)(query, k, { user_id, startTime, endTime });
|
|
19
|
+
const lines = matches.map((m) => `- (${(m.score ?? 0).toFixed(2)}) ${m.content}`);
|
|
20
|
+
const result = lines.join("\n");
|
|
21
|
+
res.json({
|
|
22
|
+
query,
|
|
23
|
+
user_id: user_id || null,
|
|
24
|
+
k,
|
|
25
|
+
result,
|
|
26
|
+
matches: matches.map((m) => ({
|
|
27
|
+
id: m.id,
|
|
28
|
+
content: m.content,
|
|
29
|
+
score: m.score,
|
|
30
|
+
sectors: m.sectors,
|
|
31
|
+
primary_sector: m.primary_sector,
|
|
32
|
+
last_seen_at: m.last_seen_at,
|
|
33
|
+
})),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
res.status(500).json({ err: "internal", msg: e?.message || String(e) });
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// Simple memory store endpoint for chat transcripts or summaries
|
|
41
|
+
app.post("/memories", async (req, res) => {
|
|
42
|
+
try {
|
|
43
|
+
const b = req.body || {};
|
|
44
|
+
const content = String(b.content || "").trim();
|
|
45
|
+
const user_id = b.user_id || req.query.user_id;
|
|
46
|
+
const tags = Array.isArray(b.tags) ? b.tags : [];
|
|
47
|
+
const metadata = b.metadata || undefined;
|
|
48
|
+
if (!content)
|
|
49
|
+
return res.status(400).json({ err: "content" });
|
|
50
|
+
const r = await (0, hsg_1.add_hsg_memory)(content, (0, utils_1.j)(tags), metadata, user_id);
|
|
51
|
+
res.json(r);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
res.status(500).json({ err: "internal", msg: e?.message || String(e) });
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
*--------------------------------------------------------------------------------
|
|
4
|
+
* ______ _ _ _ _ _
|
|
5
|
+
* | ____| | | | | | | || |
|
|
6
|
+
* | |__ _ _| |__ ___| | |_ __ _| || |_
|
|
7
|
+
* | __| | | | '_ \ / _ \ | __| \ \ / /__ _|
|
|
8
|
+
* | | | |_| | |_) | __/ | |_ \ V / | |
|
|
9
|
+
* |_| \__,_|_.__/ \___|_|\__| \_/ |_|
|
|
10
|
+
*--------------------------------------------------------------------------------
|
|
11
|
+
*
|
|
12
|
+
* @website - https:
|
|
13
|
+
* @github - https:
|
|
14
|
+
* @discord - https:
|
|
15
|
+
*
|
|
16
|
+
* @author - Cavira
|
|
17
|
+
* @copyright - 2025 Cavira OSS
|
|
18
|
+
* @version - 4.0.0
|
|
19
|
+
*
|
|
20
|
+
*--------------------------------------------------------------------------------
|
|
21
|
+
* server.js - Application webserver.
|
|
22
|
+
*--------------------------------------------------------------------------------
|
|
23
|
+
**/
|
|
24
|
+
const fs = require('fs');
|
|
25
|
+
const path = require('path');
|
|
26
|
+
const http = require('http');
|
|
27
|
+
const WebSocket = require('ws');
|
|
28
|
+
const { parse } = require('url');
|
|
29
|
+
function server(config = {}) {
|
|
30
|
+
const ROUTES = [];
|
|
31
|
+
const WARES = [];
|
|
32
|
+
const WS_ROUTES = [];
|
|
33
|
+
const wss = new WebSocket.Server({ noServer: true });
|
|
34
|
+
const SERVER = http.createServer((req, res) => {
|
|
35
|
+
let u = parse(req.url, true);
|
|
36
|
+
req.query = u.query || {};
|
|
37
|
+
req.path = u.pathname;
|
|
38
|
+
req.hostname = (req.headers.host || '').split(':')[0].replace(/[^\w.-]/g, '');
|
|
39
|
+
req.ip = (req.socket.remoteAddress || '').replace(/[^\w.:]/g, '');
|
|
40
|
+
res.statusCode = 200;
|
|
41
|
+
res.status = (x) => {
|
|
42
|
+
res.statusCode = x;
|
|
43
|
+
return res;
|
|
44
|
+
};
|
|
45
|
+
res.json = (x) => {
|
|
46
|
+
res.writeHead(res.statusCode || 200, { 'Content-Type': 'application/json' });
|
|
47
|
+
res.end(JSON.stringify(x));
|
|
48
|
+
};
|
|
49
|
+
res.send = (x) => {
|
|
50
|
+
if (x === undefined || x === null)
|
|
51
|
+
x = '';
|
|
52
|
+
if (typeof x === 'object')
|
|
53
|
+
return res.json(x);
|
|
54
|
+
res.writeHead(res.statusCode || 200, { 'Content-Type': 'text/plain' });
|
|
55
|
+
res.end(String(x));
|
|
56
|
+
};
|
|
57
|
+
res.set = (k, v) => { res.setHeader(k, v); return res; };
|
|
58
|
+
let r = matchRoute(req.method.toUpperCase(), req.path);
|
|
59
|
+
req.params = r ? r.params : {};
|
|
60
|
+
let fns = [...WARES];
|
|
61
|
+
fns.push(r ? (req, res, next) => r.handler(req, res, next) : (_req, res) => res.status(404).end('404: Not Found'));
|
|
62
|
+
let i = 0;
|
|
63
|
+
let next = () => {
|
|
64
|
+
if (i < fns.length)
|
|
65
|
+
fns[i++](req, res, next);
|
|
66
|
+
};
|
|
67
|
+
next();
|
|
68
|
+
});
|
|
69
|
+
SERVER.on('upgrade', (req, socket, head) => {
|
|
70
|
+
let u = parse(req.url || '', true);
|
|
71
|
+
let path = u.pathname;
|
|
72
|
+
if (!path || path.includes('..') || /[\0-\x1F\x7F]/.test(path)) {
|
|
73
|
+
socket.destroy();
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
for (let i = 0; i < WS_ROUTES.length; i++) {
|
|
77
|
+
let r = WS_ROUTES[i];
|
|
78
|
+
if (r.path === path) {
|
|
79
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
80
|
+
ws.req = req;
|
|
81
|
+
r.handler(ws, req);
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
socket.destroy();
|
|
87
|
+
});
|
|
88
|
+
const matchRoute = (a, b) => {
|
|
89
|
+
for (let i = 0; i < ROUTES.length; i++) {
|
|
90
|
+
let r = ROUTES[i];
|
|
91
|
+
if (r.method !== a && r.method !== 'ALL')
|
|
92
|
+
continue;
|
|
93
|
+
let p = r.path.split('/').filter(Boolean);
|
|
94
|
+
let u = b.split('/').filter(Boolean);
|
|
95
|
+
if (p.length !== u.length)
|
|
96
|
+
continue;
|
|
97
|
+
let params = {};
|
|
98
|
+
let matched = true;
|
|
99
|
+
for (let j = 0; j < p.length; j++) {
|
|
100
|
+
if (p[j].startsWith(':')) {
|
|
101
|
+
params[p[j].slice(1)] = decodeURIComponent(u[j]);
|
|
102
|
+
}
|
|
103
|
+
else if (p[j] !== u[j]) {
|
|
104
|
+
matched = false;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (matched)
|
|
109
|
+
return { handler: r.handler, params };
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
};
|
|
113
|
+
const add = (a, b, c) => { ROUTES.push({ method: a.toUpperCase(), path: b, handler: c }); };
|
|
114
|
+
const use = (a) => { WARES.push(a); };
|
|
115
|
+
const listen = (a, b) => { SERVER.setTimeout(10000); SERVER.listen(a, b); };
|
|
116
|
+
const all = (a, b) => { add('ALL', a, b); };
|
|
117
|
+
const getRoutes = () => ROUTES.reduce((acc, { method, path }) => ((acc[method] = acc[method] || []).push(path), acc), {});
|
|
118
|
+
const serverStatic = (endpoint, dir) => {
|
|
119
|
+
const a = path.resolve(dir);
|
|
120
|
+
if (!fs.existsSync(a) || !fs.statSync(a).isDirectory()) {
|
|
121
|
+
console.error(`[STATIC] Directory not found or is not a directory: ${a}`);
|
|
122
|
+
return (req, res, next) => next();
|
|
123
|
+
}
|
|
124
|
+
let b = (endpoint.endsWith('/') ? endpoint : endpoint + '/');
|
|
125
|
+
return function staticMiddleware(req, res, next) {
|
|
126
|
+
if (req.method !== 'GET' && req.method !== 'HEAD')
|
|
127
|
+
return next();
|
|
128
|
+
if (!req.path.startsWith(b))
|
|
129
|
+
return next();
|
|
130
|
+
let c = path.join(a, req.path.substring(b.length));
|
|
131
|
+
let d = path.relative(a, c);
|
|
132
|
+
if (!(d && !d.startsWith('..') && !path.isAbsolute(d)))
|
|
133
|
+
return next();
|
|
134
|
+
fs.stat(c, (err, stats) => {
|
|
135
|
+
if (err || !stats.isFile())
|
|
136
|
+
return next();
|
|
137
|
+
res.setHeader('Content-Type', getContentType(c));
|
|
138
|
+
fs.createReadStream(c).pipe(res);
|
|
139
|
+
});
|
|
140
|
+
};
|
|
141
|
+
function getContentType(a) {
|
|
142
|
+
switch (path.extname(a).toLowerCase()) {
|
|
143
|
+
case '.html': return 'text/html';
|
|
144
|
+
case '.js': return 'text/javascript';
|
|
145
|
+
case '.css': return 'text/css';
|
|
146
|
+
case '.json': return 'application/json';
|
|
147
|
+
case '.txt': return 'text/plain';
|
|
148
|
+
case '.ico': return 'image/x-icon';
|
|
149
|
+
case '.png': return 'image/png';
|
|
150
|
+
case '.webp': return 'image/webp';
|
|
151
|
+
case '.jpg': return 'image/jpeg';
|
|
152
|
+
case '.jpeg': return 'image/jpeg';
|
|
153
|
+
case '.gif': return 'image/gif';
|
|
154
|
+
case '.svg': return 'image/svg+xml';
|
|
155
|
+
default: return 'application/octet-stream';
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
use((req, res, next) => {
|
|
160
|
+
res.setHeader('Access-Control-Allow-Origin', '*');
|
|
161
|
+
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
|
|
162
|
+
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key');
|
|
163
|
+
if (req.method === 'OPTIONS')
|
|
164
|
+
return res.status(204).send();
|
|
165
|
+
next();
|
|
166
|
+
});
|
|
167
|
+
use((req, res, next) => {
|
|
168
|
+
if (req.headers['content-type']?.includes('application/json')) {
|
|
169
|
+
let d = '';
|
|
170
|
+
let max = config.max_payload_size || 1_000_000;
|
|
171
|
+
req.on('data', e => {
|
|
172
|
+
d += e;
|
|
173
|
+
if (d.length > max) {
|
|
174
|
+
res.status(413).end('Payload Too Large');
|
|
175
|
+
req.destroy();
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
req.on('end', () => {
|
|
179
|
+
req.rawBody = d;
|
|
180
|
+
try {
|
|
181
|
+
req.body = JSON.parse(d);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
req.body = null;
|
|
185
|
+
}
|
|
186
|
+
next();
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
next();
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
return {
|
|
194
|
+
use,
|
|
195
|
+
listen,
|
|
196
|
+
all,
|
|
197
|
+
serverStatic,
|
|
198
|
+
routes: ROUTES,
|
|
199
|
+
getRoutes,
|
|
200
|
+
get: (a, b) => add('GET', a, b),
|
|
201
|
+
post: (a, b) => add('POST', a, b),
|
|
202
|
+
put: (a, b) => add('PUT', a, b),
|
|
203
|
+
delete: (a, b) => add('DELETE', a, b),
|
|
204
|
+
patch: (a, b) => add('PATCH', a, b),
|
|
205
|
+
options: (a, b) => add('OPTIONS', a, b),
|
|
206
|
+
head: (a, b) => add('HEAD', a, b),
|
|
207
|
+
all: (a, b) => add('ALL', a, b),
|
|
208
|
+
ws: (a, b) => WS_ROUTES.push({ path: a, handler: b })
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
module.exports = server;
|
package/dist/server.js
ADDED