teleton 0.3.0 → 0.5.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/README.md +219 -95
- package/dist/BigInteger-DQ33LTTE.js +5 -0
- package/dist/chunk-4DU3C27M.js +30 -0
- package/dist/chunk-5WWR4CU3.js +124 -0
- package/dist/{chunk-QQW6KE7Q.js → chunk-BYTHCDZA.js} +282 -263
- package/dist/chunk-EHEV7FJ7.js +157 -0
- package/dist/{chunk-E2NXSWOS.js → chunk-NUGDTPE4.js} +24 -64
- package/dist/{chunk-UYF4TT44.js → chunk-O4R7V5Y2.js} +38 -6
- package/dist/chunk-QUAPFI2N.js +42 -0
- package/dist/{chunk-ILDG4OPK.js → chunk-RRB6BWU7.js} +9411 -10083
- package/dist/chunk-TSKJCWQQ.js +1263 -0
- package/dist/{chunk-B2PRMXOH.js → chunk-WL2Q3VRD.js} +0 -2
- package/dist/{chunk-OQGNS2FV.js → chunk-YBA6IBGT.js} +20 -5
- package/dist/cli/index.js +42 -176
- package/dist/endpoint-FLYNEZ2F.js +7 -0
- package/dist/format-transactions-FD74HI5N.js +9 -0
- package/dist/{get-my-gifts-AFKBG4YQ.js → get-my-gifts-KVULMBJ3.js} +1 -1
- package/dist/index.js +13 -11
- package/dist/{memory-ZXDAJBL6.js → memory-657W5AS6.js} +4 -5
- package/dist/{migrate-7OG67FXP.js → migrate-PMB2JVXH.js} +4 -5
- package/dist/server-BQY7CM2N.js +1120 -0
- package/dist/{task-dependency-resolver-S45DFI5C.js → task-dependency-resolver-TRPILAHM.js} +4 -4
- package/dist/{task-executor-AUTT3VAL.js → task-executor-N7XNVK5N.js} +1 -1
- package/dist/{tasks-M3QDPTGY.js → tasks-QSCWSMPS.js} +1 -1
- package/dist/{transcript-DF2Y6CFY.js → transcript-7V4UNID4.js} +1 -1
- package/dist/web/assets/index-CDMbujHf.css +1 -0
- package/dist/web/assets/index-DDX8oQ2z.js +67 -0
- package/dist/web/index.html +16 -0
- package/dist/web/logo_dark.png +0 -0
- package/package.json +23 -4
- 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/chunk-DAMFGHXV.js +0 -74
- package/dist/chunk-DUW5VBAZ.js +0 -133
- package/dist/chunk-LCMHAUNK.js +0 -62
- package/dist/scraper-KXRBQMVQ.js +0 -282
- 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
|
+
- **112 built-in tools**: Messaging, media, blockchain, DEX trading, deals, 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,24 @@ 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
|
-
| Memory | 2 | Persistent memory management, RAG-powered context retrieval |
|
|
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
|
+
| Journal | 3 | Trade/operation logging with natural language queries |
|
|
41
|
+
| Workspace | 6 | Sandboxed file operations with path traversal protection |
|
|
47
42
|
|
|
48
43
|
### Advanced Capabilities
|
|
49
44
|
|
|
50
45
|
| Capability | Description |
|
|
51
46
|
|-----------|-------------|
|
|
52
47
|
| **Multi-Provider LLM** | Switch between Anthropic, OpenAI, Google, xAI, Groq, OpenRouter with one config change |
|
|
53
|
-
| **RAG Search** |
|
|
48
|
+
| **RAG + Hybrid Search** | Local embeddings with FTS5 keyword + sqlite-vec semantic search |
|
|
54
49
|
| **Auto-Compaction** | AI-summarized context management prevents overflow, preserves key information |
|
|
55
50
|
| **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 |
|
|
51
|
+
| **Plugin SDK** | Namespaced SDK (`sdk.ton`, `sdk.telegram`, `sdk.secrets`, `sdk.storage`) with 53 methods, isolated databases and lifecycle hooks |
|
|
58
52
|
| **Vision Analysis** | Image understanding via multimodal LLM |
|
|
59
53
|
| **Voice Synthesis** | Text-to-speech for voice messages |
|
|
60
54
|
| **Scheduled Tasks** | Time-based task execution with dependency resolution |
|
|
@@ -72,7 +66,7 @@ Teleton is a production-grade autonomous AI agent that operates as a real Telegr
|
|
|
72
66
|
- **Telegram Account** - Dedicated account recommended for security
|
|
73
67
|
- **Telegram API Credentials** - From [my.telegram.org/apps](https://my.telegram.org/apps)
|
|
74
68
|
- **Your Telegram User ID** - Message [@userinfobot](https://t.me/userinfobot)
|
|
75
|
-
- **Bot Token** *(optional
|
|
69
|
+
- **Bot Token** *(optional)* - From [@BotFather](https://t.me/BotFather) for inline bot features
|
|
76
70
|
|
|
77
71
|
> **Security Warning**: The agent will have full control over the Telegram account. Use a dedicated account, not your main one.
|
|
78
72
|
|
|
@@ -100,7 +94,7 @@ docker run -it -v ~/.teleton:/data ghcr.io/tonresistor/teleton-agent:latest setu
|
|
|
100
94
|
**From source (development):**
|
|
101
95
|
```bash
|
|
102
96
|
git clone https://github.com/TONresistor/teleton-agent.git
|
|
103
|
-
cd teleton
|
|
97
|
+
cd teleton-agent
|
|
104
98
|
npm install && npm run build
|
|
105
99
|
```
|
|
106
100
|
|
|
@@ -168,13 +162,19 @@ telegram:
|
|
|
168
162
|
owner_name: "Your Name"
|
|
169
163
|
owner_username: "your_username"
|
|
170
164
|
|
|
171
|
-
# Optional: inline bot for
|
|
165
|
+
# Optional: inline bot for interactive features
|
|
172
166
|
bot_token: "123456:ABC-DEF..."
|
|
173
|
-
bot_username: "
|
|
167
|
+
bot_username: "your_bot"
|
|
174
168
|
|
|
175
169
|
session_reset_policy:
|
|
176
170
|
daily_reset_enabled: true
|
|
177
171
|
daily_reset_hour: 4
|
|
172
|
+
|
|
173
|
+
webui: # Optional: Web dashboard
|
|
174
|
+
enabled: false # Enable WebUI server
|
|
175
|
+
port: 7777 # HTTP server port
|
|
176
|
+
host: "127.0.0.1" # Localhost only (security)
|
|
177
|
+
# auth_token: "..." # Auto-generated if omitted
|
|
178
178
|
```
|
|
179
179
|
|
|
180
180
|
### Environment Variables
|
|
@@ -186,6 +186,69 @@ telegram:
|
|
|
186
186
|
| `TELETON_TG_API_ID` | Telegram API ID (overrides config) | - |
|
|
187
187
|
| `TELETON_TG_API_HASH` | Telegram API Hash (overrides config) | - |
|
|
188
188
|
| `TELETON_TG_PHONE` | Phone number (overrides config) | - |
|
|
189
|
+
| `TELETON_WEBUI_ENABLED` | Enable WebUI (overrides config) | `false` |
|
|
190
|
+
| `TELETON_WEBUI_PORT` | WebUI port (overrides config) | `7777` |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## WebUI Dashboard
|
|
195
|
+
|
|
196
|
+
Teleton includes an **optional web dashboard** for monitoring and configuration. The WebUI is disabled by default and runs only on localhost for security.
|
|
197
|
+
|
|
198
|
+
### Features
|
|
199
|
+
|
|
200
|
+
- **Dashboard**: System status, uptime, model info, session count
|
|
201
|
+
- **Tools Management**: View all 112+ tools grouped by module with scope badges
|
|
202
|
+
- **Plugins Browser**: List loaded plugins with manifests
|
|
203
|
+
- **Soul Editor**: Edit SOUL.md, SECURITY.md, STRATEGY.md, MEMORY.md files
|
|
204
|
+
- **Memory Search**: Search knowledge base with hybrid vector+keyword search
|
|
205
|
+
- **Live Logs**: Real-time log streaming via Server-Sent Events
|
|
206
|
+
|
|
207
|
+
### Usage
|
|
208
|
+
|
|
209
|
+
**Enable via config.yaml:**
|
|
210
|
+
```yaml
|
|
211
|
+
webui:
|
|
212
|
+
enabled: true
|
|
213
|
+
port: 7777
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
**Enable via CLI flag:**
|
|
217
|
+
```bash
|
|
218
|
+
teleton start --webui
|
|
219
|
+
# or specify custom port
|
|
220
|
+
teleton start --webui --webui-port 8080
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
**Enable via environment variable:**
|
|
224
|
+
```bash
|
|
225
|
+
TELETON_WEBUI_ENABLED=true teleton start
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Access
|
|
229
|
+
|
|
230
|
+
When WebUI is enabled, the agent will display:
|
|
231
|
+
```
|
|
232
|
+
🌐 WebUI: http://localhost:7777?token=your-token-here
|
|
233
|
+
🔑 Token: your-token-here
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
1. Click the URL (token is auto-filled) or visit `http://localhost:7777`
|
|
237
|
+
2. Paste the token from the console (displayed once at startup)
|
|
238
|
+
3. Token is stored in browser localStorage for subsequent visits
|
|
239
|
+
|
|
240
|
+
### Security
|
|
241
|
+
|
|
242
|
+
- **Localhost only**: Server binds to `127.0.0.1` by default (not accessible from network)
|
|
243
|
+
- **Bearer token auth**: All API routes require authentication
|
|
244
|
+
- **No persistence**: Runtime changes (like model switches via WebUI) are not saved to config.yaml
|
|
245
|
+
- **For remote access**: Use SSH tunneling or reverse proxy (nginx/caddy) with HTTPS
|
|
246
|
+
|
|
247
|
+
**SSH tunnel example:**
|
|
248
|
+
```bash
|
|
249
|
+
ssh -L 7777:localhost:7777 user@remote-server
|
|
250
|
+
# Then access http://localhost:7777 on your local machine
|
|
251
|
+
```
|
|
189
252
|
|
|
190
253
|
### Workspace Files
|
|
191
254
|
|
|
@@ -223,7 +286,7 @@ The agent's personality and rules are configured via markdown files in `~/.telet
|
|
|
223
286
|
|-------|------------|
|
|
224
287
|
| LLM | Multi-provider via [pi-ai](https://github.com/mariozechner/pi-ai) (Anthropic, OpenAI, Google, xAI, Groq, OpenRouter) |
|
|
225
288
|
| Telegram Userbot | [GramJS](https://gram.js.org/) (MTProto) |
|
|
226
|
-
| Inline Bot | [Grammy](https://grammy.dev/) (Bot API
|
|
289
|
+
| Inline Bot | [Grammy](https://grammy.dev/) (Bot API) |
|
|
227
290
|
| Blockchain | [TON SDK](https://github.com/ton-org/ton) (W5R1 wallet) |
|
|
228
291
|
| DeFi | STON.fi SDK, DeDust SDK |
|
|
229
292
|
| Database | [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) with WAL mode |
|
|
@@ -234,52 +297,69 @@ The agent's personality and rules are configured via markdown files in `~/.telet
|
|
|
234
297
|
### Project Structure
|
|
235
298
|
|
|
236
299
|
```
|
|
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
|
-
|
|
300
|
+
src/
|
|
301
|
+
├── index.ts # Entry point, lifecycle, module loading
|
|
302
|
+
├── agent/ # Core agent runtime
|
|
303
|
+
│ ├── runtime.ts # Agentic loop orchestration
|
|
304
|
+
│ ├── client.ts # Multi-provider LLM client
|
|
305
|
+
│ └── tools/ # 112 built-in tools
|
|
306
|
+
│ ├── register-all.ts # Central tool registration
|
|
307
|
+
│ ├── registry.ts # Tool registry + scope filtering
|
|
308
|
+
│ ├── module-loader.ts # Built-in module loading (deals)
|
|
309
|
+
│ ├── plugin-loader.ts # External plugin discovery
|
|
310
|
+
│ ├── telegram/ # Telegram operations (66 tools)
|
|
311
|
+
│ ├── ton/ # TON blockchain + jettons + DEX quote (15 tools)
|
|
312
|
+
│ ├── stonfi/ # STON.fi DEX (5 tools)
|
|
313
|
+
│ ├── dedust/ # DeDust DEX (5 tools)
|
|
314
|
+
│ ├── dns/ # TON DNS (7 tools)
|
|
315
|
+
│ ├── journal/ # Business journal (3 tools)
|
|
316
|
+
│ └── workspace/ # File operations (6 tools)
|
|
317
|
+
├── deals/ # Deals module (5 tools, loaded via module-loader)
|
|
318
|
+
│ ├── module.ts # Module definition + lifecycle
|
|
319
|
+
│ ├── executor.ts # Deal execution logic
|
|
320
|
+
│ └── strategy-checker.ts # Trading strategy enforcement
|
|
321
|
+
├── bot/ # Deals inline bot (Grammy + GramJS)
|
|
322
|
+
│ ├── index.ts # DealBot (Grammy Bot API)
|
|
323
|
+
│ ├── gramjs-bot.ts # GramJS MTProto for styled buttons
|
|
324
|
+
│ └── services/ # Message builder, styled keyboard, verification
|
|
325
|
+
├── telegram/ # Telegram integration layer
|
|
326
|
+
│ ├── bridge.ts # GramJS wrapper (MTProto)
|
|
327
|
+
│ ├── handlers.ts # Message routing and processing
|
|
328
|
+
│ ├── admin.ts # Admin commands (/status, /clear, /modules)
|
|
329
|
+
│ ├── debounce.ts # Message batching for groups
|
|
330
|
+
│ ├── formatting.ts # Markdown → Telegram HTML
|
|
331
|
+
│ └── callbacks/ # Inline button routing
|
|
332
|
+
├── memory/ # Storage and knowledge
|
|
333
|
+
│ ├── schema.ts # Database schema + migrations
|
|
334
|
+
│ ├── database.ts # SQLite + WAL + vec0
|
|
335
|
+
│ ├── search/ # RAG system (FTS5 + vector)
|
|
336
|
+
│ ├── embeddings/ # Local + Anthropic embedding providers
|
|
337
|
+
│ ├── compaction.ts # Context auto-compaction
|
|
338
|
+
│ ├── observation-masking.ts # Tool result compression (~90% savings)
|
|
339
|
+
│ └── daily-logs.ts # Automatic session summaries
|
|
340
|
+
├── ton/ # TON blockchain
|
|
341
|
+
│ ├── wallet-service.ts # W5R1 wallet + KeyPair cache
|
|
342
|
+
│ ├── transfer.ts # TON send operations
|
|
343
|
+
│ └── payment-verifier.ts # On-chain payment verification
|
|
344
|
+
├── sdk/ # Plugin SDK (v1.0.0)
|
|
345
|
+
│ ├── index.ts # SDK factory (createPluginSDK)
|
|
346
|
+
│ ├── ton.ts # TON service for plugins
|
|
347
|
+
│ ├── telegram.ts # Telegram service for plugins
|
|
348
|
+
│ └── types.ts # Public SDK types
|
|
349
|
+
├── session/ # Session management
|
|
350
|
+
│ ├── store.ts # Session persistence (SQLite)
|
|
351
|
+
│ └── transcript.ts # Conversation transcripts
|
|
352
|
+
├── soul/ # System prompt assembly
|
|
353
|
+
│ └── loader.ts # SOUL + STRATEGY + SECURITY + MEMORY
|
|
354
|
+
├── config/ # Configuration
|
|
355
|
+
│ ├── schema.ts # Zod schemas + validation
|
|
356
|
+
│ └── providers.ts # Multi-provider LLM registry
|
|
357
|
+
├── constants/ # Centralized limits, timeouts, API endpoints
|
|
358
|
+
├── services/ # Shared services (TTS)
|
|
359
|
+
├── utils/ # Logger, sanitize, retry, fetch
|
|
360
|
+
├── workspace/ # Sandboxed file system
|
|
361
|
+
├── templates/ # Workspace template files (SOUL.md, etc.)
|
|
362
|
+
└── cli/ # CLI commands (setup, doctor)
|
|
283
363
|
```
|
|
284
364
|
|
|
285
365
|
---
|
|
@@ -291,12 +371,11 @@ teleton-agent/
|
|
|
291
371
|
| Layer | Protection |
|
|
292
372
|
|-------|-----------|
|
|
293
373
|
| **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
374
|
| **Immutable config** | SOUL.md, STRATEGY.md, SECURITY.md cannot be modified by the agent |
|
|
375
|
+
| **RAG sanitization** | Stored prompt injection defense on all retrieved context |
|
|
296
376
|
| **Memory protection** | Memory writes blocked in group chats to prevent poisoning |
|
|
297
377
|
| **Workspace sandbox** | Agent can only access `~/.teleton/workspace/`, path traversal blocked |
|
|
298
|
-
| **
|
|
299
|
-
| **Replay protection** | Used transactions table prevents double-spending |
|
|
378
|
+
| **Plugin isolation** | Plugins get sanitized config (no API keys), isolated databases, frozen SDK objects |
|
|
300
379
|
|
|
301
380
|
### Reporting Vulnerabilities
|
|
302
381
|
|
|
@@ -309,8 +388,7 @@ Do not open public issues for security vulnerabilities. Contact maintainers (t.m
|
|
|
309
388
|
3. Start with restrictive policies (`allowlist`)
|
|
310
389
|
4. Set file permissions: `chmod 600 ~/.teleton/wallet.json`
|
|
311
390
|
5. Never commit `config.yaml` to version control
|
|
312
|
-
6.
|
|
313
|
-
7. Review `SECURITY.md` and customize for your use case
|
|
391
|
+
6. Review `SECURITY.md` and customize for your use case
|
|
314
392
|
|
|
315
393
|
---
|
|
316
394
|
|
|
@@ -320,7 +398,7 @@ Do not open public issues for security vulnerabilities. Contact maintainers (t.m
|
|
|
320
398
|
|
|
321
399
|
```bash
|
|
322
400
|
git clone https://github.com/TONresistor/teleton-agent.git
|
|
323
|
-
cd teleton
|
|
401
|
+
cd teleton-agent
|
|
324
402
|
npm install
|
|
325
403
|
npm run setup
|
|
326
404
|
npm run dev # Watch mode with auto-restart
|
|
@@ -341,45 +419,91 @@ npm run format # Prettier
|
|
|
341
419
|
|
|
342
420
|
### Plugins
|
|
343
421
|
|
|
344
|
-
|
|
422
|
+
Plugins extend the agent with custom tools. Drop a `.js` file or folder in `~/.teleton/plugins/` — loaded at startup, no rebuild needed.
|
|
345
423
|
|
|
346
424
|
```
|
|
347
425
|
~/.teleton/plugins/
|
|
348
|
-
├── weather.js # Single
|
|
349
|
-
└──
|
|
426
|
+
├── weather.js # Single-file plugin
|
|
427
|
+
└── my-plugin/
|
|
350
428
|
└── index.js # Folder plugin
|
|
351
429
|
```
|
|
352
430
|
|
|
353
|
-
|
|
431
|
+
Plugins export a `tools` function (recommended) or array, plus optional lifecycle hooks:
|
|
354
432
|
|
|
355
433
|
```js
|
|
356
434
|
// ~/.teleton/plugins/weather.js
|
|
357
|
-
|
|
435
|
+
|
|
436
|
+
export const manifest = {
|
|
437
|
+
name: "weather",
|
|
438
|
+
version: "1.0.0",
|
|
439
|
+
sdkVersion: "1.0.0",
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
// Optional: creates an isolated database at ~/.teleton/plugins/data/weather.db
|
|
443
|
+
export function migrate(db) {
|
|
444
|
+
db.exec(`CREATE TABLE IF NOT EXISTS weather_cache (
|
|
445
|
+
city TEXT PRIMARY KEY, data TEXT, cached_at INTEGER
|
|
446
|
+
)`);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Required: tools as a function receiving the Plugin SDK
|
|
450
|
+
export const tools = (sdk) => [
|
|
358
451
|
{
|
|
359
452
|
name: "weather_get",
|
|
360
453
|
description: "Get current weather for a city",
|
|
361
454
|
parameters: {
|
|
362
455
|
type: "object",
|
|
363
|
-
properties: {
|
|
364
|
-
|
|
365
|
-
},
|
|
366
|
-
required: ["city"]
|
|
456
|
+
properties: { city: { type: "string", description: "City name" } },
|
|
457
|
+
required: ["city"],
|
|
367
458
|
},
|
|
368
|
-
execute: async (params
|
|
459
|
+
execute: async (params) => {
|
|
460
|
+
sdk.log.info(`Fetching weather for ${params.city}`);
|
|
369
461
|
const res = await fetch(`https://wttr.in/${params.city}?format=j1`);
|
|
462
|
+
if (!res.ok) return { success: false, error: "City not found" };
|
|
370
463
|
const data = await res.json();
|
|
371
464
|
return { success: true, data: { temp: data.current_condition[0].temp_C } };
|
|
372
|
-
}
|
|
373
|
-
}
|
|
465
|
+
},
|
|
466
|
+
},
|
|
374
467
|
];
|
|
375
468
|
```
|
|
376
469
|
|
|
377
|
-
|
|
470
|
+
#### Plugin SDK
|
|
471
|
+
|
|
472
|
+
When `tools` is a function, the SDK provides namespaced access to core services:
|
|
473
|
+
|
|
474
|
+
| Namespace | Methods |
|
|
475
|
+
|-----------|---------|
|
|
476
|
+
| `sdk.ton` | **Wallet**: `getAddress()`, `getBalance()`, `getPrice()`, `sendTON()`, `getTransactions()`, `verifyPayment()` |
|
|
477
|
+
| | **Jettons**: `getJettonBalances()`, `getJettonInfo()`, `sendJetton()`, `getJettonWalletAddress()` |
|
|
478
|
+
| | **NFT**: `getNftItems()`, `getNftInfo()` |
|
|
479
|
+
| | **Utils**: `toNano()`, `fromNano()`, `validateAddress()` |
|
|
480
|
+
| `sdk.telegram` | **Messages**: `sendMessage()`, `editMessage()`, `deleteMessage()`, `forwardMessage()`, `pinMessage()`, `searchMessages()`, `scheduleMessage()`, `getReplies()` |
|
|
481
|
+
| | **Media**: `sendPhoto()`, `sendVideo()`, `sendVoice()`, `sendFile()`, `sendGif()`, `sendSticker()`, `downloadMedia()` |
|
|
482
|
+
| | **Chat & Users**: `getChatInfo()`, `getUserInfo()`, `resolveUsername()`, `getParticipants()` |
|
|
483
|
+
| | **Interactive**: `sendDice()`, `sendReaction()`, `createPoll()`, `createQuiz()` |
|
|
484
|
+
| | **Moderation**: `banUser()`, `unbanUser()`, `muteUser()` |
|
|
485
|
+
| | **Stars & Gifts**: `getStarsBalance()`, `sendGift()`, `getAvailableGifts()`, `getMyGifts()`, `getResaleGifts()`, `buyResaleGift()` |
|
|
486
|
+
| | **Advanced**: `getMe()`, `isAvailable()`, `getRawClient()`, `setTyping()`, `sendStory()` |
|
|
487
|
+
| `sdk.secrets` | `get()`, `require()`, `has()` — Multi-source secret resolution (env -> store -> config) |
|
|
488
|
+
| `sdk.storage` | `get()`, `set()`, `delete()`, `has()`, `clear()` — KV store with TTL support |
|
|
489
|
+
| `sdk.db` | Raw `better-sqlite3` database for custom SQL |
|
|
490
|
+
| `sdk.config` | Sanitized app config (no API keys exposed) |
|
|
491
|
+
| `sdk.pluginConfig` | Plugin-specific config from `config.yaml` `plugins:` section |
|
|
492
|
+
| `sdk.log` | `info()`, `warn()`, `error()`, `debug()` — Prefixed logger |
|
|
493
|
+
|
|
494
|
+
Plugin config in `config.yaml`:
|
|
495
|
+
```yaml
|
|
496
|
+
plugins:
|
|
497
|
+
weather:
|
|
498
|
+
api_key: "abc123"
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
Backward compatible: plugins can export `tools` as a static array without the SDK.
|
|
378
502
|
|
|
379
|
-
At startup
|
|
503
|
+
At startup:
|
|
380
504
|
```
|
|
381
|
-
🔌 Plugin "weather
|
|
382
|
-
✅
|
|
505
|
+
🔌 Plugin "weather": 1 tool registered
|
|
506
|
+
✅ 117 tools loaded (1 from plugins)
|
|
383
507
|
```
|
|
384
508
|
|
|
385
509
|
---
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/constants/timeouts.ts
|
|
2
|
+
var TTS_TIMEOUT_MS = 3e4;
|
|
3
|
+
var BATCH_TRIGGER_DELAY_MS = 500;
|
|
4
|
+
var DEFAULT_FETCH_TIMEOUT_MS = 15e3;
|
|
5
|
+
var RETRY_DEFAULT_MAX_ATTEMPTS = 3;
|
|
6
|
+
var RETRY_DEFAULT_BASE_DELAY_MS = 1e3;
|
|
7
|
+
var RETRY_DEFAULT_MAX_DELAY_MS = 1e4;
|
|
8
|
+
var RETRY_DEFAULT_TIMEOUT_MS = 15e3;
|
|
9
|
+
var RETRY_BLOCKCHAIN_BASE_DELAY_MS = 2e3;
|
|
10
|
+
var RETRY_BLOCKCHAIN_MAX_DELAY_MS = 15e3;
|
|
11
|
+
var RETRY_BLOCKCHAIN_TIMEOUT_MS = 3e4;
|
|
12
|
+
var GRAMJS_RETRY_DELAY_MS = 1e3;
|
|
13
|
+
var TOOL_EXECUTION_TIMEOUT_MS = 9e4;
|
|
14
|
+
var SHUTDOWN_TIMEOUT_MS = 1e4;
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
TTS_TIMEOUT_MS,
|
|
18
|
+
BATCH_TRIGGER_DELAY_MS,
|
|
19
|
+
DEFAULT_FETCH_TIMEOUT_MS,
|
|
20
|
+
RETRY_DEFAULT_MAX_ATTEMPTS,
|
|
21
|
+
RETRY_DEFAULT_BASE_DELAY_MS,
|
|
22
|
+
RETRY_DEFAULT_MAX_DELAY_MS,
|
|
23
|
+
RETRY_DEFAULT_TIMEOUT_MS,
|
|
24
|
+
RETRY_BLOCKCHAIN_BASE_DELAY_MS,
|
|
25
|
+
RETRY_BLOCKCHAIN_MAX_DELAY_MS,
|
|
26
|
+
RETRY_BLOCKCHAIN_TIMEOUT_MS,
|
|
27
|
+
GRAMJS_RETRY_DELAY_MS,
|
|
28
|
+
TOOL_EXECUTION_TIMEOUT_MS,
|
|
29
|
+
SHUTDOWN_TIMEOUT_MS
|
|
30
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ALLOWED_EXTENSIONS,
|
|
3
|
+
WORKSPACE_ROOT
|
|
4
|
+
} from "./chunk-EYWNOHMJ.js";
|
|
5
|
+
|
|
6
|
+
// src/workspace/validator.ts
|
|
7
|
+
import { existsSync, lstatSync, readdirSync } from "fs";
|
|
8
|
+
import { resolve, normalize, relative, extname, basename } from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
var WorkspaceSecurityError = class extends Error {
|
|
11
|
+
constructor(message, attemptedPath) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.attemptedPath = attemptedPath;
|
|
14
|
+
this.name = "WorkspaceSecurityError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function decodeRecursive(str) {
|
|
18
|
+
let decoded = str;
|
|
19
|
+
let prev = "";
|
|
20
|
+
let iterations = 0;
|
|
21
|
+
const maxIterations = 10;
|
|
22
|
+
while (decoded !== prev && iterations < maxIterations) {
|
|
23
|
+
prev = decoded;
|
|
24
|
+
try {
|
|
25
|
+
decoded = decodeURIComponent(decoded);
|
|
26
|
+
} catch {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
iterations++;
|
|
30
|
+
}
|
|
31
|
+
return decoded;
|
|
32
|
+
}
|
|
33
|
+
function validatePath(inputPath, allowCreate = false) {
|
|
34
|
+
if (!inputPath || inputPath.trim() === "") {
|
|
35
|
+
throw new WorkspaceSecurityError("Path cannot be empty.", inputPath);
|
|
36
|
+
}
|
|
37
|
+
const trimmedPath = inputPath.trim().replace(/\\/g, "/");
|
|
38
|
+
const decodedPath = decodeRecursive(trimmedPath);
|
|
39
|
+
let absolutePath;
|
|
40
|
+
if (decodedPath.startsWith("/")) {
|
|
41
|
+
absolutePath = resolve(normalize(decodedPath));
|
|
42
|
+
} else if (decodedPath.startsWith("~/")) {
|
|
43
|
+
const expanded = decodedPath.replace(/^~(?=$|[\\/])/, homedir());
|
|
44
|
+
absolutePath = resolve(expanded);
|
|
45
|
+
} else {
|
|
46
|
+
absolutePath = resolve(WORKSPACE_ROOT, normalize(decodedPath));
|
|
47
|
+
}
|
|
48
|
+
const relativePath = relative(WORKSPACE_ROOT, absolutePath);
|
|
49
|
+
if (relativePath.startsWith("..") || relativePath.startsWith("/")) {
|
|
50
|
+
throw new WorkspaceSecurityError(
|
|
51
|
+
`Access denied: Path '${inputPath}' is outside the workspace. Only files in ~/.teleton/workspace/ are accessible.`,
|
|
52
|
+
inputPath
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const exists = existsSync(absolutePath);
|
|
56
|
+
if (!exists && !allowCreate) {
|
|
57
|
+
throw new WorkspaceSecurityError(
|
|
58
|
+
`File not found: '${inputPath}' does not exist in workspace.`,
|
|
59
|
+
inputPath
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
if (exists) {
|
|
63
|
+
const stats = lstatSync(absolutePath);
|
|
64
|
+
if (stats.isSymbolicLink()) {
|
|
65
|
+
throw new WorkspaceSecurityError(
|
|
66
|
+
`Access denied: Symbolic links are not allowed for security reasons.`,
|
|
67
|
+
inputPath
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
absolutePath,
|
|
73
|
+
relativePath,
|
|
74
|
+
exists,
|
|
75
|
+
isDirectory: exists ? lstatSync(absolutePath).isDirectory() : false,
|
|
76
|
+
extension: extname(absolutePath).toLowerCase(),
|
|
77
|
+
filename: basename(absolutePath)
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function validateReadPath(inputPath) {
|
|
81
|
+
const validated = validatePath(inputPath, false);
|
|
82
|
+
if (validated.isDirectory) {
|
|
83
|
+
throw new WorkspaceSecurityError(`Cannot read directory as file: '${inputPath}'`, inputPath);
|
|
84
|
+
}
|
|
85
|
+
return validated;
|
|
86
|
+
}
|
|
87
|
+
var IMMUTABLE_FILES = ["SOUL.md", "STRATEGY.md", "SECURITY.md"];
|
|
88
|
+
function validateWritePath(inputPath, fileType) {
|
|
89
|
+
const validated = validatePath(inputPath, true);
|
|
90
|
+
if (IMMUTABLE_FILES.includes(validated.filename)) {
|
|
91
|
+
throw new WorkspaceSecurityError(
|
|
92
|
+
`Cannot write to ${validated.filename}. This file is configured by the owner. Use memory_write instead.`,
|
|
93
|
+
inputPath
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
if (fileType && ALLOWED_EXTENSIONS[fileType]) {
|
|
97
|
+
const allowedExts = ALLOWED_EXTENSIONS[fileType];
|
|
98
|
+
if (!allowedExts.includes(validated.extension)) {
|
|
99
|
+
throw new WorkspaceSecurityError(
|
|
100
|
+
`Invalid file type: '${validated.extension}' is not allowed for ${fileType}. Allowed: ${allowedExts.join(", ")}`,
|
|
101
|
+
inputPath
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return validated;
|
|
106
|
+
}
|
|
107
|
+
function validateDirectory(inputPath) {
|
|
108
|
+
const validated = validatePath(inputPath, true);
|
|
109
|
+
if (validated.exists && !validated.isDirectory) {
|
|
110
|
+
throw new WorkspaceSecurityError(
|
|
111
|
+
`Path exists but is not a directory: '${inputPath}'`,
|
|
112
|
+
inputPath
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return validated;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
WorkspaceSecurityError,
|
|
120
|
+
validatePath,
|
|
121
|
+
validateReadPath,
|
|
122
|
+
validateWritePath,
|
|
123
|
+
validateDirectory
|
|
124
|
+
};
|