teleton 0.5.2 → 0.7.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/README.md +243 -105
- package/dist/chunk-FNV5FF35.js +331 -0
- package/dist/chunk-LRCPA7SC.js +149 -0
- package/dist/{chunk-WUTMT6DW.js → chunk-N3F7E7DR.js} +114 -566
- package/dist/chunk-ND2X5FWB.js +368 -0
- package/dist/chunk-NERLQY2H.js +421 -0
- package/dist/{chunk-YBA6IBGT.js → chunk-OCLG5GKI.js} +24 -24
- package/dist/{chunk-WOXBZOQX.js → chunk-OGIG552S.js} +2152 -4488
- package/dist/chunk-RCMD3U65.js +141 -0
- package/dist/{chunk-O4R7V5Y2.js → chunk-RO62LO6Z.js} +11 -1
- package/dist/chunk-TCD4NZDA.js +3226 -0
- package/dist/chunk-UCN6TI25.js +143 -0
- package/dist/{chunk-WL2Q3VRD.js → chunk-UDD7FYOU.js} +12 -4
- package/dist/chunk-VAUJSSD3.js +20 -0
- package/dist/chunk-XBE4JB7C.js +8 -0
- package/dist/chunk-XBKSS6DM.js +58 -0
- package/dist/cli/index.js +1179 -412
- package/dist/client-3VWE7NC4.js +29 -0
- package/dist/{get-my-gifts-KVULMBJ3.js → get-my-gifts-RI7FAXAL.js} +3 -1
- package/dist/index.js +17 -8
- package/dist/{memory-Y5J7CXAR.js → memory-RD7ZSTRV.js} +16 -10
- package/dist/{migrate-UEQCDWL2.js → migrate-GO4NOBT7.js} +14 -6
- package/dist/{server-BQY7CM2N.js → server-OWVEZTR3.js} +869 -93
- package/dist/setup-server-C7ZTPHD5.js +934 -0
- package/dist/{task-dependency-resolver-TRPILAHM.js → task-dependency-resolver-WKZWJLLM.js} +19 -15
- package/dist/{task-executor-N7XNVK5N.js → task-executor-PD3H4MLO.js} +5 -2
- package/dist/tool-adapter-Y3TCEQOC.js +145 -0
- package/dist/tool-index-MIVK3D7H.js +250 -0
- package/dist/{transcript-7V4UNID4.js → transcript-UDJZP6NK.js} +2 -1
- package/dist/web/assets/complete-fZLnb5Ot.js +1 -0
- package/dist/web/assets/index-B_FcaX5D.css +1 -0
- package/dist/web/assets/index-CbeAP4_n.js +67 -0
- package/dist/web/assets/index.es-oXiZF7Hc.js +11 -0
- package/dist/web/assets/login-telegram-BP7CJDmx.js +1 -0
- package/dist/web/assets/run-DOrDowjK.js +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +21 -15
- package/dist/chunk-5WWR4CU3.js +0 -124
- package/dist/web/assets/index-CDMbujHf.css +0 -1
- package/dist/web/assets/index-DDX8oQ2z.js +0 -67
|
@@ -1,145 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
CachedEmbeddingProvider,
|
|
3
|
+
createEmbeddingProvider,
|
|
4
|
+
hashText,
|
|
5
|
+
serializeEmbedding
|
|
6
|
+
} from "./chunk-FNV5FF35.js";
|
|
7
|
+
import {
|
|
8
|
+
JOURNAL_SCHEMA
|
|
9
|
+
} from "./chunk-UCN6TI25.js";
|
|
4
10
|
import {
|
|
5
|
-
EMBEDDING_CACHE_EVICTION_INTERVAL,
|
|
6
|
-
EMBEDDING_CACHE_EVICTION_RATIO,
|
|
7
|
-
EMBEDDING_CACHE_MAX_ENTRIES,
|
|
8
|
-
EMBEDDING_CACHE_TTL_DAYS,
|
|
9
11
|
HYBRID_SEARCH_MIN_SCORE,
|
|
10
12
|
KNOWLEDGE_CHUNK_SIZE,
|
|
11
13
|
SQLITE_CACHE_SIZE_KB,
|
|
12
|
-
SQLITE_MMAP_SIZE
|
|
13
|
-
|
|
14
|
-
} from "./chunk-O4R7V5Y2.js";
|
|
14
|
+
SQLITE_MMAP_SIZE
|
|
15
|
+
} from "./chunk-RO62LO6Z.js";
|
|
15
16
|
import {
|
|
16
|
-
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
createLogger
|
|
18
|
+
} from "./chunk-RCMD3U65.js";
|
|
18
19
|
|
|
19
20
|
// src/memory/database.ts
|
|
20
|
-
import Database2 from "better-sqlite3";
|
|
21
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2, chmodSync as chmodSync2 } from "fs";
|
|
22
|
-
import { dirname as dirname2 } from "path";
|
|
23
|
-
import * as sqliteVec from "sqlite-vec";
|
|
24
|
-
|
|
25
|
-
// src/utils/module-db.ts
|
|
26
21
|
import Database from "better-sqlite3";
|
|
27
22
|
import { existsSync, mkdirSync, chmodSync } from "fs";
|
|
28
|
-
import { dirname
|
|
29
|
-
|
|
30
|
-
CREATE TABLE IF NOT EXISTS journal (
|
|
31
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
32
|
-
timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
33
|
-
type TEXT NOT NULL CHECK(type IN ('trade', 'gift', 'middleman', 'kol')),
|
|
34
|
-
action TEXT NOT NULL,
|
|
35
|
-
asset_from TEXT,
|
|
36
|
-
asset_to TEXT,
|
|
37
|
-
amount_from REAL,
|
|
38
|
-
amount_to REAL,
|
|
39
|
-
price_ton REAL,
|
|
40
|
-
counterparty TEXT,
|
|
41
|
-
platform TEXT,
|
|
42
|
-
reasoning TEXT,
|
|
43
|
-
outcome TEXT CHECK(outcome IN ('pending', 'profit', 'loss', 'neutral', 'cancelled')),
|
|
44
|
-
pnl_ton REAL,
|
|
45
|
-
pnl_pct REAL,
|
|
46
|
-
tx_hash TEXT,
|
|
47
|
-
tool_used TEXT,
|
|
48
|
-
chat_id TEXT,
|
|
49
|
-
user_id INTEGER,
|
|
50
|
-
closed_at INTEGER,
|
|
51
|
-
created_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
CREATE INDEX IF NOT EXISTS idx_journal_type ON journal(type);
|
|
55
|
-
CREATE INDEX IF NOT EXISTS idx_journal_timestamp ON journal(timestamp DESC);
|
|
56
|
-
CREATE INDEX IF NOT EXISTS idx_journal_asset_from ON journal(asset_from);
|
|
57
|
-
CREATE INDEX IF NOT EXISTS idx_journal_outcome ON journal(outcome);
|
|
58
|
-
CREATE INDEX IF NOT EXISTS idx_journal_type_timestamp ON journal(type, timestamp DESC);
|
|
59
|
-
`;
|
|
60
|
-
var USED_TRANSACTIONS_SCHEMA = `
|
|
61
|
-
CREATE TABLE IF NOT EXISTS used_transactions (
|
|
62
|
-
tx_hash TEXT PRIMARY KEY,
|
|
63
|
-
user_id TEXT NOT NULL,
|
|
64
|
-
amount REAL NOT NULL,
|
|
65
|
-
game_type TEXT NOT NULL,
|
|
66
|
-
used_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
CREATE INDEX IF NOT EXISTS idx_used_tx_user ON used_transactions(user_id);
|
|
70
|
-
CREATE INDEX IF NOT EXISTS idx_used_tx_used_at ON used_transactions(used_at);
|
|
71
|
-
`;
|
|
72
|
-
function openModuleDb(path) {
|
|
73
|
-
const dir = dirname(path);
|
|
74
|
-
if (!existsSync(dir)) {
|
|
75
|
-
mkdirSync(dir, { recursive: true });
|
|
76
|
-
}
|
|
77
|
-
const db = new Database(path);
|
|
78
|
-
try {
|
|
79
|
-
chmodSync(path, 384);
|
|
80
|
-
} catch {
|
|
81
|
-
}
|
|
82
|
-
db.pragma("journal_mode = WAL");
|
|
83
|
-
return db;
|
|
84
|
-
}
|
|
85
|
-
function createDbWrapper(getDb, moduleName) {
|
|
86
|
-
return function withDb(executor) {
|
|
87
|
-
return (params, context) => {
|
|
88
|
-
const moduleDb = getDb();
|
|
89
|
-
if (!moduleDb) {
|
|
90
|
-
return Promise.resolve({
|
|
91
|
-
success: false,
|
|
92
|
-
error: `${moduleName} module not started`
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
return executor(params, { ...context, db: moduleDb });
|
|
96
|
-
};
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
var MAIN_DB_PATH = join(TELETON_ROOT, "memory.db");
|
|
100
|
-
function migrateFromMainDb(moduleDb, tables) {
|
|
101
|
-
let totalMigrated = 0;
|
|
102
|
-
for (const table of tables) {
|
|
103
|
-
if (!/^[a-z_]+$/.test(table)) {
|
|
104
|
-
throw new Error(`Invalid table name for migration: "${table}"`);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
for (const table of tables) {
|
|
108
|
-
try {
|
|
109
|
-
const row = moduleDb.prepare(`SELECT COUNT(*) as c FROM ${table}`).get();
|
|
110
|
-
if (row.c > 0) return 0;
|
|
111
|
-
} catch {
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (!existsSync(MAIN_DB_PATH)) return 0;
|
|
116
|
-
try {
|
|
117
|
-
moduleDb.exec(`ATTACH DATABASE '${MAIN_DB_PATH}' AS main_db`);
|
|
118
|
-
for (const table of tables) {
|
|
119
|
-
try {
|
|
120
|
-
const exists = moduleDb.prepare(`SELECT name FROM main_db.sqlite_master WHERE type='table' AND name=?`).get(table);
|
|
121
|
-
if (!exists) continue;
|
|
122
|
-
const src = moduleDb.prepare(`SELECT COUNT(*) as c FROM main_db.${table}`).get();
|
|
123
|
-
if (src.c === 0) continue;
|
|
124
|
-
moduleDb.exec(`INSERT OR IGNORE INTO ${table} SELECT * FROM main_db.${table}`);
|
|
125
|
-
totalMigrated += src.c;
|
|
126
|
-
console.log(` \u{1F4E6} Migrated ${src.c} rows from memory.db \u2192 ${table}`);
|
|
127
|
-
} catch (e) {
|
|
128
|
-
console.warn(` \u26A0\uFE0F Could not migrate table ${table}:`, e);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
moduleDb.exec(`DETACH DATABASE main_db`);
|
|
132
|
-
} catch (e) {
|
|
133
|
-
console.warn(`\u26A0\uFE0F Migration from memory.db failed:`, e);
|
|
134
|
-
try {
|
|
135
|
-
moduleDb.exec(`DETACH DATABASE main_db`);
|
|
136
|
-
} catch {
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return totalMigrated;
|
|
140
|
-
}
|
|
23
|
+
import { dirname } from "path";
|
|
24
|
+
import * as sqliteVec from "sqlite-vec";
|
|
141
25
|
|
|
142
26
|
// src/memory/schema.ts
|
|
27
|
+
var log = createLogger("Memory");
|
|
143
28
|
function compareSemver(a, b) {
|
|
144
29
|
const parseVersion = (v) => {
|
|
145
30
|
const parts = v.split("-")[0].split(".").map(Number);
|
|
@@ -428,15 +313,15 @@ function setSchemaVersion(db, version) {
|
|
|
428
313
|
`
|
|
429
314
|
).run(version);
|
|
430
315
|
}
|
|
431
|
-
var CURRENT_SCHEMA_VERSION = "1.
|
|
316
|
+
var CURRENT_SCHEMA_VERSION = "1.11.0";
|
|
432
317
|
function runMigrations(db) {
|
|
433
318
|
const currentVersion = getSchemaVersion(db);
|
|
434
319
|
if (!currentVersion || versionLessThan(currentVersion, "1.1.0")) {
|
|
435
|
-
|
|
320
|
+
log.info("Running migration: Adding scheduled task columns...");
|
|
436
321
|
try {
|
|
437
322
|
const tableExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='tasks'").get();
|
|
438
323
|
if (!tableExists) {
|
|
439
|
-
|
|
324
|
+
log.info("Tasks table doesn't exist yet, skipping column migration");
|
|
440
325
|
setSchemaVersion(db, CURRENT_SCHEMA_VERSION);
|
|
441
326
|
return;
|
|
442
327
|
}
|
|
@@ -469,15 +354,15 @@ function runMigrations(db) {
|
|
|
469
354
|
CREATE INDEX IF NOT EXISTS idx_task_deps_task ON task_dependencies(task_id);
|
|
470
355
|
CREATE INDEX IF NOT EXISTS idx_task_deps_parent ON task_dependencies(depends_on_task_id);
|
|
471
356
|
`);
|
|
472
|
-
|
|
357
|
+
log.info("Migration 1.1.0 complete: Scheduled tasks support added");
|
|
473
358
|
} catch (error) {
|
|
474
|
-
|
|
359
|
+
log.error({ err: error }, "Migration 1.1.0 failed");
|
|
475
360
|
throw error;
|
|
476
361
|
}
|
|
477
362
|
}
|
|
478
363
|
if (!currentVersion || versionLessThan(currentVersion, "1.2.0")) {
|
|
479
364
|
try {
|
|
480
|
-
|
|
365
|
+
log.info("Running migration 1.2.0: Extend sessions table for SQLite backend");
|
|
481
366
|
const addColumnIfNotExists = (table, column, type) => {
|
|
482
367
|
try {
|
|
483
368
|
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${type}`);
|
|
@@ -506,14 +391,14 @@ function runMigrations(db) {
|
|
|
506
391
|
);
|
|
507
392
|
}
|
|
508
393
|
db.exec("CREATE INDEX IF NOT EXISTS idx_sessions_updated ON sessions(updated_at DESC)");
|
|
509
|
-
|
|
394
|
+
log.info("Migration 1.2.0 complete: Sessions table extended");
|
|
510
395
|
} catch (error) {
|
|
511
|
-
|
|
396
|
+
log.error({ err: error }, "Migration 1.2.0 failed");
|
|
512
397
|
throw error;
|
|
513
398
|
}
|
|
514
399
|
}
|
|
515
400
|
if (!currentVersion || versionLessThan(currentVersion, "1.9.0")) {
|
|
516
|
-
|
|
401
|
+
log.info("Running migration 1.9.0: Upgrade embedding_cache to BLOB storage");
|
|
517
402
|
try {
|
|
518
403
|
db.exec(`DROP TABLE IF EXISTS embedding_cache`);
|
|
519
404
|
db.exec(`
|
|
@@ -529,14 +414,14 @@ function runMigrations(db) {
|
|
|
529
414
|
);
|
|
530
415
|
CREATE INDEX IF NOT EXISTS idx_embedding_cache_accessed ON embedding_cache(accessed_at);
|
|
531
416
|
`);
|
|
532
|
-
|
|
417
|
+
log.info("Migration 1.9.0 complete: embedding_cache upgraded to BLOB storage");
|
|
533
418
|
} catch (error) {
|
|
534
|
-
|
|
419
|
+
log.error({ err: error }, "Migration 1.9.0 failed");
|
|
535
420
|
throw error;
|
|
536
421
|
}
|
|
537
422
|
}
|
|
538
423
|
if (!currentVersion || versionLessThan(currentVersion, "1.10.0")) {
|
|
539
|
-
|
|
424
|
+
log.info("Running migration 1.10.0: Add tool_config table for runtime tool management");
|
|
540
425
|
try {
|
|
541
426
|
db.exec(`
|
|
542
427
|
CREATE TABLE IF NOT EXISTS tool_config (
|
|
@@ -547,32 +432,71 @@ function runMigrations(db) {
|
|
|
547
432
|
updated_by INTEGER
|
|
548
433
|
);
|
|
549
434
|
`);
|
|
550
|
-
|
|
435
|
+
log.info("Migration 1.10.0 complete: tool_config table created");
|
|
551
436
|
} catch (error) {
|
|
552
|
-
|
|
437
|
+
log.error({ err: error }, "Migration 1.10.0 failed");
|
|
553
438
|
throw error;
|
|
554
439
|
}
|
|
555
440
|
}
|
|
556
441
|
if (!currentVersion || versionLessThan(currentVersion, "1.10.1")) {
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
442
|
+
log.info("Running migration 1.10.1: Fix tool_config scope CHECK constraint (add admin-only)");
|
|
443
|
+
try {
|
|
444
|
+
db.transaction(() => {
|
|
445
|
+
db.exec(`
|
|
446
|
+
CREATE TABLE IF NOT EXISTS tool_config_new (
|
|
447
|
+
tool_name TEXT PRIMARY KEY,
|
|
448
|
+
enabled INTEGER NOT NULL DEFAULT 1 CHECK(enabled IN (0, 1)),
|
|
449
|
+
scope TEXT CHECK(scope IN ('always', 'dm-only', 'group-only', 'admin-only')),
|
|
450
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
451
|
+
updated_by INTEGER
|
|
452
|
+
);
|
|
453
|
+
INSERT OR IGNORE INTO tool_config_new SELECT * FROM tool_config;
|
|
454
|
+
DROP TABLE tool_config;
|
|
455
|
+
ALTER TABLE tool_config_new RENAME TO tool_config;
|
|
456
|
+
`);
|
|
457
|
+
})();
|
|
458
|
+
log.info("Migration 1.10.1 complete: tool_config CHECK constraint updated");
|
|
459
|
+
} catch (error) {
|
|
460
|
+
log.error({ err: error }, "Migration 1.10.1 failed");
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (!currentVersion || versionLessThan(currentVersion, "1.11.0")) {
|
|
465
|
+
log.info("Running migration 1.11.0: Add tool_index tables for Tool RAG");
|
|
560
466
|
try {
|
|
561
467
|
db.exec(`
|
|
562
|
-
CREATE TABLE IF NOT EXISTS
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
567
|
-
|
|
468
|
+
CREATE TABLE IF NOT EXISTS tool_index (
|
|
469
|
+
name TEXT PRIMARY KEY,
|
|
470
|
+
description TEXT NOT NULL,
|
|
471
|
+
search_text TEXT NOT NULL,
|
|
472
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS tool_index_fts USING fts5(
|
|
476
|
+
search_text,
|
|
477
|
+
name UNINDEXED,
|
|
478
|
+
content='tool_index',
|
|
479
|
+
content_rowid='rowid'
|
|
568
480
|
);
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
481
|
+
|
|
482
|
+
CREATE TRIGGER IF NOT EXISTS tool_index_fts_insert AFTER INSERT ON tool_index BEGIN
|
|
483
|
+
INSERT INTO tool_index_fts(rowid, search_text, name)
|
|
484
|
+
VALUES (new.rowid, new.search_text, new.name);
|
|
485
|
+
END;
|
|
486
|
+
|
|
487
|
+
CREATE TRIGGER IF NOT EXISTS tool_index_fts_delete AFTER DELETE ON tool_index BEGIN
|
|
488
|
+
DELETE FROM tool_index_fts WHERE rowid = old.rowid;
|
|
489
|
+
END;
|
|
490
|
+
|
|
491
|
+
CREATE TRIGGER IF NOT EXISTS tool_index_fts_update AFTER UPDATE ON tool_index BEGIN
|
|
492
|
+
DELETE FROM tool_index_fts WHERE rowid = old.rowid;
|
|
493
|
+
INSERT INTO tool_index_fts(rowid, search_text, name)
|
|
494
|
+
VALUES (new.rowid, new.search_text, new.name);
|
|
495
|
+
END;
|
|
572
496
|
`);
|
|
573
|
-
|
|
497
|
+
log.info("Migration 1.11.0 complete: tool_index tables created");
|
|
574
498
|
} catch (error) {
|
|
575
|
-
|
|
499
|
+
log.error({ err: error }, "Migration 1.11.0 failed");
|
|
576
500
|
throw error;
|
|
577
501
|
}
|
|
578
502
|
}
|
|
@@ -580,21 +504,22 @@ function runMigrations(db) {
|
|
|
580
504
|
}
|
|
581
505
|
|
|
582
506
|
// src/memory/database.ts
|
|
507
|
+
var log2 = createLogger("Memory");
|
|
583
508
|
var MemoryDatabase = class {
|
|
584
509
|
db;
|
|
585
510
|
config;
|
|
586
511
|
vectorReady = false;
|
|
587
512
|
constructor(config) {
|
|
588
513
|
this.config = config;
|
|
589
|
-
const dir =
|
|
590
|
-
if (!
|
|
591
|
-
|
|
514
|
+
const dir = dirname(config.path);
|
|
515
|
+
if (!existsSync(dir)) {
|
|
516
|
+
mkdirSync(dir, { recursive: true });
|
|
592
517
|
}
|
|
593
|
-
this.db = new
|
|
594
|
-
verbose: process.env.DEBUG_SQL ?
|
|
518
|
+
this.db = new Database(config.path, {
|
|
519
|
+
verbose: process.env.DEBUG_SQL ? (msg) => log2.debug(String(msg)) : void 0
|
|
595
520
|
});
|
|
596
521
|
try {
|
|
597
|
-
|
|
522
|
+
chmodSync(config.path, 384);
|
|
598
523
|
} catch {
|
|
599
524
|
}
|
|
600
525
|
this.db.pragma("journal_mode = WAL");
|
|
@@ -631,18 +556,16 @@ var MemoryDatabase = class {
|
|
|
631
556
|
ensureVectorTables(this.db, dims);
|
|
632
557
|
this.vectorReady = true;
|
|
633
558
|
} catch (error) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
);
|
|
637
|
-
console.warn(" Falling back to keyword-only search");
|
|
559
|
+
log2.warn(`sqlite-vec not available, vector search disabled: ${error.message}`);
|
|
560
|
+
log2.warn("Falling back to keyword-only search");
|
|
638
561
|
this.config.enableVectorSearch = false;
|
|
639
562
|
}
|
|
640
563
|
}
|
|
641
564
|
migrate(from, to) {
|
|
642
|
-
|
|
565
|
+
log2.info(`Migrating database from ${from} to ${to}...`);
|
|
643
566
|
runMigrations(this.db);
|
|
644
567
|
ensureSchema(this.db);
|
|
645
|
-
|
|
568
|
+
log2.info("Migration complete");
|
|
646
569
|
}
|
|
647
570
|
getDb() {
|
|
648
571
|
return this.db;
|
|
@@ -743,365 +666,9 @@ function closeDatabase() {
|
|
|
743
666
|
}
|
|
744
667
|
}
|
|
745
668
|
|
|
746
|
-
// src/memory/embeddings/index.ts
|
|
747
|
-
import { createHash } from "crypto";
|
|
748
|
-
|
|
749
|
-
// src/memory/embeddings/provider.ts
|
|
750
|
-
var NoopEmbeddingProvider = class {
|
|
751
|
-
id = "noop";
|
|
752
|
-
model = "none";
|
|
753
|
-
dimensions = 0;
|
|
754
|
-
async embedQuery(_text) {
|
|
755
|
-
return [];
|
|
756
|
-
}
|
|
757
|
-
async embedBatch(_texts) {
|
|
758
|
-
return [];
|
|
759
|
-
}
|
|
760
|
-
};
|
|
761
|
-
|
|
762
|
-
// src/utils/fetch.ts
|
|
763
|
-
var DEFAULT_TIMEOUT_MS = DEFAULT_FETCH_TIMEOUT_MS;
|
|
764
|
-
function fetchWithTimeout(url, init) {
|
|
765
|
-
const { timeoutMs = DEFAULT_TIMEOUT_MS, ...fetchInit } = init ?? {};
|
|
766
|
-
if (fetchInit.signal) {
|
|
767
|
-
return fetch(url, fetchInit);
|
|
768
|
-
}
|
|
769
|
-
return fetch(url, {
|
|
770
|
-
...fetchInit,
|
|
771
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
// src/constants/api-endpoints.ts
|
|
776
|
-
var TONAPI_BASE_URL = "https://tonapi.io/v2";
|
|
777
|
-
var _tonapiKey;
|
|
778
|
-
function setTonapiKey(key) {
|
|
779
|
-
_tonapiKey = key;
|
|
780
|
-
}
|
|
781
|
-
function tonapiHeaders() {
|
|
782
|
-
const headers = { Accept: "application/json" };
|
|
783
|
-
if (_tonapiKey) {
|
|
784
|
-
headers["Authorization"] = `Bearer ${_tonapiKey}`;
|
|
785
|
-
}
|
|
786
|
-
return headers;
|
|
787
|
-
}
|
|
788
|
-
var TONAPI_MAX_RPS = 5;
|
|
789
|
-
var _tonapiTimestamps = [];
|
|
790
|
-
async function waitForTonapiSlot() {
|
|
791
|
-
const clean = () => {
|
|
792
|
-
const cutoff = Date.now() - 1e3;
|
|
793
|
-
while (_tonapiTimestamps.length > 0 && _tonapiTimestamps[0] <= cutoff) {
|
|
794
|
-
_tonapiTimestamps.shift();
|
|
795
|
-
}
|
|
796
|
-
};
|
|
797
|
-
clean();
|
|
798
|
-
if (_tonapiTimestamps.length >= TONAPI_MAX_RPS) {
|
|
799
|
-
const waitMs = _tonapiTimestamps[0] + 1e3 - Date.now() + 50;
|
|
800
|
-
if (waitMs > 0) await new Promise((r) => setTimeout(r, waitMs));
|
|
801
|
-
clean();
|
|
802
|
-
}
|
|
803
|
-
_tonapiTimestamps.push(Date.now());
|
|
804
|
-
}
|
|
805
|
-
async function tonapiFetch(path, init) {
|
|
806
|
-
await waitForTonapiSlot();
|
|
807
|
-
return fetchWithTimeout(`${TONAPI_BASE_URL}${path}`, {
|
|
808
|
-
...init,
|
|
809
|
-
headers: { ...tonapiHeaders(), ...init?.headers }
|
|
810
|
-
});
|
|
811
|
-
}
|
|
812
|
-
var STONFI_API_BASE_URL = "https://api.ston.fi/v1";
|
|
813
|
-
var GECKOTERMINAL_API_URL = "https://api.geckoterminal.com/api/v2";
|
|
814
|
-
var COINGECKO_API_URL = "https://api.coingecko.com/api/v3";
|
|
815
|
-
var OPENAI_TTS_URL = "https://api.openai.com/v1/audio/speech";
|
|
816
|
-
var ELEVENLABS_TTS_URL = "https://api.elevenlabs.io/v1/text-to-speech";
|
|
817
|
-
var VOYAGE_API_URL = "https://api.voyageai.com/v1";
|
|
818
|
-
|
|
819
|
-
// src/memory/embeddings/anthropic.ts
|
|
820
|
-
var AnthropicEmbeddingProvider = class {
|
|
821
|
-
id = "anthropic";
|
|
822
|
-
model;
|
|
823
|
-
dimensions;
|
|
824
|
-
apiKey;
|
|
825
|
-
baseUrl = VOYAGE_API_URL;
|
|
826
|
-
constructor(config) {
|
|
827
|
-
this.apiKey = config.apiKey;
|
|
828
|
-
this.model = config.model ?? "voyage-3-lite";
|
|
829
|
-
const dims = {
|
|
830
|
-
"voyage-3": 1024,
|
|
831
|
-
"voyage-3-lite": 512,
|
|
832
|
-
"voyage-code-3": 1024,
|
|
833
|
-
"voyage-finance-2": 1024,
|
|
834
|
-
"voyage-multilingual-2": 1024,
|
|
835
|
-
"voyage-law-2": 1024
|
|
836
|
-
};
|
|
837
|
-
this.dimensions = dims[this.model] ?? 512;
|
|
838
|
-
}
|
|
839
|
-
async embedQuery(text) {
|
|
840
|
-
const result = await this.embed([text]);
|
|
841
|
-
return result[0] ?? [];
|
|
842
|
-
}
|
|
843
|
-
async embedBatch(texts) {
|
|
844
|
-
if (texts.length === 0) return [];
|
|
845
|
-
const batchSize = VOYAGE_BATCH_SIZE;
|
|
846
|
-
const results = [];
|
|
847
|
-
for (let i = 0; i < texts.length; i += batchSize) {
|
|
848
|
-
const batch = texts.slice(i, i + batchSize);
|
|
849
|
-
const embeddings = await this.embed(batch);
|
|
850
|
-
results.push(...embeddings);
|
|
851
|
-
}
|
|
852
|
-
return results;
|
|
853
|
-
}
|
|
854
|
-
async embed(texts) {
|
|
855
|
-
const response = await fetchWithTimeout(`${this.baseUrl}/embeddings`, {
|
|
856
|
-
method: "POST",
|
|
857
|
-
headers: {
|
|
858
|
-
"Content-Type": "application/json",
|
|
859
|
-
Authorization: `Bearer ${this.apiKey}`
|
|
860
|
-
},
|
|
861
|
-
body: JSON.stringify({
|
|
862
|
-
input: texts,
|
|
863
|
-
model: this.model,
|
|
864
|
-
input_type: "document"
|
|
865
|
-
})
|
|
866
|
-
});
|
|
867
|
-
if (!response.ok) {
|
|
868
|
-
const error = await response.text();
|
|
869
|
-
throw new Error(`Voyage API error: ${response.status} ${error}`);
|
|
870
|
-
}
|
|
871
|
-
const data = await response.json();
|
|
872
|
-
return data.data.map((item) => item.embedding);
|
|
873
|
-
}
|
|
874
|
-
};
|
|
875
|
-
|
|
876
|
-
// src/memory/embeddings/local.ts
|
|
877
|
-
import { pipeline, env } from "@huggingface/transformers";
|
|
878
|
-
import { join as join2 } from "path";
|
|
879
|
-
env.cacheDir = join2(TELETON_ROOT, "models");
|
|
880
|
-
var extractorPromise = null;
|
|
881
|
-
function getExtractor(model) {
|
|
882
|
-
if (!extractorPromise) {
|
|
883
|
-
console.log(`\u{1F4E6} Loading local embedding model: ${model} (cache: ${env.cacheDir})`);
|
|
884
|
-
extractorPromise = pipeline("feature-extraction", model, {
|
|
885
|
-
dtype: "fp32"
|
|
886
|
-
}).then((ext) => {
|
|
887
|
-
console.log(`\u2705 Local embedding model ready`);
|
|
888
|
-
return ext;
|
|
889
|
-
}).catch((err) => {
|
|
890
|
-
console.error(`\u274C Failed to load embedding model: ${err.message}`);
|
|
891
|
-
extractorPromise = null;
|
|
892
|
-
throw err;
|
|
893
|
-
});
|
|
894
|
-
}
|
|
895
|
-
return extractorPromise;
|
|
896
|
-
}
|
|
897
|
-
var LocalEmbeddingProvider = class {
|
|
898
|
-
id = "local";
|
|
899
|
-
model;
|
|
900
|
-
dimensions;
|
|
901
|
-
_disabled = false;
|
|
902
|
-
constructor(config) {
|
|
903
|
-
this.model = config.model || "Xenova/all-MiniLM-L6-v2";
|
|
904
|
-
this.dimensions = 384;
|
|
905
|
-
}
|
|
906
|
-
/**
|
|
907
|
-
* Pre-download and load the model at startup.
|
|
908
|
-
* If loading fails, marks this provider as disabled (returns empty embeddings).
|
|
909
|
-
* Call this once during app init — avoids retry spam on every message.
|
|
910
|
-
* @returns true if model loaded successfully, false if fallback to noop
|
|
911
|
-
*/
|
|
912
|
-
async warmup() {
|
|
913
|
-
try {
|
|
914
|
-
await getExtractor(this.model);
|
|
915
|
-
return true;
|
|
916
|
-
} catch (err) {
|
|
917
|
-
console.warn(
|
|
918
|
-
`\u26A0\uFE0F Local embedding model unavailable \u2014 falling back to FTS5-only search (no vector embeddings)`
|
|
919
|
-
);
|
|
920
|
-
this._disabled = true;
|
|
921
|
-
return false;
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
async embedQuery(text) {
|
|
925
|
-
if (this._disabled) return [];
|
|
926
|
-
const extractor = await getExtractor(this.model);
|
|
927
|
-
const output = await extractor(text, { pooling: "mean", normalize: true });
|
|
928
|
-
return Array.from(output.data);
|
|
929
|
-
}
|
|
930
|
-
async embedBatch(texts) {
|
|
931
|
-
if (this._disabled) return [];
|
|
932
|
-
if (texts.length === 0) return [];
|
|
933
|
-
const extractor = await getExtractor(this.model);
|
|
934
|
-
const output = await extractor(texts, { pooling: "mean", normalize: true });
|
|
935
|
-
const data = output.data;
|
|
936
|
-
const dims = this.dimensions;
|
|
937
|
-
const results = [];
|
|
938
|
-
for (let i = 0; i < texts.length; i++) {
|
|
939
|
-
results.push(Array.from(data.slice(i * dims, (i + 1) * dims)));
|
|
940
|
-
}
|
|
941
|
-
return results;
|
|
942
|
-
}
|
|
943
|
-
};
|
|
944
|
-
|
|
945
|
-
// src/memory/embeddings/cached.ts
|
|
946
|
-
var CachedEmbeddingProvider = class {
|
|
947
|
-
constructor(inner, db) {
|
|
948
|
-
this.inner = inner;
|
|
949
|
-
this.db = db;
|
|
950
|
-
this.id = inner.id;
|
|
951
|
-
this.model = inner.model;
|
|
952
|
-
this.dimensions = inner.dimensions;
|
|
953
|
-
}
|
|
954
|
-
id;
|
|
955
|
-
model;
|
|
956
|
-
dimensions;
|
|
957
|
-
hits = 0;
|
|
958
|
-
misses = 0;
|
|
959
|
-
ops = 0;
|
|
960
|
-
cacheGet(hash) {
|
|
961
|
-
return this.db.prepare(
|
|
962
|
-
`SELECT embedding FROM embedding_cache WHERE hash = ? AND model = ? AND provider = ?`
|
|
963
|
-
).get(hash, this.model, this.id);
|
|
964
|
-
}
|
|
965
|
-
cachePut(hash, blob) {
|
|
966
|
-
this.db.prepare(
|
|
967
|
-
`INSERT OR REPLACE INTO embedding_cache (hash, embedding, model, provider, dims, created_at, accessed_at)
|
|
968
|
-
VALUES (?, ?, ?, ?, ?, unixepoch(), unixepoch())`
|
|
969
|
-
).run(hash, blob, this.model, this.id, this.dimensions);
|
|
970
|
-
}
|
|
971
|
-
cacheTouch(hash) {
|
|
972
|
-
this.db.prepare(
|
|
973
|
-
`UPDATE embedding_cache SET accessed_at = unixepoch() WHERE hash = ? AND model = ? AND provider = ?`
|
|
974
|
-
).run(hash, this.model, this.id);
|
|
975
|
-
}
|
|
976
|
-
async warmup() {
|
|
977
|
-
return this.inner.warmup?.() ?? true;
|
|
978
|
-
}
|
|
979
|
-
async embedQuery(text) {
|
|
980
|
-
const hash = hashText(text);
|
|
981
|
-
const row = this.cacheGet(hash);
|
|
982
|
-
if (row) {
|
|
983
|
-
this.hits++;
|
|
984
|
-
this.cacheTouch(hash);
|
|
985
|
-
this.tick();
|
|
986
|
-
return deserializeEmbedding(row.embedding);
|
|
987
|
-
}
|
|
988
|
-
this.misses++;
|
|
989
|
-
const embedding = await this.inner.embedQuery(text);
|
|
990
|
-
this.cachePut(hash, serializeEmbedding(embedding));
|
|
991
|
-
this.tick();
|
|
992
|
-
return embedding;
|
|
993
|
-
}
|
|
994
|
-
async embedBatch(texts) {
|
|
995
|
-
if (texts.length === 0) return [];
|
|
996
|
-
const hashes = texts.map(hashText);
|
|
997
|
-
const results = new Array(texts.length).fill(null);
|
|
998
|
-
const missIndices = [];
|
|
999
|
-
const missTexts = [];
|
|
1000
|
-
for (let i = 0; i < texts.length; i++) {
|
|
1001
|
-
const row = this.cacheGet(hashes[i]);
|
|
1002
|
-
if (row) {
|
|
1003
|
-
this.hits++;
|
|
1004
|
-
this.cacheTouch(hashes[i]);
|
|
1005
|
-
results[i] = deserializeEmbedding(row.embedding);
|
|
1006
|
-
} else {
|
|
1007
|
-
this.misses++;
|
|
1008
|
-
missIndices.push(i);
|
|
1009
|
-
missTexts.push(texts[i]);
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
if (missTexts.length > 0) {
|
|
1013
|
-
const newEmbeddings = await this.inner.embedBatch(missTexts);
|
|
1014
|
-
for (let j = 0; j < missIndices.length; j++) {
|
|
1015
|
-
const idx = missIndices[j];
|
|
1016
|
-
const embedding = newEmbeddings[j] ?? [];
|
|
1017
|
-
results[idx] = embedding;
|
|
1018
|
-
if (embedding.length > 0) {
|
|
1019
|
-
this.cachePut(hashes[idx], serializeEmbedding(embedding));
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
this.ops += texts.length;
|
|
1024
|
-
this.maybeEvict();
|
|
1025
|
-
this.maybeLogStats();
|
|
1026
|
-
return results;
|
|
1027
|
-
}
|
|
1028
|
-
tick() {
|
|
1029
|
-
this.ops++;
|
|
1030
|
-
this.maybeEvict();
|
|
1031
|
-
this.maybeLogStats();
|
|
1032
|
-
}
|
|
1033
|
-
maybeLogStats() {
|
|
1034
|
-
const total = this.hits + this.misses;
|
|
1035
|
-
if (total > 0 && total % 100 === 0) {
|
|
1036
|
-
const rate = (this.hits / total * 100).toFixed(0);
|
|
1037
|
-
console.log(
|
|
1038
|
-
`\u{1F4CA} Embedding cache: ${this.hits} hits, ${this.misses} misses (${rate}% hit rate)`
|
|
1039
|
-
);
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
maybeEvict() {
|
|
1043
|
-
if (this.ops % EMBEDDING_CACHE_EVICTION_INTERVAL !== 0) return;
|
|
1044
|
-
try {
|
|
1045
|
-
const cutoff = Math.floor(Date.now() / 1e3) - EMBEDDING_CACHE_TTL_DAYS * 86400;
|
|
1046
|
-
this.db.prepare(`DELETE FROM embedding_cache WHERE accessed_at < ?`).run(cutoff);
|
|
1047
|
-
const count = this.db.prepare(`SELECT COUNT(*) as cnt FROM embedding_cache`).get().cnt;
|
|
1048
|
-
if (count > EMBEDDING_CACHE_MAX_ENTRIES) {
|
|
1049
|
-
const toDelete = Math.ceil(count * EMBEDDING_CACHE_EVICTION_RATIO);
|
|
1050
|
-
this.db.prepare(
|
|
1051
|
-
`DELETE FROM embedding_cache WHERE (hash, model, provider) IN (
|
|
1052
|
-
SELECT hash, model, provider FROM embedding_cache ORDER BY accessed_at ASC LIMIT ?
|
|
1053
|
-
)`
|
|
1054
|
-
).run(toDelete);
|
|
1055
|
-
console.log(`\u{1F9F9} Embedding cache eviction: removed ${toDelete} entries (${count} total)`);
|
|
1056
|
-
}
|
|
1057
|
-
} catch (err) {
|
|
1058
|
-
console.warn("\u26A0\uFE0F Embedding cache eviction error:", err);
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
};
|
|
1062
|
-
|
|
1063
|
-
// src/memory/embeddings/index.ts
|
|
1064
|
-
function createEmbeddingProvider(config) {
|
|
1065
|
-
switch (config.provider) {
|
|
1066
|
-
case "anthropic":
|
|
1067
|
-
if (!config.apiKey) {
|
|
1068
|
-
throw new Error("API key required for Anthropic embedding provider");
|
|
1069
|
-
}
|
|
1070
|
-
return new AnthropicEmbeddingProvider({
|
|
1071
|
-
apiKey: config.apiKey,
|
|
1072
|
-
model: config.model
|
|
1073
|
-
});
|
|
1074
|
-
case "local":
|
|
1075
|
-
return new LocalEmbeddingProvider({
|
|
1076
|
-
model: config.model
|
|
1077
|
-
});
|
|
1078
|
-
case "none":
|
|
1079
|
-
return new NoopEmbeddingProvider();
|
|
1080
|
-
default:
|
|
1081
|
-
throw new Error(`Unknown embedding provider: ${config.provider}`);
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
function hashText(text) {
|
|
1085
|
-
return createHash("sha256").update(text).digest("hex");
|
|
1086
|
-
}
|
|
1087
|
-
function serializeEmbedding(embedding) {
|
|
1088
|
-
return Buffer.from(new Float32Array(embedding).buffer);
|
|
1089
|
-
}
|
|
1090
|
-
function deserializeEmbedding(data) {
|
|
1091
|
-
try {
|
|
1092
|
-
if (Buffer.isBuffer(data)) {
|
|
1093
|
-
const floats = new Float32Array(data.buffer, data.byteOffset, data.byteLength / 4);
|
|
1094
|
-
return Array.from(floats);
|
|
1095
|
-
}
|
|
1096
|
-
return JSON.parse(data);
|
|
1097
|
-
} catch {
|
|
1098
|
-
return [];
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
669
|
// src/memory/agent/knowledge.ts
|
|
1103
|
-
import { readFileSync, existsSync as
|
|
1104
|
-
import { join
|
|
670
|
+
import { readFileSync, existsSync as existsSync2, readdirSync, statSync } from "fs";
|
|
671
|
+
import { join } from "path";
|
|
1105
672
|
var KnowledgeIndexer = class {
|
|
1106
673
|
constructor(db, workspaceDir, embedder, vectorEnabled) {
|
|
1107
674
|
this.db = db;
|
|
@@ -1124,7 +691,7 @@ var KnowledgeIndexer = class {
|
|
|
1124
691
|
return { indexed, skipped };
|
|
1125
692
|
}
|
|
1126
693
|
async indexFile(absPath) {
|
|
1127
|
-
if (!
|
|
694
|
+
if (!existsSync2(absPath) || !absPath.endsWith(".md")) {
|
|
1128
695
|
return false;
|
|
1129
696
|
}
|
|
1130
697
|
const content = readFileSync(absPath, "utf-8");
|
|
@@ -1172,15 +739,15 @@ var KnowledgeIndexer = class {
|
|
|
1172
739
|
}
|
|
1173
740
|
listMemoryFiles() {
|
|
1174
741
|
const files = [];
|
|
1175
|
-
const memoryMd =
|
|
1176
|
-
if (
|
|
742
|
+
const memoryMd = join(this.workspaceDir, "MEMORY.md");
|
|
743
|
+
if (existsSync2(memoryMd)) {
|
|
1177
744
|
files.push(memoryMd);
|
|
1178
745
|
}
|
|
1179
|
-
const memoryDir =
|
|
1180
|
-
if (
|
|
746
|
+
const memoryDir = join(this.workspaceDir, "memory");
|
|
747
|
+
if (existsSync2(memoryDir)) {
|
|
1181
748
|
const entries = readdirSync(memoryDir);
|
|
1182
749
|
for (const entry of entries) {
|
|
1183
|
-
const absPath =
|
|
750
|
+
const absPath = join(memoryDir, entry);
|
|
1184
751
|
if (statSync(absPath).isFile() && entry.endsWith(".md")) {
|
|
1185
752
|
files.push(absPath);
|
|
1186
753
|
}
|
|
@@ -1247,6 +814,7 @@ var KnowledgeIndexer = class {
|
|
|
1247
814
|
|
|
1248
815
|
// src/memory/agent/sessions.ts
|
|
1249
816
|
import { randomUUID } from "crypto";
|
|
817
|
+
var log3 = createLogger("Memory");
|
|
1250
818
|
var SessionStore = class {
|
|
1251
819
|
constructor(db, embedder, vectorEnabled) {
|
|
1252
820
|
this.db = db;
|
|
@@ -1367,13 +935,12 @@ ${session.summary}`;
|
|
|
1367
935
|
).run(knowledgeId, sessionId, text, hash);
|
|
1368
936
|
if (embedding && this.vectorEnabled) {
|
|
1369
937
|
const embeddingBuffer = serializeEmbedding(embedding);
|
|
1370
|
-
|
|
1371
|
-
this.db.prepare(`
|
|
1372
|
-
this.db.prepare(`INSERT INTO knowledge_vec (rowid, embedding) VALUES (?, ?)`).run(rowid.rowid, embeddingBuffer);
|
|
938
|
+
this.db.prepare(`DELETE FROM knowledge_vec WHERE id = ?`).run(knowledgeId);
|
|
939
|
+
this.db.prepare(`INSERT INTO knowledge_vec (id, embedding) VALUES (?, ?)`).run(knowledgeId, embeddingBuffer);
|
|
1373
940
|
}
|
|
1374
|
-
|
|
941
|
+
log3.info(`Indexed session ${sessionId} to knowledge base`);
|
|
1375
942
|
} catch (error) {
|
|
1376
|
-
|
|
943
|
+
log3.error({ err: error }, "Error indexing session");
|
|
1377
944
|
}
|
|
1378
945
|
}
|
|
1379
946
|
deleteSession(sessionId) {
|
|
@@ -1738,6 +1305,7 @@ var UserStore = class {
|
|
|
1738
1305
|
};
|
|
1739
1306
|
|
|
1740
1307
|
// src/memory/search/hybrid.ts
|
|
1308
|
+
var log4 = createLogger("Memory");
|
|
1741
1309
|
function escapeFts5Query(query) {
|
|
1742
1310
|
return query.replace(/["\*\-\+\(\)\:\^\~\?\.\@\#\$\%\&\!\[\]\{\}\|\\\/<>=,;'`]/g, " ").replace(/\s+/g, " ").trim();
|
|
1743
1311
|
}
|
|
@@ -1785,7 +1353,7 @@ var HybridSearch = class {
|
|
|
1785
1353
|
vectorScore: 1 - row.distance
|
|
1786
1354
|
}));
|
|
1787
1355
|
} catch (error) {
|
|
1788
|
-
|
|
1356
|
+
log4.error({ err: error }, "Vector search error (knowledge)");
|
|
1789
1357
|
return [];
|
|
1790
1358
|
}
|
|
1791
1359
|
}
|
|
@@ -1808,7 +1376,7 @@ var HybridSearch = class {
|
|
|
1808
1376
|
keywordScore: this.bm25ToScore(row.score)
|
|
1809
1377
|
}));
|
|
1810
1378
|
} catch (error) {
|
|
1811
|
-
|
|
1379
|
+
log4.error({ err: error }, "FTS5 search error (knowledge)");
|
|
1812
1380
|
return [];
|
|
1813
1381
|
}
|
|
1814
1382
|
}
|
|
@@ -1843,7 +1411,7 @@ var HybridSearch = class {
|
|
|
1843
1411
|
vectorScore: 1 - row.distance
|
|
1844
1412
|
}));
|
|
1845
1413
|
} catch (error) {
|
|
1846
|
-
|
|
1414
|
+
log4.error({ err: error }, "Vector search error (messages)");
|
|
1847
1415
|
return [];
|
|
1848
1416
|
}
|
|
1849
1417
|
}
|
|
@@ -1873,7 +1441,7 @@ var HybridSearch = class {
|
|
|
1873
1441
|
keywordScore: this.bm25ToScore(row.score)
|
|
1874
1442
|
}));
|
|
1875
1443
|
} catch (error) {
|
|
1876
|
-
|
|
1444
|
+
log4.error({ err: error }, "FTS5 search error (messages)");
|
|
1877
1445
|
return [];
|
|
1878
1446
|
}
|
|
1879
1447
|
}
|
|
@@ -1903,6 +1471,7 @@ var HybridSearch = class {
|
|
|
1903
1471
|
};
|
|
1904
1472
|
|
|
1905
1473
|
// src/memory/search/context.ts
|
|
1474
|
+
var log5 = createLogger("Memory");
|
|
1906
1475
|
var ContextBuilder = class {
|
|
1907
1476
|
constructor(db, embedder, vectorEnabled) {
|
|
1908
1477
|
this.db = db;
|
|
@@ -1936,7 +1505,7 @@ var ContextBuilder = class {
|
|
|
1936
1505
|
});
|
|
1937
1506
|
relevantKnowledge.push(...knowledgeResults.map((r) => r.text));
|
|
1938
1507
|
} catch (error) {
|
|
1939
|
-
|
|
1508
|
+
log5.warn({ err: error }, "Knowledge search failed");
|
|
1940
1509
|
}
|
|
1941
1510
|
}
|
|
1942
1511
|
const recentTextsSet = new Set(
|
|
@@ -1966,7 +1535,7 @@ var ContextBuilder = class {
|
|
|
1966
1535
|
}
|
|
1967
1536
|
}
|
|
1968
1537
|
} catch (error) {
|
|
1969
|
-
|
|
1538
|
+
log5.warn({ err: error }, "Feed search failed");
|
|
1970
1539
|
}
|
|
1971
1540
|
if (relevantFeed.length === 0 && recentTgMessages.length > 0) {
|
|
1972
1541
|
const recentTexts = recentTgMessages.filter((m) => m.text && m.text.length > 0).slice(-maxRelevantChunks).map((m) => {
|
|
@@ -2004,11 +1573,6 @@ function initializeMemory(config) {
|
|
|
2004
1573
|
}
|
|
2005
1574
|
|
|
2006
1575
|
export {
|
|
2007
|
-
JOURNAL_SCHEMA,
|
|
2008
|
-
USED_TRANSACTIONS_SCHEMA,
|
|
2009
|
-
openModuleDb,
|
|
2010
|
-
createDbWrapper,
|
|
2011
|
-
migrateFromMainDb,
|
|
2012
1576
|
ensureSchema,
|
|
2013
1577
|
ensureVectorTables,
|
|
2014
1578
|
getSchemaVersion,
|
|
@@ -2018,22 +1582,6 @@ export {
|
|
|
2018
1582
|
MemoryDatabase,
|
|
2019
1583
|
getDatabase,
|
|
2020
1584
|
closeDatabase,
|
|
2021
|
-
NoopEmbeddingProvider,
|
|
2022
|
-
fetchWithTimeout,
|
|
2023
|
-
setTonapiKey,
|
|
2024
|
-
tonapiFetch,
|
|
2025
|
-
STONFI_API_BASE_URL,
|
|
2026
|
-
GECKOTERMINAL_API_URL,
|
|
2027
|
-
COINGECKO_API_URL,
|
|
2028
|
-
OPENAI_TTS_URL,
|
|
2029
|
-
ELEVENLABS_TTS_URL,
|
|
2030
|
-
AnthropicEmbeddingProvider,
|
|
2031
|
-
LocalEmbeddingProvider,
|
|
2032
|
-
CachedEmbeddingProvider,
|
|
2033
|
-
createEmbeddingProvider,
|
|
2034
|
-
hashText,
|
|
2035
|
-
serializeEmbedding,
|
|
2036
|
-
deserializeEmbedding,
|
|
2037
1585
|
KnowledgeIndexer,
|
|
2038
1586
|
SessionStore,
|
|
2039
1587
|
MessageStore,
|