teleton 0.1.21 → 0.2.2

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 CHANGED
@@ -397,6 +397,14 @@ Contributions are welcome.
397
397
 
398
398
  ---
399
399
 
400
+ ## Contributors
401
+
402
+ <a href="https://github.com/TONresistor/teleton-agent/graphs/contributors">
403
+ <img src="https://contrib.rocks/image?repo=TONresistor/teleton-agent" />
404
+ </a>
405
+
406
+ ---
407
+
400
408
  ## License
401
409
 
402
410
  MIT License - See [LICENSE](LICENSE) for details.
@@ -9,12 +9,123 @@ import {
9
9
  SQLITE_MMAP_SIZE,
10
10
  VOYAGE_BATCH_SIZE
11
11
  } from "./chunk-QMN6ZOA5.js";
12
+ import {
13
+ TELETON_ROOT
14
+ } from "./chunk-EYWNOHMJ.js";
12
15
 
13
16
  // src/memory/database.ts
17
+ import Database2 from "better-sqlite3";
18
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
19
+ import { dirname as dirname2 } from "path";
20
+ import * as sqliteVec from "sqlite-vec";
21
+
22
+ // src/utils/module-db.ts
14
23
  import Database from "better-sqlite3";
15
24
  import { existsSync, mkdirSync } from "fs";
16
- import { dirname } from "path";
17
- import * as sqliteVec from "sqlite-vec";
25
+ import { dirname, join } from "path";
26
+ var JOURNAL_SCHEMA = `
27
+ CREATE TABLE IF NOT EXISTS journal (
28
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
29
+ timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
30
+ type TEXT NOT NULL CHECK(type IN ('trade', 'gift', 'middleman', 'kol')),
31
+ action TEXT NOT NULL,
32
+ asset_from TEXT,
33
+ asset_to TEXT,
34
+ amount_from REAL,
35
+ amount_to REAL,
36
+ price_ton REAL,
37
+ counterparty TEXT,
38
+ platform TEXT,
39
+ reasoning TEXT,
40
+ outcome TEXT CHECK(outcome IN ('pending', 'profit', 'loss', 'neutral', 'cancelled')),
41
+ pnl_ton REAL,
42
+ pnl_pct REAL,
43
+ tx_hash TEXT,
44
+ tool_used TEXT,
45
+ chat_id TEXT,
46
+ user_id INTEGER,
47
+ closed_at INTEGER,
48
+ created_at INTEGER NOT NULL DEFAULT (unixepoch())
49
+ );
50
+
51
+ CREATE INDEX IF NOT EXISTS idx_journal_type ON journal(type);
52
+ CREATE INDEX IF NOT EXISTS idx_journal_timestamp ON journal(timestamp DESC);
53
+ CREATE INDEX IF NOT EXISTS idx_journal_asset_from ON journal(asset_from);
54
+ CREATE INDEX IF NOT EXISTS idx_journal_outcome ON journal(outcome);
55
+ CREATE INDEX IF NOT EXISTS idx_journal_type_timestamp ON journal(type, timestamp DESC);
56
+ `;
57
+ var USED_TRANSACTIONS_SCHEMA = `
58
+ CREATE TABLE IF NOT EXISTS used_transactions (
59
+ tx_hash TEXT PRIMARY KEY,
60
+ user_id TEXT NOT NULL,
61
+ amount REAL NOT NULL,
62
+ game_type TEXT NOT NULL,
63
+ used_at INTEGER NOT NULL DEFAULT (unixepoch())
64
+ );
65
+
66
+ CREATE INDEX IF NOT EXISTS idx_used_tx_user ON used_transactions(user_id);
67
+ CREATE INDEX IF NOT EXISTS idx_used_tx_used_at ON used_transactions(used_at);
68
+ `;
69
+ function openModuleDb(path) {
70
+ const dir = dirname(path);
71
+ if (!existsSync(dir)) {
72
+ mkdirSync(dir, { recursive: true });
73
+ }
74
+ const db = new Database(path);
75
+ db.pragma("journal_mode = WAL");
76
+ return db;
77
+ }
78
+ function createDbWrapper(getDb, moduleName) {
79
+ return function withDb(executor) {
80
+ return (params, context) => {
81
+ const moduleDb = getDb();
82
+ if (!moduleDb) {
83
+ return Promise.resolve({
84
+ success: false,
85
+ error: `${moduleName} module not started`
86
+ });
87
+ }
88
+ return executor(params, { ...context, db: moduleDb });
89
+ };
90
+ };
91
+ }
92
+ var MAIN_DB_PATH = join(TELETON_ROOT, "memory.db");
93
+ function migrateFromMainDb(moduleDb, tables) {
94
+ let totalMigrated = 0;
95
+ for (const table of tables) {
96
+ try {
97
+ const row = moduleDb.prepare(`SELECT COUNT(*) as c FROM ${table}`).get();
98
+ if (row.c > 0) return 0;
99
+ } catch {
100
+ continue;
101
+ }
102
+ }
103
+ if (!existsSync(MAIN_DB_PATH)) return 0;
104
+ try {
105
+ moduleDb.exec(`ATTACH DATABASE '${MAIN_DB_PATH}' AS main_db`);
106
+ for (const table of tables) {
107
+ try {
108
+ const exists = moduleDb.prepare(`SELECT name FROM main_db.sqlite_master WHERE type='table' AND name=?`).get(table);
109
+ if (!exists) continue;
110
+ const src = moduleDb.prepare(`SELECT COUNT(*) as c FROM main_db.${table}`).get();
111
+ if (src.c === 0) continue;
112
+ moduleDb.exec(`INSERT OR IGNORE INTO ${table} SELECT * FROM main_db.${table}`);
113
+ totalMigrated += src.c;
114
+ console.log(` \u{1F4E6} Migrated ${src.c} rows from memory.db \u2192 ${table}`);
115
+ } catch (e) {
116
+ console.warn(` \u26A0\uFE0F Could not migrate table ${table}:`, e);
117
+ }
118
+ }
119
+ moduleDb.exec(`DETACH DATABASE main_db`);
120
+ } catch (e) {
121
+ console.warn(`\u26A0\uFE0F Migration from memory.db failed:`, e);
122
+ try {
123
+ moduleDb.exec(`DETACH DATABASE main_db`);
124
+ } catch {
125
+ }
126
+ }
127
+ return totalMigrated;
128
+ }
18
129
 
