teleton 0.3.0 → 0.4.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 +144 -95
- package/dist/{chunk-LCMHAUNK.js → chunk-67QC5FBN.js} +0 -2
- package/dist/{chunk-QQW6KE7Q.js → chunk-7UPH62J2.js} +34 -21
- package/dist/{chunk-DAMFGHXV.js → chunk-A64NPEFL.js} +1 -1
- package/dist/chunk-EHEV7FJ7.js +157 -0
- package/dist/{chunk-UYF4TT44.js → chunk-OA5L7GM6.js} +1 -1
- package/dist/chunk-QBGUCUOW.js +16 -0
- package/dist/{chunk-ILDG4OPK.js → chunk-QU4ZOR35.js} +6386 -6821
- package/dist/cli/index.js +13 -14
- package/dist/endpoint-FT2B2RZ2.js +7 -0
- package/dist/format-transactions-FD74HI5N.js +9 -0
- package/dist/index.js +7 -5
- package/dist/{memory-ZXDAJBL6.js → memory-SYTQ5P7P.js} +4 -4
- package/dist/{migrate-7OG67FXP.js → migrate-ITXMRRSZ.js} +4 -4
- package/dist/{scraper-KXRBQMVQ.js → scraper-SH7GS7TO.js} +6 -6
- package/dist/{task-dependency-resolver-S45DFI5C.js → task-dependency-resolver-GY6PEBIS.js} +4 -4
- package/dist/{task-executor-AUTT3VAL.js → task-executor-4QKTZZ3P.js} +1 -1
- package/package.json +1 -1
- package/src/templates/IDENTITY.md +1 -1
- package/src/templates/MEMORY.md +1 -0
- package/src/templates/SECURITY.md +5 -0
- package/src/templates/SOUL.md +3 -2
- package/dist/timeouts-ZAK6NELA.js +0 -63
package/README.md
CHANGED
|
@@ -6,25 +6,22 @@
|
|
|
6
6
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
7
7
|
<a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen" alt="Node.js"></a>
|
|
8
8
|
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-5.7-blue" alt="TypeScript"></a>
|
|
9
|
-
<a href="https://
|
|
9
|
+
<a href="https://teletonagent.dev"><img src="https://img.shields.io/badge/Website-teletonagent.dev-ff6600" alt="Website"></a>
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
Teleton is a production-grade autonomous AI agent that operates as a real Telegram user account (not a bot), powered by multi-provider LLM support. It provides full access to the Telegram API with deep TON blockchain integration for cryptocurrency trading, NFT marketplace operations, and decentralized finance.
|
|
14
|
+
<p align="center">Teleton is a production-grade autonomous AI agent that operates as a real Telegram user account (not a bot), powered by multi-provider LLM support. It provides full access to the Telegram API with deep TON blockchain integration for cryptocurrency operations, DEX trading, and decentralized finance.</p>
|
|
17
15
|
|
|
18
16
|
### Key Highlights
|
|
19
17
|
|
|
20
18
|
- **Full Telegram access**: Operates as a real user with the full API, not a limited bot
|
|
21
19
|
- **Multi-Provider LLM**: Anthropic, OpenAI, Google Gemini, xAI Grok, Groq, OpenRouter
|
|
22
|
-
- **TON Blockchain**: Built-in wallet, send/receive TON, swap
|
|
23
|
-
- **Gift trading**: Buy and sell Telegram collectible gifts with real-time floor prices and strategy enforcement
|
|
20
|
+
- **TON Blockchain**: Built-in wallet, send/receive TON & jettons, swap on STON.fi and DeDust, NFTs
|
|
24
21
|
- **Persistent memory**: Remembers context across restarts with automatic context management
|
|
25
|
-
- **
|
|
26
|
-
- **Plugin
|
|
27
|
-
- **Secure by design**: Sandboxed workspace, immutable config,
|
|
22
|
+
- **116 built-in tools**: Messaging, media, blockchain, DEX trading, deals, market, DNS, journaling, and more
|
|
23
|
+
- **Plugin SDK**: Extend the agent with custom tools — full access to TON and Telegram APIs via namespaced SDK
|
|
24
|
+
- **Secure by design**: Sandboxed workspace, immutable config, prompt injection defense
|
|
28
25
|
|
|
29
26
|
---
|
|
30
27
|
|
|
@@ -34,27 +31,25 @@ Teleton is a production-grade autonomous AI agent that operates as a real Telegr
|
|
|
34
31
|
|
|
35
32
|
| Category | Tools | Description |
|
|
36
33
|
|----------|-------|-------------|
|
|
37
|
-
| Telegram |
|
|
38
|
-
| TON
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
| Workspace | 6 | Sandboxed file operations with security validation |
|
|
34
|
+
| Telegram | 66 | Messaging, media, chats, groups, polls, stickers, gifts, stars, stories, contacts, folders, profile, memory, tasks |
|
|
35
|
+
| TON & Jettons | 15 | W5R1 wallet, send/receive TON & jettons, balances, prices, holders, history, charts, NFTs, DEX quotes |
|
|
36
|
+
| STON.fi DEX | 5 | Swap, quote, search, trending tokens, liquidity pools |
|
|
37
|
+
| DeDust DEX | 5 | Swap, quote, pools, prices, token info |
|
|
38
|
+
| TON DNS | 7 | Domain auctions, bidding, linking, resolution, availability checks |
|
|
39
|
+
| Deals | 5 | Secure gift/TON trading with strategy enforcement and inline bot confirmations |
|
|
40
|
+
| Market | 4 | Gift floor prices, search, cheapest listings, price history |
|
|
41
|
+
| Journal | 3 | Trade/operation logging with natural language queries |
|
|
42
|
+
| Workspace | 6 | Sandboxed file operations with path traversal protection |
|
|
47
43
|
|
|
48
44
|
### Advanced Capabilities
|
|
49
45
|
|
|
50
46
|
| Capability | Description |
|
|
51
47
|
|-----------|-------------|
|
|
52
48
|
| **Multi-Provider LLM** | Switch between Anthropic, OpenAI, Google, xAI, Groq, OpenRouter with one config change |
|
|
53
|
-
| **RAG Search** |
|
|
49
|
+
| **RAG + Hybrid Search** | Local embeddings with FTS5 keyword + sqlite-vec semantic search |
|
|
54
50
|
| **Auto-Compaction** | AI-summarized context management prevents overflow, preserves key information |
|
|
55
51
|
| **Observation Masking** | Compresses old tool results to save ~90% context window |
|
|
56
|
-
| **
|
|
57
|
-
| **Deals System** | Secure gift/TON trading with code-enforced strategy rules and inline bot confirmations |
|
|
52
|
+
| **Plugin SDK** | Namespaced SDK (`sdk.ton`, `sdk.telegram`) with isolated databases and lifecycle hooks |
|
|
58
53
|
| **Vision Analysis** | Image understanding via multimodal LLM |
|
|
59
54
|
| **Voice Synthesis** | Text-to-speech for voice messages |
|
|
60
55
|
| **Scheduled Tasks** | Time-based task execution with dependency resolution |
|
|
@@ -72,7 +67,7 @@ Teleton is a production-grade autonomous AI agent that operates as a real Telegr
|
|
|
72
67
|
- **Telegram Account** - Dedicated account recommended for security
|
|
73
68
|
- **Telegram API Credentials** - From [my.telegram.org/apps](https://my.telegram.org/apps)
|
|
74
69
|
- **Your Telegram User ID** - Message [@userinfobot](https://t.me/userinfobot)
|
|
75
|
-
- **Bot Token** *(optional
|
|
70
|
+
- **Bot Token** *(optional)* - From [@BotFather](https://t.me/BotFather) for inline bot features
|
|
76
71
|
|
|
77
72
|
> **Security Warning**: The agent will have full control over the Telegram account. Use a dedicated account, not your main one.
|
|
78
73
|
|
|
@@ -100,7 +95,7 @@ docker run -it -v ~/.teleton:/data ghcr.io/tonresistor/teleton-agent:latest setu
|
|
|
100
95
|
**From source (development):**
|
|
101
96
|
```bash
|
|
102
97
|
git clone https://github.com/TONresistor/teleton-agent.git
|
|
103
|
-
cd teleton
|
|
98
|
+
cd teleton-agent
|
|
104
99
|
npm install && npm run build
|
|
105
100
|
```
|
|
106
101
|
|
|
@@ -168,9 +163,9 @@ telegram:
|
|
|
168
163
|
owner_name: "Your Name"
|
|
169
164
|
owner_username: "your_username"
|
|
170
165
|
|
|
171
|
-
# Optional: inline bot for
|
|
166
|
+
# Optional: inline bot for interactive features
|
|
172
167
|
bot_token: "123456:ABC-DEF..."
|
|
173
|
-
bot_username: "
|
|
168
|
+
bot_username: "your_bot"
|
|
174
169
|
|
|
175
170
|
session_reset_policy:
|
|
176
171
|
daily_reset_enabled: true
|
|
@@ -223,7 +218,7 @@ The agent's personality and rules are configured via markdown files in `~/.telet
|
|
|
223
218
|
|-------|------------|
|
|
224
219
|
| LLM | Multi-provider via [pi-ai](https://github.com/mariozechner/pi-ai) (Anthropic, OpenAI, Google, xAI, Groq, OpenRouter) |
|
|
225
220
|
| Telegram Userbot | [GramJS](https://gram.js.org/) (MTProto) |
|
|
226
|
-
| Inline Bot | [Grammy](https://grammy.dev/) (Bot API
|
|
221
|
+
| Inline Bot | [Grammy](https://grammy.dev/) (Bot API) |
|
|
227
222
|
| Blockchain | [TON SDK](https://github.com/ton-org/ton) (W5R1 wallet) |
|
|
228
223
|
| DeFi | STON.fi SDK, DeDust SDK |
|
|
229
224
|
| Database | [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) with WAL mode |
|
|
@@ -234,52 +229,73 @@ The agent's personality and rules are configured via markdown files in `~/.telet
|
|
|
234
229
|
### Project Structure
|
|
235
230
|
|
|
236
231
|
```
|
|
237
|
-
|
|
238
|
-
├──
|
|
239
|
-
|
|
240
|
-
│ ├──
|
|
241
|
-
│
|
|
242
|
-
│
|
|
243
|
-
│
|
|
244
|
-
│
|
|
245
|
-
│
|
|
246
|
-
│
|
|
247
|
-
│
|
|
248
|
-
│
|
|
249
|
-
│
|
|
250
|
-
│
|
|
251
|
-
│
|
|
252
|
-
│
|
|
253
|
-
│
|
|
254
|
-
|
|
255
|
-
│
|
|
256
|
-
│
|
|
257
|
-
│
|
|
258
|
-
|
|
259
|
-
│
|
|
260
|
-
│
|
|
261
|
-
│
|
|
262
|
-
|
|
263
|
-
│
|
|
264
|
-
│
|
|
265
|
-
│
|
|
266
|
-
|
|
267
|
-
│
|
|
268
|
-
│
|
|
269
|
-
│ ├──
|
|
270
|
-
│
|
|
271
|
-
│
|
|
272
|
-
│
|
|
273
|
-
|
|
274
|
-
│ ├──
|
|
275
|
-
│
|
|
276
|
-
│
|
|
277
|
-
│ ├──
|
|
278
|
-
│
|
|
279
|
-
│
|
|
280
|
-
│ └──
|
|
281
|
-
|
|
282
|
-
|
|
232
|
+
src/
|
|
233
|
+
├── index.ts # Entry point, lifecycle, module loading
|
|
234
|
+
├── agent/ # Core agent runtime
|
|
235
|
+
│ ├── runtime.ts # Agentic loop orchestration
|
|
236
|
+
│ ├── client.ts # Multi-provider LLM client
|
|
237
|
+
│ └── tools/ # 116 built-in tools
|
|
238
|
+
│ ├── register-all.ts # Central tool registration
|
|
239
|
+
│ ├── registry.ts # Tool registry + scope filtering
|
|
240
|
+
│ ├── module-loader.ts # Built-in module loading (deals, market)
|
|
241
|
+
│ ├── plugin-loader.ts # External plugin discovery
|
|
242
|
+
│ ├── telegram/ # Telegram operations (66 tools)
|
|
243
|
+
│ ├── ton/ # TON blockchain + jettons + DEX quote (15 tools)
|
|
244
|
+
│ ├── stonfi/ # STON.fi DEX (5 tools)
|
|
245
|
+
│ ├── dedust/ # DeDust DEX (5 tools)
|
|
246
|
+
│ ├── dns/ # TON DNS (7 tools)
|
|
247
|
+
│ ├── journal/ # Business journal (3 tools)
|
|
248
|
+
│ └── workspace/ # File operations (6 tools)
|
|
249
|
+
├── deals/ # Deals module (5 tools, loaded via module-loader)
|
|
250
|
+
│ ├── module.ts # Module definition + lifecycle
|
|
251
|
+
│ ├── executor.ts # Deal execution logic
|
|
252
|
+
│ └── strategy-checker.ts # Trading strategy enforcement
|
|
253
|
+
├── market/ # Market module (4 tools, loaded via module-loader)
|
|
254
|
+
│ ├── module.ts # Module definition + lifecycle
|
|
255
|
+
│ ├── price-service.ts # Gift floor-price tracking
|
|
256
|
+
│ └── scraper.ts # Market data scraping (Playwright)
|
|
257
|
+
├── bot/ # Deals inline bot (Grammy + GramJS)
|
|
258
|
+
│ ├── index.ts # DealBot (Grammy Bot API)
|
|
259
|
+
│ ├── gramjs-bot.ts # GramJS MTProto for styled buttons
|
|
260
|
+
│ └── services/ # Message builder, styled keyboard, verification
|
|
261
|
+
├── telegram/ # Telegram integration layer
|
|
262
|
+
│ ├── bridge.ts # GramJS wrapper (MTProto)
|
|
263
|
+
│ ├── handlers.ts # Message routing and processing
|
|
264
|
+
│ ├── admin.ts # Admin commands (/status, /clear, /modules)
|
|
265
|
+
│ ├── debounce.ts # Message batching for groups
|
|
266
|
+
│ ├── formatting.ts # Markdown → Telegram HTML
|
|
267
|
+
│ └── callbacks/ # Inline button routing
|
|
268
|
+
├── memory/ # Storage and knowledge
|
|
269
|
+
│ ├── schema.ts # Database schema + migrations
|
|
270
|
+
│ ├── database.ts # SQLite + WAL + vec0
|
|
271
|
+
│ ├── search/ # RAG system (FTS5 + vector)
|
|
272
|
+
│ ├── embeddings/ # Local + Anthropic embedding providers
|
|
273
|
+
│ ├── compaction.ts # Context auto-compaction
|
|
274
|
+
│ ├── observation-masking.ts # Tool result compression (~90% savings)
|
|
275
|
+
│ └── daily-logs.ts # Automatic session summaries
|
|
276
|
+
├── ton/ # TON blockchain
|
|
277
|
+
│ ├── wallet-service.ts # W5R1 wallet + KeyPair cache
|
|
278
|
+
│ ├── transfer.ts # TON send operations
|
|
279
|
+
│ └── payment-verifier.ts # On-chain payment verification
|
|
280
|
+
├── sdk/ # Plugin SDK (v1.0.0)
|
|
281
|
+
│ ├── index.ts # SDK factory (createPluginSDK)
|
|
282
|
+
│ ├── ton.ts # TON service for plugins
|
|
283
|
+
│ ├── telegram.ts # Telegram service for plugins
|
|
284
|
+
│ └── types.ts # Public SDK types
|
|
285
|
+
├── session/ # Session management
|
|
286
|
+
│ ├── store.ts # Session persistence (SQLite)
|
|
287
|
+
│ └── transcript.ts # Conversation transcripts
|
|
288
|
+
├── soul/ # System prompt assembly
|
|
289
|
+
│ └── loader.ts # SOUL + STRATEGY + SECURITY + MEMORY
|
|
290
|
+
├── config/ # Configuration
|
|
291
|
+
│ ├── schema.ts # Zod schemas + validation
|
|
292
|
+
│ └── providers.ts # Multi-provider LLM registry
|
|
293
|
+
├── constants/ # Centralized limits, timeouts, API endpoints
|
|
294
|
+
├── services/ # Shared services (TTS)
|
|
295
|
+
├── utils/ # Logger, sanitize, retry, fetch
|
|
296
|
+
├── workspace/ # Sandboxed file system
|
|
297
|
+
├── templates/ # Workspace template files (SOUL.md, etc.)
|
|
298
|
+
└── cli/ # CLI commands (setup, doctor)
|
|
283
299
|
```
|
|
284
300
|
|
|
285
301
|
---
|
|
@@ -291,12 +307,11 @@ teleton-agent/
|
|
|
291
307
|
| Layer | Protection |
|
|
292
308
|
|-------|-----------|
|
|
293
309
|
| **SECURITY.md** | Identity-based security principles injected into every system prompt |
|
|
294
|
-
| **Strategy enforcement** | Trading rules (buy/sell thresholds) enforced in code, not prompts |
|
|
295
310
|
| **Immutable config** | SOUL.md, STRATEGY.md, SECURITY.md cannot be modified by the agent |
|
|
311
|
+
| **RAG sanitization** | Stored prompt injection defense on all retrieved context |
|
|
296
312
|
| **Memory protection** | Memory writes blocked in group chats to prevent poisoning |
|
|
297
313
|
| **Workspace sandbox** | Agent can only access `~/.teleton/workspace/`, path traversal blocked |
|
|
298
|
-
| **
|
|
299
|
-
| **Replay protection** | Used transactions table prevents double-spending |
|
|
314
|
+
| **Plugin isolation** | Plugins get sanitized config (no API keys), isolated databases, frozen SDK objects |
|
|
300
315
|
|
|
301
316
|
### Reporting Vulnerabilities
|
|
302
317
|
|
|
@@ -309,8 +324,7 @@ Do not open public issues for security vulnerabilities. Contact maintainers (t.m
|
|
|
309
324
|
3. Start with restrictive policies (`allowlist`)
|
|
310
325
|
4. Set file permissions: `chmod 600 ~/.teleton/wallet.json`
|
|
311
326
|
5. Never commit `config.yaml` to version control
|
|
312
|
-
6.
|
|
313
|
-
7. Review `SECURITY.md` and customize for your use case
|
|
327
|
+
6. Review `SECURITY.md` and customize for your use case
|
|
314
328
|
|
|
315
329
|
---
|
|
316
330
|
|
|
@@ -320,7 +334,7 @@ Do not open public issues for security vulnerabilities. Contact maintainers (t.m
|
|
|
320
334
|
|
|
321
335
|
```bash
|
|
322
336
|
git clone https://github.com/TONresistor/teleton-agent.git
|
|
323
|
-
cd teleton
|
|
337
|
+
cd teleton-agent
|
|
324
338
|
npm install
|
|
325
339
|
npm run setup
|
|
326
340
|
npm run dev # Watch mode with auto-restart
|
|
@@ -341,45 +355,80 @@ npm run format # Prettier
|
|
|
341
355
|
|
|
342
356
|
### Plugins
|
|
343
357
|
|
|
344
|
-
|
|
358
|
+
Plugins extend the agent with custom tools. Drop a `.js` file or folder in `~/.teleton/plugins/` — loaded at startup, no rebuild needed.
|
|
345
359
|
|
|
346
360
|
```
|
|
347
361
|
~/.teleton/plugins/
|
|
348
|
-
├── weather.js # Single
|
|
349
|
-
└──
|
|
362
|
+
├── weather.js # Single-file plugin
|
|
363
|
+
└── my-plugin/
|
|
350
364
|
└── index.js # Folder plugin
|
|
351
365
|
```
|
|
352
366
|
|
|
353
|
-
|
|
367
|
+
Plugins export a `tools` function (recommended) or array, plus optional lifecycle hooks:
|
|
354
368
|
|
|
355
369
|
```js
|
|
356
370
|
// ~/.teleton/plugins/weather.js
|
|
357
|
-
|
|
371
|
+
|
|
372
|
+
export const manifest = {
|
|
373
|
+
name: "weather",
|
|
374
|
+
version: "1.0.0",
|
|
375
|
+
sdkVersion: "1.0.0",
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
// Optional: creates an isolated database at ~/.teleton/plugins/data/weather.db
|
|
379
|
+
export function migrate(db) {
|
|
380
|
+
db.exec(`CREATE TABLE IF NOT EXISTS weather_cache (
|
|
381
|
+
city TEXT PRIMARY KEY, data TEXT, cached_at INTEGER
|
|
382
|
+
)`);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Required: tools as a function receiving the Plugin SDK
|
|
386
|
+
export const tools = (sdk) => [
|
|
358
387
|
{
|
|
359
388
|
name: "weather_get",
|
|
360
389
|
description: "Get current weather for a city",
|
|
361
390
|
parameters: {
|
|
362
391
|
type: "object",
|
|
363
|
-
properties: {
|
|
364
|
-
|
|
365
|
-
},
|
|
366
|
-
required: ["city"]
|
|
392
|
+
properties: { city: { type: "string", description: "City name" } },
|
|
393
|
+
required: ["city"],
|
|
367
394
|
},
|
|
368
|
-
execute: async (params
|
|
395
|
+
execute: async (params) => {
|
|
396
|
+
sdk.log.info(`Fetching weather for ${params.city}`);
|
|
369
397
|
const res = await fetch(`https://wttr.in/${params.city}?format=j1`);
|
|
398
|
+
if (!res.ok) return { success: false, error: "City not found" };
|
|
370
399
|
const data = await res.json();
|
|
371
400
|
return { success: true, data: { temp: data.current_condition[0].temp_C } };
|
|
372
|
-
}
|
|
373
|
-
}
|
|
401
|
+
},
|
|
402
|
+
},
|
|
374
403
|
];
|
|
375
404
|
```
|
|
376
405
|
|
|
377
|
-
|
|
406
|
+
#### Plugin SDK
|
|
407
|
+
|
|
408
|
+
When `tools` is a function, the SDK provides namespaced access to core services:
|
|
409
|
+
|
|
410
|
+
| Namespace | Methods |
|
|
411
|
+
|-----------|---------|
|
|
412
|
+
| `sdk.ton` | `getAddress()`, `getBalance()`, `getPrice()`, `sendTON(to, amount, comment?)`, `getTransactions()` |
|
|
413
|
+
| `sdk.telegram` | `sendMessage()`, `editMessage()`, `sendDice()`, `sendReaction()`, `getMessages()`, `getMe()` |
|
|
414
|
+
| `sdk.db` | SQLite database (available if `migrate()` is exported) |
|
|
415
|
+
| `sdk.config` | Sanitized app config (no API keys exposed) |
|
|
416
|
+
| `sdk.pluginConfig` | Plugin-specific config from `config.yaml` `plugins:` section |
|
|
417
|
+
| `sdk.log` | Prefixed logger (`info`, `warn`, `error`, `debug`) |
|
|
418
|
+
|
|
419
|
+
Plugin config in `config.yaml`:
|
|
420
|
+
```yaml
|
|
421
|
+
plugins:
|
|
422
|
+
weather:
|
|
423
|
+
api_key: "abc123"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Backward compatible: plugins can export `tools` as a static array without the SDK.
|
|
378
427
|
|
|
379
|
-
At startup
|
|
428
|
+
At startup:
|
|
380
429
|
```
|
|
381
|
-
🔌 Plugin "weather
|
|
382
|
-
✅
|
|
430
|
+
🔌 Plugin "weather": 1 tool registered
|
|
431
|
+
✅ 117 tools loaded (1 from plugins)
|
|
383
432
|
```
|
|
384
433
|
|
|
385
434
|
---
|
|
@@ -15,7 +15,6 @@ var SCRAPER_PRE_SCROLL_MS = 4e3;
|
|
|
15
15
|
var SCRAPER_COLLECTION_SCROLL_MS = 200;
|
|
16
16
|
var SCRAPER_SCROLL_INCREMENT_PX = 250;
|
|
17
17
|
var SCRAPER_SCROLL_PADDING_PX = 500;
|
|
18
|
-
var SCRAPER_WINDOW_SCROLL_PX = 2e3;
|
|
19
18
|
var SCRAPER_MAX_SCROLL_ITERATIONS = 15;
|
|
20
19
|
var SCRAPER_COLLECTION_NAV_MS = 6e4;
|
|
21
20
|
var RETRY_DEFAULT_MAX_ATTEMPTS = 3;
|
|
@@ -46,7 +45,6 @@ export {
|
|
|
46
45
|
SCRAPER_COLLECTION_SCROLL_MS,
|
|
47
46
|
SCRAPER_SCROLL_INCREMENT_PX,
|
|
48
47
|
SCRAPER_SCROLL_PADDING_PX,
|
|
49
|
-
SCRAPER_WINDOW_SCROLL_PX,
|
|
50
48
|
SCRAPER_MAX_SCROLL_ITERATIONS,
|
|
51
49
|
SCRAPER_COLLECTION_NAV_MS,
|
|
52
50
|
RETRY_DEFAULT_MAX_ATTEMPTS,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
VOYAGE_API_URL,
|
|
3
3
|
fetchWithTimeout
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-A64NPEFL.js";
|
|
5
5
|
import {
|
|
6
6
|
EMBEDDING_CACHE_EVICTION_INTERVAL,
|
|
7
7
|
EMBEDDING_CACHE_MAX_ENTRIES,
|
|
@@ -11,20 +11,20 @@ import {
|
|
|
11
11
|
SQLITE_CACHE_SIZE_KB,
|
|
12
12
|
SQLITE_MMAP_SIZE,
|
|
13
13
|
VOYAGE_BATCH_SIZE
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-OA5L7GM6.js";
|
|
15
15
|
import {
|
|
16
16
|
TELETON_ROOT
|
|
17
17
|
} from "./chunk-EYWNOHMJ.js";
|
|
18
18
|
|
|
19
19
|
// src/memory/database.ts
|
|
20
20
|
import Database2 from "better-sqlite3";
|
|
21
|
-
import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
21
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, chmodSync as chmodSync2 } from "fs";
|
|
22
22
|
import { dirname as dirname2 } from "path";
|
|
23
23
|
import * as sqliteVec from "sqlite-vec";
|
|
24
24
|
|
|
25
25
|
// src/utils/module-db.ts
|
|
26
26
|
import Database from "better-sqlite3";
|
|
27
|
-
import { existsSync, mkdirSync } from "fs";
|
|
27
|
+
import { existsSync, mkdirSync, chmodSync } from "fs";
|
|
28
28
|
import { dirname, join } from "path";
|
|
29
29
|
var JOURNAL_SCHEMA = `
|
|
30
30
|
CREATE TABLE IF NOT EXISTS journal (
|
|
@@ -75,6 +75,10 @@ function openModuleDb(path) {
|
|
|
75
75
|
mkdirSync(dir, { recursive: true });
|
|
76
76
|
}
|
|
77
77
|
const db = new Database(path);
|
|
78
|
+
try {
|
|
79
|
+
chmodSync(path, 384);
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
78
82
|
db.pragma("journal_mode = WAL");
|
|
79
83
|
return db;
|
|
80
84
|
}
|
|
@@ -95,6 +99,11 @@ function createDbWrapper(getDb, moduleName) {
|
|
|
95
99
|
var MAIN_DB_PATH = join(TELETON_ROOT, "memory.db");
|
|
96
100
|
function migrateFromMainDb(moduleDb, tables) {
|
|
97
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
|
+
}
|
|
98
107
|
for (const table of tables) {
|
|
99
108
|
try {
|
|
100
109
|
const row = moduleDb.prepare(`SELECT COUNT(*) as c FROM ${table}`).get();
|
|
@@ -543,6 +552,10 @@ var MemoryDatabase = class {
|
|
|
543
552
|
this.db = new Database2(config.path, {
|
|
544
553
|
verbose: process.env.DEBUG_SQL ? console.log : void 0
|
|
545
554
|
});
|
|
555
|
+
try {
|
|
556
|
+
chmodSync2(config.path, 384);
|
|
557
|
+
} catch {
|
|
558
|
+
}
|
|
546
559
|
this.db.pragma("journal_mode = WAL");
|
|
547
560
|
this.db.pragma("synchronous = NORMAL");
|
|
548
561
|
this.db.pragma(`cache_size = -${SQLITE_CACHE_SIZE_KB}`);
|
|
@@ -567,13 +580,12 @@ var MemoryDatabase = class {
|
|
|
567
580
|
if (this.config.enableVectorSearch) {
|
|
568
581
|
this.loadVectorExtension();
|
|
569
582
|
}
|
|
583
|
+
this.db.exec("ANALYZE");
|
|
570
584
|
}
|
|
571
585
|
loadVectorExtension() {
|
|
572
586
|
try {
|
|
573
587
|
sqliteVec.load(this.db);
|
|
574
|
-
|
|
575
|
-
const { vec_version } = this.db.prepare("SELECT vec_version() as vec_version").get();
|
|
576
|
-
console.log(` Version: ${vec_version}`);
|
|
588
|
+
this.db.prepare("SELECT vec_version() as vec_version").get();
|
|
577
589
|
const dims = this.config.vectorDimensions ?? 512;
|
|
578
590
|
ensureVectorTables(this.db, dims);
|
|
579
591
|
this.vectorReady = true;
|
|
@@ -1271,13 +1283,8 @@ ${session.summary}`;
|
|
|
1271
1283
|
if (embedding && this.vectorEnabled) {
|
|
1272
1284
|
const embeddingBuffer = serializeEmbedding(embedding);
|
|
1273
1285
|
const rowid = this.db.prepare(`SELECT rowid FROM knowledge WHERE id = ?`).get(knowledgeId);
|
|
1274
|
-
this.db.prepare(
|
|
1275
|
-
|
|
1276
|
-
INSERT INTO knowledge_vec (rowid, embedding)
|
|
1277
|
-
VALUES (?, ?)
|
|
1278
|
-
ON CONFLICT(rowid) DO UPDATE SET embedding = excluded.embedding
|
|
1279
|
-
`
|
|
1280
|
-
).run(rowid.rowid, embeddingBuffer);
|
|
1286
|
+
this.db.prepare(`DELETE FROM knowledge_vec WHERE rowid = ?`).run(rowid.rowid);
|
|
1287
|
+
this.db.prepare(`INSERT INTO knowledge_vec (rowid, embedding) VALUES (?, ?)`).run(rowid.rowid, embeddingBuffer);
|
|
1281
1288
|
}
|
|
1282
1289
|
console.log(`Indexed session ${sessionId} to knowledge base`);
|
|
1283
1290
|
} catch (error) {
|
|
@@ -1331,7 +1338,8 @@ var MessageStore = class {
|
|
|
1331
1338
|
if (message.senderId) {
|
|
1332
1339
|
this.ensureUser(message.senderId);
|
|
1333
1340
|
}
|
|
1334
|
-
const embedding = message.text ? await this.embedder.embedQuery(message.text) : [];
|
|
1341
|
+
const embedding = this.vectorEnabled && message.text ? await this.embedder.embedQuery(message.text) : [];
|
|
1342
|
+
const embeddingBuffer = serializeEmbedding(embedding);
|
|
1335
1343
|
this.db.prepare(
|
|
1336
1344
|
`
|
|
1337
1345
|
INSERT OR REPLACE INTO tg_messages (
|
|
@@ -1344,7 +1352,7 @@ var MessageStore = class {
|
|
|
1344
1352
|
message.chatId,
|
|
1345
1353
|
message.senderId,
|
|
1346
1354
|
message.text,
|
|
1347
|
-
|
|
1355
|
+
embeddingBuffer,
|
|
1348
1356
|
message.replyToId,
|
|
1349
1357
|
message.isFromAgent ? 1 : 0,
|
|
1350
1358
|
message.hasMedia ? 1 : 0,
|
|
@@ -1352,7 +1360,8 @@ var MessageStore = class {
|
|
|
1352
1360
|
message.timestamp
|
|
1353
1361
|
);
|
|
1354
1362
|
if (this.vectorEnabled && embedding.length > 0 && message.text) {
|
|
1355
|
-
this.db.prepare(`
|
|
1363
|
+
this.db.prepare(`DELETE FROM tg_messages_vec WHERE id = ?`).run(message.id);
|
|
1364
|
+
this.db.prepare(`INSERT INTO tg_messages_vec (id, embedding) VALUES (?, ?)`).run(message.id, embeddingBuffer);
|
|
1356
1365
|
}
|
|
1357
1366
|
this.db.prepare(`UPDATE tg_chats SET last_message_at = ?, last_message_id = ? WHERE id = ?`).run(message.timestamp, message.id, message.chatId);
|
|
1358
1367
|
}
|
|
@@ -1720,8 +1729,8 @@ var HybridSearch = class {
|
|
|
1720
1729
|
const limit = options.limit ?? 10;
|
|
1721
1730
|
const vectorWeight = options.vectorWeight ?? 0.7;
|
|
1722
1731
|
const keywordWeight = options.keywordWeight ?? 0.3;
|
|
1723
|
-
const vectorResults = this.vectorEnabled ? this.vectorSearchKnowledge(queryEmbedding, limit *
|
|
1724
|
-
const keywordResults = this.keywordSearchKnowledge(query, limit *
|
|
1732
|
+
const vectorResults = this.vectorEnabled ? this.vectorSearchKnowledge(queryEmbedding, Math.ceil(limit * 1.5)) : [];
|
|
1733
|
+
const keywordResults = this.keywordSearchKnowledge(query, Math.ceil(limit * 1.5));
|
|
1725
1734
|
return this.mergeResults(vectorResults, keywordResults, vectorWeight, keywordWeight, limit);
|
|
1726
1735
|
}
|
|
1727
1736
|
/**
|
|
@@ -1731,8 +1740,12 @@ var HybridSearch = class {
|
|
|
1731
1740
|
const limit = options.limit ?? 10;
|
|
1732
1741
|
const vectorWeight = options.vectorWeight ?? 0.7;
|
|
1733
1742
|
const keywordWeight = options.keywordWeight ?? 0.3;
|
|
1734
|
-
const vectorResults = this.vectorEnabled ? this.vectorSearchMessages(queryEmbedding, limit *
|
|
1735
|
-
const keywordResults = this.keywordSearchMessages(
|
|
1743
|
+
const vectorResults = this.vectorEnabled ? this.vectorSearchMessages(queryEmbedding, Math.ceil(limit * 1.5), options.chatId) : [];
|
|
1744
|
+
const keywordResults = this.keywordSearchMessages(
|
|
1745
|
+
query,
|
|
1746
|
+
Math.ceil(limit * 1.5),
|
|
1747
|
+
options.chatId
|
|
1748
|
+
);
|
|
1736
1749
|
return this.mergeResults(vectorResults, keywordResults, vectorWeight, keywordWeight, limit);
|
|
1737
1750
|
}
|
|
1738
1751
|
vectorSearchKnowledge(embedding, limit) {
|