19
130
  // src/memory/schema.ts
20
131
  function compareSemver(a, b) {
@@ -263,70 +374,10 @@ function ensureSchema(db) {
263
374
  CREATE INDEX IF NOT EXISTS idx_embedding_cache_model ON embedding_cache(provider, model);
264
375
  CREATE INDEX IF NOT EXISTS idx_embedding_cache_accessed ON embedding_cache(accessed_at);
265
376
 
266
- -- =====================================================
267
- -- CASINO
268
- -- =====================================================
269
-
270
- CREATE TABLE IF NOT EXISTS casino_users (
271
- telegram_id TEXT PRIMARY KEY,
272
- wallet_address TEXT,
273
- total_bets INTEGER NOT NULL DEFAULT 0,
274
- total_wagered REAL NOT NULL DEFAULT 0,
275
- total_wins INTEGER NOT NULL DEFAULT 0,
276
- total_losses INTEGER NOT NULL DEFAULT 0,
277
- total_won REAL NOT NULL DEFAULT 0,
278
- last_bet_at INTEGER
279
- );
280
-
281
- CREATE TABLE IF NOT EXISTS used_transactions (
282
- tx_hash TEXT PRIMARY KEY,
283
- user_id TEXT NOT NULL,
284
- amount REAL NOT NULL,
285
- game_type TEXT NOT NULL,
286
- used_at INTEGER NOT NULL DEFAULT (unixepoch())
287
- );
288
-
289
- CREATE INDEX IF NOT EXISTS idx_used_tx_user ON used_transactions(user_id);
290
- CREATE INDEX IF NOT EXISTS idx_used_tx_used_at ON used_transactions(used_at);
291
-
292
- CREATE TABLE IF NOT EXISTS casino_cooldowns (
293
- user_id TEXT PRIMARY KEY,
294
- last_spin_at INTEGER NOT NULL
295
- );
296
-
297
377
  -- =====================================================
298
378
  -- JOURNAL (Trading & Business Operations)
299
379
  -- =====================================================
300
-
301
- CREATE TABLE IF NOT EXISTS journal (
302
- id INTEGER PRIMARY KEY AUTOINCREMENT,
303
- timestamp INTEGER NOT NULL DEFAULT (unixepoch()),
304
- type TEXT NOT NULL CHECK(type IN ('trade', 'gift', 'middleman', 'kol')),
305
- action TEXT NOT NULL,
306
- asset_from TEXT,
307
- asset_to TEXT,
308
- amount_from REAL,
309
- amount_to REAL,
310
- price_ton REAL,
311
- counterparty TEXT,
312
- platform TEXT,
313
- reasoning TEXT,
314
- outcome TEXT CHECK(outcome IN ('pending', 'profit', 'loss', 'neutral', 'cancelled')),
315
- pnl_ton REAL,
316
- pnl_pct REAL,
317
- tx_hash TEXT,
318
- tool_used TEXT,
319
- chat_id TEXT,
320
- user_id INTEGER,
321
- closed_at INTEGER,
322
- created_at INTEGER NOT NULL DEFAULT (unixepoch())
323
- );
324
-
325
- CREATE INDEX IF NOT EXISTS idx_journal_type ON journal(type);
326
- CREATE INDEX IF NOT EXISTS idx_journal_timestamp ON journal(timestamp DESC);
327
- CREATE INDEX IF NOT EXISTS idx_journal_asset_from ON journal(asset_from);
328
- CREATE INDEX IF NOT EXISTS idx_journal_outcome ON journal(outcome);
329
- CREATE INDEX IF NOT EXISTS idx_journal_type_timestamp ON journal(type, timestamp DESC);
380
+ ${JOURNAL_SCHEMA}
330
381
  `);
331
382
  }
332
383
  function ensureVectorTables(db, dimensions) {
@@ -449,225 +500,6 @@ function runMigrations(db) {
449
500
  throw error;
450
501
  }
451
502
  }
452
- if (!currentVersion || versionLessThan(currentVersion, "1.5.0")) {
453
- try {
454
- console.log("\u{1F504} Running migration 1.5.0: Add deals system for secure trading");
455
- db.exec(`
456
- CREATE TABLE IF NOT EXISTS deals (
457
- id TEXT PRIMARY KEY,
458
- status TEXT NOT NULL CHECK(status IN (
459
- 'proposed', 'accepted', 'payment_claimed', 'verified', 'completed',
460
- 'declined', 'expired', 'cancelled', 'failed'
461
- )),
462
-
463
- -- Parties
464
- user_telegram_id INTEGER NOT NULL,
465
- user_username TEXT,
466
- chat_id TEXT NOT NULL,
467
- proposal_message_id INTEGER,
468
-
469
- -- What USER gives
470
- user_gives_type TEXT NOT NULL CHECK(user_gives_type IN ('ton', 'gift')),
471
- user_gives_ton_amount REAL,
472
- user_gives_gift_id TEXT,
473
- user_gives_gift_slug TEXT,
474
- user_gives_value_ton REAL NOT NULL,
475
-
476
- -- What AGENT gives
477
- agent_gives_type TEXT NOT NULL CHECK(agent_gives_type IN ('ton', 'gift')),
478
- agent_gives_ton_amount REAL,
479
- agent_gives_gift_id TEXT,
480
- agent_gives_gift_slug TEXT,
481
- agent_gives_value_ton REAL NOT NULL,
482
-
483
- -- Payment/Gift verification
484
- user_payment_verified_at INTEGER,
485
- user_payment_tx_hash TEXT,
486
- user_payment_gift_msgid TEXT,
487
- user_payment_wallet TEXT,
488
-
489
- -- Agent send tracking
490
- agent_sent_at INTEGER,
491
- agent_sent_tx_hash TEXT,
492
- agent_sent_gift_msgid TEXT,
493
-
494
- -- Business logic
495
- strategy_check TEXT,
496
- profit_ton REAL,
497
-
498
- -- Timestamps
499
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
500
- expires_at INTEGER NOT NULL,
501
- completed_at INTEGER,
502
-
503
- notes TEXT
504
- );
505
-
506
- CREATE INDEX IF NOT EXISTS idx_deals_status ON deals(status);
507
- CREATE INDEX IF NOT EXISTS idx_deals_user ON deals(user_telegram_id);
508
- CREATE INDEX IF NOT EXISTS idx_deals_chat ON deals(chat_id);
509
- CREATE INDEX IF NOT EXISTS idx_deals_expires ON deals(expires_at)
510
- WHERE status IN ('proposed', 'accepted');
511
- `);
512
- console.log("\u2705 Migration 1.5.0 complete: Deals system added");
513
- } catch (error) {
514
- console.error("\u274C Migration 1.5.0 failed:", error);
515
- throw error;
516
- }
517
- }
518
- if (!currentVersion || versionLessThan(currentVersion, "1.6.0")) {
519
- try {
520
- console.log("\u{1F504} Running migration 1.6.0: Add bot inline tracking + payment_claimed status");
521
- const dealsExists = db.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='deals'").get();
522
- if (dealsExists) {
523
- const tableSql = db.prepare("SELECT sql FROM sqlite_master WHERE type='table' AND name='deals'").get()?.sql || "";
524
- if (!tableSql.includes("payment_claimed")) {
525
- db.exec(`
526
- ALTER TABLE deals RENAME TO deals_old;
527
-
528
- CREATE TABLE deals (
529
- id TEXT PRIMARY KEY,
530
- status TEXT NOT NULL CHECK(status IN (
531
- 'proposed', 'accepted', 'payment_claimed', 'verified', 'completed',
532
- 'declined', 'expired', 'cancelled', 'failed'
533
- )),
534
- user_telegram_id INTEGER NOT NULL,
535
- user_username TEXT,
536
- chat_id TEXT NOT NULL,
537
- proposal_message_id INTEGER,
538
- user_gives_type TEXT NOT NULL CHECK(user_gives_type IN ('ton', 'gift')),
539
- user_gives_ton_amount REAL,
540
- user_gives_gift_id TEXT,
541
- user_gives_gift_slug TEXT,
542
- user_gives_value_ton REAL NOT NULL,
543
- agent_gives_type TEXT NOT NULL CHECK(agent_gives_type IN ('ton', 'gift')),
544
- agent_gives_ton_amount REAL,
545
- agent_gives_gift_id TEXT,
546
- agent_gives_gift_slug TEXT,
547
- agent_gives_value_ton REAL NOT NULL,
548
- user_payment_verified_at INTEGER,
549
- user_payment_tx_hash TEXT,
550
- user_payment_gift_msgid TEXT,
551
- user_payment_wallet TEXT,
552
- agent_sent_at INTEGER,
553
- agent_sent_tx_hash TEXT,
554
- agent_sent_gift_msgid TEXT,
555
- strategy_check TEXT,
556
- profit_ton REAL,
557
- created_at INTEGER NOT NULL DEFAULT (unixepoch()),
558
- expires_at INTEGER NOT NULL,
559
- completed_at INTEGER,
560
- notes TEXT,
561
- inline_message_id TEXT,
562
- payment_claimed_at INTEGER
563
- );
564
-
565
- INSERT INTO deals (
566
- id, status, user_telegram_id, user_username, chat_id, proposal_message_id,
567
- user_gives_type, user_gives_ton_amount, user_gives_gift_id, user_gives_gift_slug, user_gives_value_ton,
568
- agent_gives_type, agent_gives_ton_amount, agent_gives_gift_id, agent_gives_gift_slug, agent_gives_value_ton,
569
- user_payment_verified_at, user_payment_tx_hash, user_payment_gift_msgid, user_payment_wallet,
570
- agent_sent_at, agent_sent_tx_hash, agent_sent_gift_msgid,
571
- strategy_check, profit_ton, created_at, expires_at, completed_at, notes
572
- )
573
- SELECT
574
- id, status, user_telegram_id, user_username, chat_id, proposal_message_id,
575
- user_gives_type, user_gives_ton_amount, user_gives_gift_id, user_gives_gift_slug, user_gives_value_ton,
576
- agent_gives_type, agent_gives_ton_amount, agent_gives_gift_id, agent_gives_gift_slug, agent_gives_value_ton,
577
- user_payment_verified_at, user_payment_tx_hash, user_payment_gift_msgid, user_payment_wallet,
578
- agent_sent_at, agent_sent_tx_hash, agent_sent_gift_msgid,
579
- strategy_check, profit_ton, created_at, expires_at, completed_at, notes
580
- FROM deals_old;
581
-
582
- DROP TABLE deals_old;
583
-
584
- CREATE INDEX IF NOT EXISTS idx_deals_status ON deals(status);
585
- CREATE INDEX IF NOT EXISTS idx_deals_user ON deals(user_telegram_id);
586
- CREATE INDEX IF NOT EXISTS idx_deals_chat ON deals(chat_id);
587
- CREATE INDEX IF NOT EXISTS idx_deals_inline_msg ON deals(inline_message_id)
588
- WHERE inline_message_id IS NOT NULL;
589
- CREATE INDEX IF NOT EXISTS idx_deals_payment_claimed ON deals(payment_claimed_at)
590
- WHERE payment_claimed_at IS NOT NULL;
591
- `);
592
- } else {
593
- const columns = db.prepare(`PRAGMA table_info(deals)`).all();
594
- const columnNames = columns.map((c) => c.name);
595
- if (!columnNames.includes("inline_message_id")) {
596
- db.exec(`ALTER TABLE deals ADD COLUMN inline_message_id TEXT`);
597
- }
598
- if (!columnNames.includes("payment_claimed_at")) {
599
- db.exec(`ALTER TABLE deals ADD COLUMN payment_claimed_at INTEGER`);
600
- }
601
- }
602
- }
603
- db.exec(`
604
- CREATE TABLE IF NOT EXISTS user_trade_stats (
605
- telegram_id INTEGER PRIMARY KEY,
606
- username TEXT,
607
- first_trade_at INTEGER DEFAULT (unixepoch()),
608
- total_deals INTEGER DEFAULT 0,
609
- completed_deals INTEGER DEFAULT 0,
610
- declined_deals INTEGER DEFAULT 0,
611
- total_ton_sent REAL DEFAULT 0,
612
- total_ton_received REAL DEFAULT 0,
613
- total_gifts_sent INTEGER DEFAULT 0,
614
- total_gifts_received INTEGER DEFAULT 0,
615
- last_deal_at INTEGER
616
- );
617
- `);
618
- console.log("\u2705 Migration 1.6.0 complete: Bot inline tracking + payment_claimed added");
619
- } catch (error) {
620
- console.error("\u274C Migration 1.6.0 failed:", error);
621
- throw error;
622
- }
623
- }
624
- if (!currentVersion || versionLessThan(currentVersion, "1.7.0")) {
625
- try {
626
- console.log("\u{1F504} Running migration 1.7.0: Add casino tables");
627
- db.exec(`
628
- CREATE TABLE IF NOT EXISTS casino_users (
629
- telegram_id TEXT PRIMARY KEY,
630
- wallet_address TEXT,
631
- total_bets INTEGER NOT NULL DEFAULT 0,
632
- total_wagered REAL NOT NULL DEFAULT 0,
633
- total_wins INTEGER NOT NULL DEFAULT 0,
634
- total_losses INTEGER NOT NULL DEFAULT 0,
635
- total_won REAL NOT NULL DEFAULT 0,
636
- last_bet_at INTEGER
637
- );
638
-
639
- CREATE TABLE IF NOT EXISTS used_transactions (
640
- tx_hash TEXT PRIMARY KEY,
641
- user_id TEXT NOT NULL,
642
- amount REAL NOT NULL,
643
- game_type TEXT NOT NULL,
644
- used_at INTEGER NOT NULL DEFAULT (unixepoch())
645
- );
646
-
647
- CREATE INDEX IF NOT EXISTS idx_used_tx_user ON used_transactions(user_id);
648
- CREATE INDEX IF NOT EXISTS idx_used_tx_used_at ON used_transactions(used_at);
649
-
650
- CREATE TABLE IF NOT EXISTS casino_cooldowns (
651
- user_id TEXT PRIMARY KEY,
652
- last_spin_at INTEGER NOT NULL
653
- );
654
- `);
655
- console.log("\u2705 Migration 1.7.0 complete: Casino tables added");
656
- } catch (error) {
657
- console.error("\u274C Migration 1.7.0 failed:", error);
658
- throw error;
659
- }
660
- }
661
- if (!currentVersion || versionLessThan(currentVersion, "1.8.0")) {
662
- try {
663
- console.log("\u{1F504} Running migration 1.8.0: Remove casino_jackpot table");
664
- db.exec(`DROP TABLE IF EXISTS casino_jackpot;`);
665
- console.log("\u2705 Migration 1.8.0 complete: casino_jackpot removed");
666
- } catch (error) {
667
- console.error("\u274C Migration 1.8.0 failed:", error);
668
- throw error;
669
- }
670
- }
671
503
  setSchemaVersion(db, CURRENT_SCHEMA_VERSION);
672
504
  }
673
505
 
@@ -678,11 +510,11 @@ var MemoryDatabase = class {
678
510
  vectorReady = false;
679
511
  constructor(config) {
680
512
  this.config = config;
681
- const dir = dirname(config.path);
682
- if (!existsSync(dir)) {
683
- mkdirSync(dir, { recursive: true });
513
+ const dir = dirname2(config.path);
514
+ if (!existsSync2(dir)) {
515
+ mkdirSync2(dir, { recursive: true });
684
516
  }
685
- this.db = new Database(config.path, {
517
+ this.db = new Database2(config.path, {
686
518
  verbose: process.env.DEBUG_SQL ? console.log : void 0
687
519
  });
688
520
  this.db.pragma("journal_mode = WAL");
@@ -1004,8 +836,8 @@ function embeddingToBlob(embedding) {
1004
836
  }
1005
837
 
1006
838
  // src/memory/agent/knowledge.ts
1007
- import { readFileSync, existsSync as existsSync2, readdirSync, statSync } from "fs";
1008
- import { join } from "path";
839
+ import { readFileSync, existsSync as existsSync3, readdirSync, statSync } from "fs";
840
+ import { join as join2 } from "path";
1009
841
  var KnowledgeIndexer = class {
1010
842
  constructor(db, workspaceDir, embedder, vectorEnabled) {
1011
843
  this.db = db;
@@ -1034,7 +866,7 @@ var KnowledgeIndexer = class {
1034
866
  * Index a single file
1035
867
  */
1036
868
  async indexFile(absPath) {
1037
- if (!existsSync2(absPath) || !absPath.endsWith(".md")) {
869
+ if (!existsSync3(absPath) || !absPath.endsWith(".md")) {
1038
870
  return false;
1039
871
  }
1040
872
  const content = readFileSync(absPath, "utf-8");
@@ -1076,15 +908,15 @@ var KnowledgeIndexer = class {
1076
908
  */
1077
909
  listMemoryFiles() {
1078
910
  const files = [];
1079
- const memoryMd = join(this.workspaceDir, "MEMORY.md");
1080
- if (existsSync2(memoryMd)) {
911
+ const memoryMd = join2(this.workspaceDir, "MEMORY.md");
912
+ if (existsSync3(memoryMd)) {
1081
913
  files.push(memoryMd);
1082
914
  }
1083
- const memoryDir = join(this.workspaceDir, "memory");
1084
- if (existsSync2(memoryDir)) {
915
+ const memoryDir = join2(this.workspaceDir, "memory");
916
+ if (existsSync3(memoryDir)) {
1085
917
  const entries = readdirSync(memoryDir);
1086
918
  for (const entry of entries) {
1087
- const absPath = join(memoryDir, entry);
919
+ const absPath = join2(memoryDir, entry);
1088
920
  if (statSync(absPath).isFile() && entry.endsWith(".md")) {
1089
921
  files.push(absPath);
1090
922
  }
@@ -1989,6 +1821,11 @@ function initializeMemory(config) {
1989
1821
  }
1990
1822
 
1991
1823
  export {
1824
+ JOURNAL_SCHEMA,
1825
+ USED_TRANSACTIONS_SCHEMA,
1826
+ openModuleDb,
1827
+ createDbWrapper,
1828
+ migrateFromMainDb,
1992
1829
  ensureSchema,
1993
1830
  ensureVectorTables,
1994
1831
  getSchemaVersion,