teleton 0.8.4 → 0.8.6

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.
Files changed (84) hide show
  1. package/README.md +40 -17
  2. package/dist/{bootstrap-NNEI3Z5H.js → bootstrap-PFBH6ALD.js} +11 -8
  3. package/dist/bridge-guards-HZTNH7IB.js +9 -0
  4. package/dist/{chunk-NH2CNRKJ.js → chunk-2UUGRY5B.js} +151 -159
  5. package/dist/{chunk-UMUONAD6.js → chunk-4MFN75ZK.js} +5941 -2716
  6. package/dist/{chunk-LC4TV3KL.js → chunk-4MG2AROG.js} +5 -7
  7. package/dist/{chunk-LZQOX6YY.js → chunk-6IFNQWIM.js} +7714 -8748
  8. package/dist/chunk-7KI25UJU.js +215 -0
  9. package/dist/chunk-AX5NBEHX.js +12 -0
  10. package/dist/{chunk-5LOHRZYY.js → chunk-BLUES3FJ.js} +80 -101
  11. package/dist/{chunk-CUE4UZXR.js → chunk-BT2I3ETV.js} +3 -3
  12. package/dist/chunk-CXTZPOTA.js +107 -0
  13. package/dist/{chunk-LVTKJQ7O.js → chunk-D3GT6YIY.js} +59 -7
  14. package/dist/chunk-EKCXKL5M.js +53 -0
  15. package/dist/{chunk-XDZDOKIF.js → chunk-F6S3L3OV.js} +3 -3
  16. package/dist/{chunk-C4NKJT2Z.js → chunk-J4WDJ7XS.js} +1 -1
  17. package/dist/{chunk-G7PCW63M.js → chunk-JYF2MM5I.js} +147 -113
  18. package/dist/{chunk-NVKBBTI6.js → chunk-K3QSIIMZ.js} +9 -6
  19. package/dist/{chunk-EYWNOHMJ.js → chunk-L653KKCR.js} +1 -0
  20. package/dist/chunk-OMQIAWEU.js +273 -0
  21. package/dist/chunk-PCT7GYBP.js +274 -0
  22. package/dist/chunk-QYZBWU2D.js +139 -0
  23. package/dist/{chunk-WTDAICGT.js → chunk-R6W4DJRK.js} +7 -7
  24. package/dist/{chunk-5SEMA47R.js → chunk-RILOEIK6.js} +1 -1
  25. package/dist/{chunk-6OOHHJ4N.js → chunk-TFTNZZDH.js} +20 -20
  26. package/dist/chunk-TTOZCZWE.js +96 -0
  27. package/dist/chunk-UJ54YT2T.js +12 -0
  28. package/dist/{chunk-GHMXWAXI.js → chunk-ULVL2W3D.js} +211 -445
  29. package/dist/{chunk-NQ6FZKCE.js → chunk-V3S3NXBQ.js} +3 -1
  30. package/dist/{chunk-H7MFXJZK.js → chunk-WSL4KIOI.js} +31 -26
  31. package/dist/{chunk-35MX4ZUI.js → chunk-Z5WY7BSB.js} +5 -5
  32. package/dist/{chunk-ALKAAG4O.js → chunk-ZGKE3OTA.js} +112 -49
  33. package/dist/{chunk-JROBTXWY.js → chunk-ZHRDETCX.js} +38 -4
  34. package/dist/cli/index.d.ts +2 -0
  35. package/dist/cli/index.js +272 -159
  36. package/dist/{client-5KD25NOP.js → client-S5UIK6OG.js} +10 -8
  37. package/dist/daily-logs-3WXGYAQF.js +25 -0
  38. package/dist/{get-my-gifts-Y7EN7RK4.js → get-my-gifts-3YSYM3LI.js} +3 -2
  39. package/dist/harden-permissions-PV5SGV5D.js +100 -0
  40. package/dist/index.d.ts +923 -0
  41. package/dist/index.js +29 -20
  42. package/dist/knowledge-RRWUIO3G.js +19 -0
  43. package/dist/{local-IHKJFQJS.js → local-MSZAXWUL.js} +3 -3
  44. package/dist/mcp-loader-OELDFR63.js +15 -0
  45. package/dist/{memory-QMJRM3XJ.js → memory-6U6HGRK2.js} +23 -12
  46. package/dist/memory-hook-T7Y235KY.js +19 -0
  47. package/dist/messages-KV5ADNJB.js +17 -0
  48. package/dist/{migrate-5VBAP52B.js → migrate-AX3HOKOO.js} +10 -7
  49. package/dist/{paths-XA2RJH4S.js → paths-WMVV7ZAJ.js} +1 -1
  50. package/dist/{server-WWGVDFPW.js → server-MFRYOGHR.js} +21 -23
  51. package/dist/{server-AJCOURH7.js → server-SFLCAZFR.js} +221 -27
  52. package/dist/{setup-server-VDY64CWW.js → setup-server-YWAPKZVE.js} +26 -26
  53. package/dist/{store-BY7S6IFN.js → store-PGHQASBC.js} +11 -8
  54. package/dist/{task-dependency-resolver-L6UUMTHK.js → task-dependency-resolver-YQKADDEU.js} +24 -10
  55. package/dist/{task-executor-XBNJLUCS.js → task-executor-LWAWD225.js} +4 -4
  56. package/dist/{tool-adapter-IVX2XQJE.js → tool-adapter-VKLUZSQS.js} +1 -1
  57. package/dist/{tool-index-FTERJSZK.js → tool-index-YEWDF5CK.js} +5 -5
  58. package/dist/{transcript-IM7G25OS.js → transcript-4Y3Z2BJ3.js} +3 -3
  59. package/dist/web/assets/Config-MNxA69ib.js +1 -0
  60. package/dist/web/assets/Conversations-Dk958paA.js +1 -0
  61. package/dist/web/assets/Dashboard-dM18fGOm.js +1 -0
  62. package/dist/web/assets/Hooks-D2griQnI.js +1 -0
  63. package/dist/web/assets/Mcp-CtWNzwsz.js +1 -0
  64. package/dist/web/assets/Memory-CfLwH45G.js +1 -0
  65. package/dist/web/assets/Plugins-3hoJprFo.js +1 -0
  66. package/dist/web/assets/SearchInput-CpcETdpE.js +1 -0
  67. package/dist/web/assets/Soul-BSxE73aK.js +1 -0
  68. package/dist/web/assets/Tasks-DkCkfu3A.js +1 -0
  69. package/dist/web/assets/TelegramSettingsPanel-BRzc5G6e.js +1 -0
  70. package/dist/web/assets/Tools-Du8B8Mb4.js +1 -0
  71. package/dist/web/assets/Wallet-BLILP2Gn.js +1 -0
  72. package/dist/web/assets/Workspace-qklcXpXV.js +1 -0
  73. package/dist/web/assets/index-BwEPTTKp.js +90 -0
  74. package/dist/web/assets/index-noejUsK7.css +1 -0
  75. package/dist/web/assets/{index.es-DitvF-9H.js → index.es-DdpKlnGb.js} +1 -1
  76. package/dist/web/assets/useToolManager-tdxkKn3H.js +1 -0
  77. package/dist/web/assets/utils-CnsbSMo4.js +1 -0
  78. package/dist/web/index.html +2 -2
  79. package/package.json +7 -12
  80. package/src/templates/HEARTBEAT.md +5 -0
  81. package/dist/memory-hook-VUNWZ3NY.js +0 -19
  82. package/dist/web/assets/index-BfYCdwLI.js +0 -80
  83. package/dist/web/assets/index-DmlyQVhR.css +0 -1
  84. package/dist/{chunk-WFTC3JJW.js → chunk-3NO7QU7W.js} +1 -1
@@ -0,0 +1,923 @@
1
+ import { z } from 'zod';
2
+ import { Api } from 'telegram';
3
+ import { Tool as Tool$1, ToolCall } from '@mariozechner/pi-ai';
4
+ import { TSchema } from '@sinclair/typebox';
5
+ import Database from 'better-sqlite3';
6
+ import { HookName, HookHandlerMap } from '@teleton-agent/sdk';
7
+ import { EventEmitter } from 'node:events';
8
+
9
+ interface CompactionConfig {
10
+ enabled: boolean;
11
+ maxMessages?: number;
12
+ maxTokens?: number;
13
+ keepRecentMessages?: number;
14
+ memoryFlushEnabled?: boolean;
15
+ softThresholdTokens?: number;
16
+ }
17
+
18
+ declare const ConfigSchema: z.ZodObject<{
19
+ meta: z.ZodDefault<z.ZodObject<{
20
+ version: z.ZodDefault<z.ZodString>;
21
+ created_at: z.ZodOptional<z.ZodString>;
22
+ last_modified_at: z.ZodOptional<z.ZodString>;
23
+ onboard_command: z.ZodDefault<z.ZodString>;
24
+ }, z.core.$strip>>;
25
+ agent: z.ZodObject<{
26
+ provider: z.ZodDefault<z.ZodEnum<{
27
+ anthropic: "anthropic";
28
+ "claude-code": "claude-code";
29
+ openai: "openai";
30
+ google: "google";
31
+ xai: "xai";
32
+ groq: "groq";
33
+ openrouter: "openrouter";
34
+ moonshot: "moonshot";
35
+ mistral: "mistral";
36
+ cerebras: "cerebras";
37
+ zai: "zai";
38
+ minimax: "minimax";
39
+ huggingface: "huggingface";
40
+ cocoon: "cocoon";
41
+ local: "local";
42
+ }>>;
43
+ api_key: z.ZodDefault<z.ZodString>;
44
+ base_url: z.ZodOptional<z.ZodString>;
45
+ model: z.ZodDefault<z.ZodString>;
46
+ utility_model: z.ZodOptional<z.ZodString>;
47
+ max_tokens: z.ZodDefault<z.ZodNumber>;
48
+ temperature: z.ZodDefault<z.ZodNumber>;
49
+ system_prompt: z.ZodDefault<z.ZodNullable<z.ZodString>>;
50
+ max_agentic_iterations: z.ZodDefault<z.ZodNumber>;
51
+ toolset: z.ZodDefault<z.ZodString>;
52
+ session_reset_policy: z.ZodDefault<z.ZodObject<{
53
+ daily_reset_enabled: z.ZodDefault<z.ZodBoolean>;
54
+ daily_reset_hour: z.ZodDefault<z.ZodNumber>;
55
+ idle_expiry_enabled: z.ZodDefault<z.ZodBoolean>;
56
+ idle_expiry_minutes: z.ZodDefault<z.ZodNumber>;
57
+ }, z.core.$strip>>;
58
+ }, z.core.$strip>;
59
+ telegram: z.ZodObject<{
60
+ mode: z.ZodDefault<z.ZodEnum<{
61
+ user: "user";
62
+ bot: "bot";
63
+ }>>;
64
+ api_id: z.ZodOptional<z.ZodNumber>;
65
+ api_hash: z.ZodOptional<z.ZodString>;
66
+ phone: z.ZodOptional<z.ZodString>;
67
+ session_name: z.ZodDefault<z.ZodString>;
68
+ session_path: z.ZodDefault<z.ZodString>;
69
+ dm_policy: z.ZodDefault<z.ZodEnum<{
70
+ allowlist: "allowlist";
71
+ open: "open";
72
+ "admin-only": "admin-only";
73
+ disabled: "disabled";
74
+ }>>;
75
+ allow_from: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
76
+ group_policy: z.ZodDefault<z.ZodEnum<{
77
+ allowlist: "allowlist";
78
+ open: "open";
79
+ "admin-only": "admin-only";
80
+ disabled: "disabled";
81
+ }>>;
82
+ group_allow_from: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
83
+ require_mention: z.ZodDefault<z.ZodBoolean>;
84
+ max_message_length: z.ZodDefault<z.ZodNumber>;
85
+ typing_simulation: z.ZodDefault<z.ZodBoolean>;
86
+ rate_limit_messages_per_second: z.ZodDefault<z.ZodNumber>;
87
+ rate_limit_groups_per_minute: z.ZodDefault<z.ZodNumber>;
88
+ admin_ids: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
89
+ agent_channel: z.ZodDefault<z.ZodNullable<z.ZodString>>;
90
+ owner_name: z.ZodOptional<z.ZodString>;
91
+ owner_username: z.ZodOptional<z.ZodString>;
92
+ owner_id: z.ZodOptional<z.ZodNumber>;
93
+ debounce_ms: z.ZodDefault<z.ZodNumber>;
94
+ bot_token: z.ZodOptional<z.ZodString>;
95
+ bot_username: z.ZodOptional<z.ZodString>;
96
+ stream_mode: z.ZodDefault<z.ZodEnum<{
97
+ all: "all";
98
+ replace: "replace";
99
+ off: "off";
100
+ }>>;
101
+ }, z.core.$strip>;
102
+ storage: z.ZodDefault<z.ZodObject<{
103
+ sessions_file: z.ZodDefault<z.ZodString>;
104
+ memory_file: z.ZodDefault<z.ZodString>;
105
+ history_limit: z.ZodDefault<z.ZodNumber>;
106
+ }, z.core.$strip>>;
107
+ embedding: z.ZodDefault<z.ZodObject<{
108
+ provider: z.ZodDefault<z.ZodEnum<{
109
+ anthropic: "anthropic";
110
+ local: "local";
111
+ none: "none";
112
+ }>>;
113
+ model: z.ZodOptional<z.ZodString>;
114
+ }, z.core.$strip>>;
115
+ deals: z.ZodDefault<z.ZodObject<{
116
+ enabled: z.ZodDefault<z.ZodBoolean>;
117
+ expiry_seconds: z.ZodDefault<z.ZodNumber>;
118
+ buy_max_floor_percent: z.ZodDefault<z.ZodNumber>;
119
+ sell_min_floor_percent: z.ZodDefault<z.ZodNumber>;
120
+ poll_interval_ms: z.ZodDefault<z.ZodNumber>;
121
+ max_verification_retries: z.ZodDefault<z.ZodNumber>;
122
+ expiry_check_interval_ms: z.ZodDefault<z.ZodNumber>;
123
+ }, z.core.$strip>>;
124
+ webui: z.ZodDefault<z.ZodObject<{
125
+ enabled: z.ZodDefault<z.ZodBoolean>;
126
+ port: z.ZodDefault<z.ZodNumber>;
127
+ host: z.ZodDefault<z.ZodString>;
128
+ auth_token: z.ZodOptional<z.ZodString>;
129
+ cors_origins: z.ZodDefault<z.ZodArray<z.ZodString>>;
130
+ log_requests: z.ZodDefault<z.ZodBoolean>;
131
+ }, z.core.$strip>>;
132
+ logging: z.ZodDefault<z.ZodObject<{
133
+ level: z.ZodDefault<z.ZodEnum<{
134
+ fatal: "fatal";
135
+ error: "error";
136
+ warn: "warn";
137
+ info: "info";
138
+ debug: "debug";
139
+ trace: "trace";
140
+ }>>;
141
+ pretty: z.ZodDefault<z.ZodBoolean>;
142
+ }, z.core.$strip>>;
143
+ dev: z.ZodDefault<z.ZodObject<{
144
+ hot_reload: z.ZodDefault<z.ZodBoolean>;
145
+ }, z.core.$strip>>;
146
+ tool_rag: z.ZodDefault<z.ZodObject<{
147
+ enabled: z.ZodDefault<z.ZodBoolean>;
148
+ top_k: z.ZodDefault<z.ZodNumber>;
149
+ always_include: z.ZodDefault<z.ZodArray<z.ZodString>>;
150
+ skip_unlimited_providers: z.ZodDefault<z.ZodBoolean>;
151
+ }, z.core.$strip>>;
152
+ capabilities: z.ZodDefault<z.ZodObject<{
153
+ exec: z.ZodDefault<z.ZodObject<{
154
+ mode: z.ZodDefault<z.ZodEnum<{
155
+ off: "off";
156
+ yolo: "yolo";
157
+ }>>;
158
+ scope: z.ZodDefault<z.ZodEnum<{
159
+ allowlist: "allowlist";
160
+ "admin-only": "admin-only";
161
+ all: "all";
162
+ }>>;
163
+ allowlist: z.ZodDefault<z.ZodArray<z.ZodNumber>>;
164
+ limits: z.ZodDefault<z.ZodObject<{
165
+ timeout: z.ZodDefault<z.ZodNumber>;
166
+ max_output: z.ZodDefault<z.ZodNumber>;
167
+ }, z.core.$strip>>;
168
+ audit: z.ZodDefault<z.ZodObject<{
169
+ log_commands: z.ZodDefault<z.ZodBoolean>;
170
+ }, z.core.$strip>>;
171
+ }, z.core.$strip>>;
172
+ }, z.core.$strip>>;
173
+ api: z.ZodOptional<z.ZodDefault<z.ZodObject<{
174
+ enabled: z.ZodDefault<z.ZodBoolean>;
175
+ port: z.ZodDefault<z.ZodNumber>;
176
+ key_hash: z.ZodDefault<z.ZodString>;
177
+ allowed_ips: z.ZodDefault<z.ZodArray<z.ZodString>>;
178
+ }, z.core.$strip>>>;
179
+ ton_proxy: z.ZodDefault<z.ZodObject<{
180
+ enabled: z.ZodDefault<z.ZodBoolean>;
181
+ port: z.ZodDefault<z.ZodNumber>;
182
+ binary_path: z.ZodOptional<z.ZodString>;
183
+ }, z.core.$strip>>;
184
+ heartbeat: z.ZodDefault<z.ZodObject<{
185
+ enabled: z.ZodDefault<z.ZodBoolean>;
186
+ interval_ms: z.ZodDefault<z.ZodNumber>;
187
+ prompt: z.ZodDefault<z.ZodString>;
188
+ self_configurable: z.ZodDefault<z.ZodBoolean>;
189
+ }, z.core.$strip>>;
190
+ mcp: z.ZodDefault<z.ZodObject<{
191
+ servers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
192
+ command: z.ZodOptional<z.ZodString>;
193
+ args: z.ZodOptional<z.ZodArray<z.ZodString>>;
194
+ env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
195
+ url: z.ZodOptional<z.ZodString>;
196
+ scope: z.ZodDefault<z.ZodEnum<{
197
+ allowlist: "allowlist";
198
+ open: "open";
199
+ "admin-only": "admin-only";
200
+ disabled: "disabled";
201
+ always: "always";
202
+ "dm-only": "dm-only";
203
+ "group-only": "group-only";
204
+ }>>;
205
+ enabled: z.ZodDefault<z.ZodBoolean>;
206
+ }, z.core.$strip>>>;
207
+ }, z.core.$strip>>;
208
+ plugins: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
209
+ cocoon: z.ZodOptional<z.ZodObject<{
210
+ port: z.ZodDefault<z.ZodNumber>;
211
+ }, z.core.$strip>>;
212
+ tonapi_key: z.ZodOptional<z.ZodString>;
213
+ toncenter_api_key: z.ZodOptional<z.ZodString>;
214
+ tavily_api_key: z.ZodOptional<z.ZodString>;
215
+ }, z.core.$strip>;
216
+ type Config = z.infer<typeof ConfigSchema>;
217
+
218
+ interface TelegramMessage$1 {
219
+ id: number;
220
+ chatId: string;
221
+ senderId: number;
222
+ senderUsername?: string;
223
+ senderFirstName?: string;
224
+ senderRank?: string;
225
+ text: string;
226
+ isGroup: boolean;
227
+ isChannel: boolean;
228
+ isBot: boolean;
229
+ mentionsMe: boolean;
230
+ timestamp: Date;
231
+ _rawPeer?: Api.TypePeer;
232
+ hasMedia: boolean;
233
+ mediaType?: "photo" | "document" | "video" | "audio" | "voice" | "sticker";
234
+ replyToId?: number;
235
+ _rawMessage?: Api.Message;
236
+ }
237
+ interface InlineButton {
238
+ text: string;
239
+ callback_data: string;
240
+ }
241
+ interface SendMessageOptions {
242
+ chatId: string;
243
+ text: string;
244
+ replyToId?: number;
245
+ inlineKeyboard?: InlineButton[][];
246
+ }
247
+ interface SentMessage {
248
+ id: number;
249
+ date: number;
250
+ chatId: string;
251
+ }
252
+ interface EditMessageOptions {
253
+ chatId: string;
254
+ messageId: number;
255
+ text: string;
256
+ inlineKeyboard?: InlineButton[][];
257
+ }
258
+ interface ReplyContext {
259
+ text?: string;
260
+ senderName?: string;
261
+ isAgent?: boolean;
262
+ }
263
+ interface BotInfo {
264
+ id: number;
265
+ username?: string;
266
+ firstName: string;
267
+ isBot: boolean;
268
+ }
269
+ interface ChatInfo {
270
+ id: string;
271
+ title?: string;
272
+ type: "private" | "group" | "supergroup" | "channel";
273
+ memberCount?: number;
274
+ description?: string;
275
+ username?: string;
276
+ }
277
+ interface ITelegramBridge {
278
+ connect(): Promise<void>;
279
+ disconnect(): Promise<void>;
280
+ isAvailable(): boolean;
281
+ getMode(): "user" | "bot";
282
+ getOwnUserId(): bigint | undefined;
283
+ getUsername(): string | undefined;
284
+ getMe(): Promise<BotInfo | undefined>;
285
+ getMessages(chatId: string, limit: number): Promise<TelegramMessage$1[]>;
286
+ sendMessage(options: SendMessageOptions): Promise<SentMessage>;
287
+ editMessage(options: EditMessageOptions): Promise<SentMessage>;
288
+ deleteMessage(chatId: string, messageId: number): Promise<boolean>;
289
+ forwardMessage(fromChatId: string, toChatId: string, messageId: number): Promise<SentMessage>;
290
+ sendPhoto(chatId: string, photo: string | Buffer, caption?: string, replyToId?: number): Promise<SentMessage>;
291
+ setTyping(chatId: string): Promise<void>;
292
+ sendReaction(chatId: string, messageId: number, emoji: string): Promise<void>;
293
+ pinMessage(chatId: string, messageId: number): Promise<boolean>;
294
+ sendDice(chatId: string, emoji?: string): Promise<SentMessage>;
295
+ getChatInfo(chatId: string): Promise<ChatInfo>;
296
+ /** Stream a response token by token via message drafts (bot mode). Returns final sent message. */
297
+ streamResponse?(chatId: string, textStream: AsyncIterable<string>): Promise<SentMessage>;
298
+ onNewMessage(handler: (msg: TelegramMessage$1) => void | Promise<void>, filters?: {
299
+ incoming?: boolean;
300
+ outgoing?: boolean;
301
+ chats?: string[];
302
+ }): void;
303
+ fetchReplyContext(rawMsg: unknown): Promise<ReplyContext | null>;
304
+ getPeer(chatId: string): unknown | undefined;
305
+ getRawClient(): unknown;
306
+ }
307
+
308
+ interface EmbeddingProvider {
309
+ id: string;
310
+ model: string;
311
+ dimensions: number;
312
+ embedQuery(text: string): Promise<number[]>;
313
+ embedBatch(texts: string[]): Promise<number[][]>;
314
+ /** Optional startup warmup — pre-load model, validate credentials, etc. */
315
+ warmup?(): Promise<boolean>;
316
+ }
317
+ interface EmbeddingProviderConfig {
318
+ provider: "anthropic" | "local" | "none";
319
+ model?: string;
320
+ apiKey?: string;
321
+ dimensions?: number;
322
+ }
323
+
324
+ /**
325
+ * Context provided to tool executors
326
+ */
327
+ interface ToolContext {
328
+ /** Telegram bridge for sending messages, reactions, etc. */
329
+ bridge: ITelegramBridge;
330
+ /** Database instance for storage */
331
+ db: Database.Database;
332
+ /** Current chat ID where the tool is being executed */
333
+ chatId: string;
334
+ /** Current user/sender ID */
335
+ senderId: number;
336
+ /** Whether this is a group chat */
337
+ isGroup: boolean;
338
+ /** Full config for accessing API key, model, etc. (optional) */
339
+ config?: Config;
340
+ }
341
+ /**
342
+ * Result returned by a tool execution
343
+ */
344
+ interface ToolResult {
345
+ /** Whether the execution was successful */
346
+ success: boolean;
347
+ /** Result data (will be serialized to JSON for the LLM) */
348
+ data?: unknown;
349
+ /** Error message if failed */
350
+ error?: string;
351
+ }
352
+ /**
353
+ * Tool category for masking behavior
354
+ */
355
+ type ToolCategory = "data-bearing" | "action";
356
+ /**
357
+ * Tool scope for context-based filtering.
358
+ * - "open": included in both DMs and groups (default, canonical form)
359
+ * - "always": legacy alias for "open" (backward compat)
360
+ * - "dm-only": excluded from group chats (financial, private tools)
361
+ * - "group-only": excluded from DMs (moderation tools)
362
+ * - "admin-only": restricted to admin users only
363
+ * - "allowlist": restricted to allow_from user IDs (admins bypass)
364
+ * - "disabled": tool completely hidden from all contexts
365
+ */
366
+ type ToolScope = "open" | "always" | "dm-only" | "group-only" | "admin-only" | "allowlist" | "disabled";
367
+ /**
368
+ * Tool definition compatible with pi-ai
369
+ */
370
+ interface Tool<TParameters extends TSchema = TSchema> {
371
+ /** Unique tool name (e.g., "telegram_send_message") */
372
+ name: string;
373
+ /** Human-readable description for the LLM */
374
+ description: string;
375
+ /** TypeBox schema for parameter validation */
376
+ parameters: TParameters;
377
+ /** Tool category (affects masking behavior) */
378
+ category?: ToolCategory;
379
+ }
380
+ /**
381
+ * Tool executor function
382
+ */
383
+ type ToolExecutor<TParams = unknown> = (params: TParams, context: ToolContext) => Promise<ToolResult>;
384
+
385
+ type ModuleLevel = "open" | "admin" | "disabled";
386
+ /**
387
+ * Per-group module permission manager.
388
+ * Only non-default overrides (level !== "open") are stored in DB.
389
+ */
390
+ declare class ModulePermissions {
391
+ private db;
392
+ private cache;
393
+ constructor(db: Database.Database);
394
+ private ensureTable;
395
+ private loadAll;
396
+ getLevel(chatId: string, module: string): ModuleLevel;
397
+ setLevel(chatId: string, module: string, level: ModuleLevel, userId?: number): void;
398
+ resetModule(chatId: string, module: string): void;
399
+ resetAll(chatId: string): void;
400
+ getOverrides(chatId: string): Map<string, ModuleLevel>;
401
+ isProtected(module: string): boolean;
402
+ }
403
+
404
+ interface ToolIndexConfig {
405
+ topK: number;
406
+ alwaysInclude: string[];
407
+ skipUnlimitedProviders: boolean;
408
+ }
409
+ interface ToolSearchResult {
410
+ name: string;
411
+ description: string;
412
+ score: number;
413
+ vectorScore?: number;
414
+ keywordScore?: number;
415
+ }
416
+ /**
417
+ * Semantic index for tool definitions.
418
+ * Uses the same hybrid search pattern (vector + FTS5) as the knowledge RAG.
419
+ */
420
+ declare class ToolIndex {
421
+ private db;
422
+ private embedder;
423
+ private vectorEnabled;
424
+ private config;
425
+ private _isIndexed;
426
+ constructor(db: Database.Database, embedder: EmbeddingProvider, vectorEnabled: boolean, config: ToolIndexConfig);
427
+ get isIndexed(): boolean;
428
+ /**
429
+ * Create the vector table (dimensions are dynamic, so can't be in schema migration).
430
+ */
431
+ ensureSchema(): void;
432
+ /**
433
+ * Index all registered tools. Replaces any previous index.
434
+ */
435
+ indexAll(tools: Tool$1[]): Promise<number>;
436
+ /**
437
+ * Delta update for hot-reload plugins.
438
+ */
439
+ reindexTools(removed: string[], added: Tool$1[]): Promise<void>;
440
+ /**
441
+ * Hybrid search: vector + FTS5, same pattern as HybridSearch.
442
+ */
443
+ search(query: string, queryEmbedding: number[], limit?: number): Promise<ToolSearchResult[]>;
444
+ /**
445
+ * Check if a tool name matches any always-include pattern.
446
+ */
447
+ isAlwaysIncluded(toolName: string): boolean;
448
+ private vectorSearch;
449
+ private keywordSearch;
450
+ private mergeResults;
451
+ }
452
+
453
+ declare class ToolRegistry {
454
+ private tools;
455
+ private scopes;
456
+ private toolModules;
457
+ private permissions;
458
+ private toolArrayCache;
459
+ private toolConfigs;
460
+ private db;
461
+ private pluginToolNames;
462
+ private toolIndex;
463
+ private onToolsChangedCallbacks;
464
+ private mode;
465
+ private requiredModes;
466
+ private toolTags;
467
+ private activeToolset;
468
+ private allowFrom;
469
+ private static readonly TOOLSET_PROFILES;
470
+ constructor(mode?: "user" | "bot");
471
+ register<TParams = unknown>(tool: Tool, executor: ToolExecutor<TParams>, scope?: ToolScope, requiredMode?: "user" | "bot", tags?: string[]): void;
472
+ setPermissions(mp: ModulePermissions): void;
473
+ setMode(mode: "user" | "bot"): void;
474
+ setActiveToolset(name: string | null): void;
475
+ setAllowFrom(ids: number[]): void;
476
+ getActiveToolset(): string | null;
477
+ getAvailableToolsets(): string[];
478
+ getAvailableModules(): string[];
479
+ getModuleToolCount(module: string): number;
480
+ getModuleTools(module: string): Array<{
481
+ name: string;
482
+ scope: ToolScope;
483
+ }>;
484
+ getAll(): Tool$1[];
485
+ execute(toolCall: ToolCall, context: ToolContext): Promise<ToolResult>;
486
+ getForProvider(toolLimit: number | null): Tool$1[];
487
+ getForContext(isGroup: boolean, toolLimit: number | null, chatId?: string, isAdmin?: boolean, senderId?: number): Tool$1[];
488
+ isPluginModule(moduleName: string): boolean;
489
+ has(name: string): boolean;
490
+ get count(): number;
491
+ getToolCategory(name: string): "data-bearing" | "action" | undefined;
492
+ /**
493
+ * Load tool configurations from database and seed missing ones
494
+ */
495
+ loadConfigFromDB(db: Database.Database): void;
496
+ /**
497
+ * Get effective scope for a tool (config override or default)
498
+ */
499
+ private getEffectiveScope;
500
+ /**
501
+ * Check if a tool is enabled
502
+ */
503
+ isToolEnabled(toolName: string): boolean;
504
+ /**
505
+ * Update tool enabled status
506
+ */
507
+ setToolEnabled(toolName: string, enabled: boolean, updatedBy?: number): boolean;
508
+ /**
509
+ * Update tool scope
510
+ */
511
+ updateToolScope(toolName: string, scope: ToolScope, updatedBy?: number): boolean;
512
+ /**
513
+ * Get tool configuration
514
+ */
515
+ getToolConfig(toolName: string): {
516
+ enabled: boolean;
517
+ scope: ToolScope;
518
+ } | null;
519
+ /**
520
+ * Register all tools belonging to a plugin (tracks ownership for hot-reload).
521
+ */
522
+ registerPluginTools(pluginName: string, tools: Array<{
523
+ tool: Tool;
524
+ executor: ToolExecutor;
525
+ scope?: ToolScope;
526
+ }>): number;
527
+ /**
528
+ * Replace all tools belonging to a plugin with new ones (hot-reload).
529
+ * Atomically removes old tools then registers new ones.
530
+ */
531
+ replacePluginTools(pluginName: string, newTools: Array<{
532
+ tool: Tool;
533
+ executor: ToolExecutor;
534
+ scope?: ToolScope;
535
+ }>): void;
536
+ /**
537
+ * Remove all tools belonging to a plugin.
538
+ */
539
+ removePluginTools(pluginName: string): void;
540
+ setToolIndex(index: ToolIndex): void;
541
+ getToolIndex(): ToolIndex | null;
542
+ onToolsChanged(callback: (removed: string[], added: Tool$1[]) => void): void;
543
+ private notifyToolsChanged;
544
+ /**
545
+ * Select tools using semantic RAG search on the user message.
546
+ * Falls back to getForContext() if search returns nothing.
547
+ */
548
+ getForContextWithRAG(query: string, queryEmbedding: number[], isGroup: boolean, toolLimit: number | null, chatId?: string, isAdmin?: boolean, senderId?: number): Promise<Tool$1[]>;
549
+ private applyLimit;
550
+ }
551
+
552
+ /**
553
+ * Hook registration entry.
554
+ *
555
+ * Priority ranges (convention):
556
+ * -100 to -1 : Security gates, auth checks, spam filters
557
+ * 0 : Default — standard plugin logic
558
+ * 1 to 49 : Post-processing, enrichment
559
+ * 50 to 99 : Audit, logging, observability
560
+ * 100+ : Reserved — always-last guarantees
561
+ */
562
+ interface HookRegistration<K extends HookName = HookName> {
563
+ pluginId: string;
564
+ hookName: K;
565
+ handler: HookHandlerMap[K];
566
+ priority: number;
567
+ /** Plugin-level priority offset (from plugin_config DB table). Default 0. */
568
+ globalPriority: number;
569
+ }
570
+ interface HookRunnerOptions {
571
+ logger: {
572
+ warn: (...args: unknown[]) => void;
573
+ error: (...args: unknown[]) => void;
574
+ debug: (...args: unknown[]) => void;
575
+ };
576
+ timeoutMs?: number;
577
+ catchErrors?: boolean;
578
+ }
579
+
580
+ declare class HookRegistry {
581
+ private hooks;
582
+ private hookMap;
583
+ private rebuildMap;
584
+ register<K extends HookName>(reg: Omit<HookRegistration<K>, "globalPriority"> & {
585
+ globalPriority?: number;
586
+ }): boolean;
587
+ getHooks<K extends HookName>(name: K): HookRegistration<K>[];
588
+ hasHooks(name: HookName): boolean;
589
+ hasAnyHooks(): boolean;
590
+ unregister(pluginId: string): number;
591
+ clear(): void;
592
+ }
593
+
594
+ declare function createHookRunner(registry: HookRegistry, opts: HookRunnerOptions): {
595
+ runModifyingHook: <K extends HookName>(name: K, event: Parameters<HookHandlerMap[K]>[0]) => Promise<void>;
596
+ runObservingHook: <K extends HookName>(name: K, event: Parameters<HookHandlerMap[K]>[0]) => Promise<void>;
597
+ readonly depth: number;
598
+ };
599
+
600
+ /**
601
+ * UserHookEvaluator — keyword blocklist + context injection triggers.
602
+ * Hot-reloadable: call reload() after DB changes, no restart needed.
603
+ */
604
+
605
+ interface UserHookResult {
606
+ blocked: boolean;
607
+ blockMessage?: string;
608
+ additionalContext: string;
609
+ }
610
+ declare class UserHookEvaluator {
611
+ private db;
612
+ private blocklistEnabled;
613
+ private singleKeywords;
614
+ private multiKeywords;
615
+ private blockMessage;
616
+ private triggers;
617
+ constructor(db: Database.Database);
618
+ /** Reload config from DB — called on startup and after WebUI changes */
619
+ reload(): void;
620
+ /** Evaluate a message — returns { blocked, blockMessage, additionalContext } */
621
+ evaluate(text: string): UserHookResult;
622
+ }
623
+
624
+ interface ProcessMessageOptions {
625
+ chatId: string;
626
+ userMessage: string;
627
+ userName?: string;
628
+ timestamp?: number;
629
+ isGroup?: boolean;
630
+ pendingContext?: string | null;
631
+ toolContext?: Omit<ToolContext, "chatId" | "isGroup">;
632
+ senderUsername?: string;
633
+ senderRank?: string;
634
+ hasMedia?: boolean;
635
+ mediaType?: string;
636
+ messageId?: number;
637
+ replyContext?: {
638
+ senderName?: string;
639
+ text: string;
640
+ isAgent?: boolean;
641
+ };
642
+ isHeartbeat?: boolean;
643
+ streamToChat?: {
644
+ chatId: string;
645
+ bridge: ITelegramBridge;
646
+ mode: "all" | "replace" | "off";
647
+ };
648
+ }
649
+ interface AgentResponse {
650
+ content: string;
651
+ toolCalls?: Array<{
652
+ name: string;
653
+ input: Record<string, unknown>;
654
+ }>;
655
+ streamed?: boolean;
656
+ }
657
+ declare class AgentRuntime {
658
+ private config;
659
+ private soul;
660
+ private compactionManager;
661
+ private contextBuilder;
662
+ private toolRegistry;
663
+ private embedder;
664
+ private hookRunner?;
665
+ private userHookEvaluator?;
666
+ constructor(config: Config, soul?: string, toolRegistry?: ToolRegistry);
667
+ setHookRunner(runner: ReturnType<typeof createHookRunner>): void;
668
+ setUserHookEvaluator(evaluator: UserHookEvaluator): void;
669
+ initializeContextBuilder(embedder: EmbeddingProvider, vectorEnabled: boolean): void;
670
+ getToolRegistry(): ToolRegistry | null;
671
+ processMessage(opts: ProcessMessageOptions): Promise<AgentResponse>;
672
+ clearHistory(chatId: string): void;
673
+ getConfig(): Config;
674
+ getActiveChatIds(): string[];
675
+ setSoul(soul: string): void;
676
+ configureCompaction(config: {
677
+ enabled?: boolean;
678
+ maxMessages?: number;
679
+ maxTokens?: number;
680
+ }): void;
681
+ getCompactionConfig(): CompactionConfig;
682
+ private _memoryStatsCache;
683
+ getMemoryStats(): {
684
+ totalMessages: number;
685
+ totalChats: number;
686
+ knowledgeChunks: number;
687
+ };
688
+ }
689
+
690
+ declare function createEmbeddingProvider(config: EmbeddingProviderConfig): EmbeddingProvider;
691
+
692
+ declare class KnowledgeIndexer {
693
+ private db;
694
+ private workspaceDir;
695
+ private embedder;
696
+ private vectorEnabled;
697
+ constructor(db: Database.Database, workspaceDir: string, embedder: EmbeddingProvider, vectorEnabled: boolean);
698
+ getEmbedder(): EmbeddingProvider;
699
+ indexAll(options?: {
700
+ force?: boolean;
701
+ }): Promise<{
702
+ indexed: number;
703
+ skipped: number;
704
+ }>;
705
+ indexFile(absPath: string, force?: boolean): Promise<boolean>;
706
+ pruneOrphans(): Promise<{
707
+ markedInactive: number;
708
+ deleted: number;
709
+ }>;
710
+ private listMemoryFiles;
711
+ private getMemoryType;
712
+ /**
713
+ * Chunk markdown content with structure awareness.
714
+ * Respects heading boundaries, code blocks, and list groups.
715
+ * Target: KNOWLEDGE_CHUNK_SIZE chars, hard max: 2x target.
716
+ */
717
+ private chunkMarkdown;
718
+ }
719
+
720
+ interface TelegramMessage {
721
+ id: string;
722
+ chatId: string;
723
+ senderId: string | null;
724
+ text: string | null;
725
+ replyToId?: string;
726
+ isFromAgent: boolean;
727
+ hasMedia: boolean;
728
+ mediaType?: string;
729
+ timestamp: number;
730
+ }
731
+ declare class MessageStore {
732
+ private db;
733
+ private embedder;
734
+ private vectorEnabled;
735
+ constructor(db: Database.Database, embedder: EmbeddingProvider, vectorEnabled: boolean);
736
+ private ensureChat;
737
+ private ensureUser;
738
+ storeMessage(message: TelegramMessage): Promise<void>;
739
+ pruneOldMessages(maxAgeDays?: number): number;
740
+ getRecentMessages(chatId: string, limit?: number): TelegramMessage[];
741
+ }
742
+
743
+ interface ContextOptions {
744
+ query: string;
745
+ chatId: string;
746
+ includeAgentMemory?: boolean;
747
+ includeFeedHistory?: boolean;
748
+ searchAllChats?: boolean;
749
+ maxRecentMessages?: number;
750
+ maxRelevantChunks?: number;
751
+ maxTokens?: number;
752
+ queryEmbedding?: number[];
753
+ }
754
+ interface Context {
755
+ recentMessages: Array<{
756
+ role: string;
757
+ content: string;
758
+ }>;
759
+ relevantKnowledge: string[];
760
+ relevantFeed: string[];
761
+ estimatedTokens: number;
762
+ }
763
+ declare class ContextBuilder {
764
+ private db;
765
+ private embedder;
766
+ private hybridSearch;
767
+ private messageStore;
768
+ constructor(db: Database.Database, embedder: EmbeddingProvider, vectorEnabled: boolean);
769
+ buildContext(options: ContextOptions): Promise<Context>;
770
+ }
771
+
772
+ interface MemorySystem {
773
+ db: Database.Database;
774
+ embedder: ReturnType<typeof createEmbeddingProvider>;
775
+ knowledge: KnowledgeIndexer;
776
+ messages: MessageStore;
777
+ context: ContextBuilder;
778
+ }
779
+
780
+ type AgentState = "stopped" | "starting" | "running" | "stopping";
781
+ declare class AgentLifecycle extends EventEmitter {
782
+ private state;
783
+ private error;
784
+ private startPromise;
785
+ private stopPromise;
786
+ private runningSince;
787
+ private registeredStartFn;
788
+ private registeredStopFn;
789
+ getState(): AgentState;
790
+ getError(): string | undefined;
791
+ getUptime(): number | null;
792
+ /**
793
+ * Register the start/stop callbacks so start()/stop() can be called without args.
794
+ */
795
+ registerCallbacks(startFn: () => Promise<void>, stopFn: () => Promise<void>): void;
796
+ /**
797
+ * Start the agent. Uses the provided callback or falls back to registered one.
798
+ * - No-op if already running
799
+ * - Returns existing promise if already starting
800
+ * - Throws if currently stopping
801
+ */
802
+ start(startFn?: () => Promise<void>): Promise<void>;
803
+ /**
804
+ * Stop the agent. Uses the provided callback or falls back to registered one.
805
+ * - No-op if already stopped
806
+ * - Returns existing promise if already stopping
807
+ * - If starting, waits for start to complete then stops
808
+ */
809
+ stop(stopFn?: () => Promise<void>): Promise<void>;
810
+ private transition;
811
+ }
812
+
813
+ declare class TeletonApp {
814
+ private config;
815
+ private agent;
816
+ private bridge;
817
+ private messageHandler;
818
+ private adminHandler;
819
+ private debouncer;
820
+ private toolCount;
821
+ private toolRegistry;
822
+ private modules;
823
+ private builtinModuleCount;
824
+ private memory;
825
+ private sdkDeps;
826
+ private webuiServer;
827
+ private apiServer;
828
+ private pluginWatcher;
829
+ private mcpConnections;
830
+ private callbackHandlerRegistered;
831
+ private messageHandlersRegistered;
832
+ private lifecycle;
833
+ private hookRunner?;
834
+ private userHookEvaluator;
835
+ private startTime;
836
+ private messagesProcessed;
837
+ private heartbeatRunner;
838
+ private scheduledTaskHandler;
839
+ private configPath;
840
+ private getMcpServerInfo;
841
+ private buildServerDeps;
842
+ constructor(configPath?: string);
843
+ /**
844
+ * Get the lifecycle state machine for WebUI integration
845
+ */
846
+ getLifecycle(): AgentLifecycle;
847
+ getAgent(): AgentRuntime;
848
+ getBridge(): ITelegramBridge;
849
+ getMemory(): MemorySystem;
850
+ getToolRegistry(): ToolRegistry;
851
+ getPlugins(): {
852
+ name: string;
853
+ version: string;
854
+ }[];
855
+ getWebuiConfig(): {
856
+ enabled: boolean;
857
+ port: number;
858
+ host: string;
859
+ cors_origins: string[];
860
+ log_requests: boolean;
861
+ auth_token?: string | undefined;
862
+ };
863
+ getConfigPath(): string;
864
+ /** Start agent subsystems without WebUI/API servers. For bootstrap mode. */
865
+ startAgentSubsystems(): Promise<void>;
866
+ /** Stop agent subsystems and close database. For bootstrap mode. */
867
+ stopAgentSubsystems(): Promise<void>;
868
+ /**
869
+ * Start the agent
870
+ */
871
+ start(): Promise<void>;
872
+ /**
873
+ * Start agent subsystems (Telegram, plugins, MCP, modules, debouncer, handler).
874
+ * Called by lifecycle.start() — do NOT call directly.
875
+ */
876
+ private startAgent;
877
+ /**
878
+ * Wire bot-mode SDK deps, callback handler, and Grammy polling.
879
+ */
880
+ private wireBotMode;
881
+ /**
882
+ * Wire user-mode SDK deps from DealBot and register service message handler.
883
+ */
884
+ private wireUserMode;
885
+ /**
886
+ * Register provider-specific models (Cocoon Network / local LLM).
887
+ */
888
+ private initializeProviders;
889
+ /**
890
+ * Start module background jobs with timeout. Skips deals module in bot mode.
891
+ */
892
+ private startModules;
893
+ /**
894
+ * Resolve owner name and username from Telegram API if not already configured.
895
+ * Persists resolved values to the config file so this only happens once.
896
+ */
897
+ private resolveOwnerInfo;
898
+ /**
899
+ * Handle a single message (extracted for debouncer callback)
900
+ */
901
+ private handleSingleMessage;
902
+ /**
903
+ * Collect plugin onMessage/onCallbackQuery hooks and register them.
904
+ * Uses dynamic dispatch over this.modules so newly installed/uninstalled
905
+ * plugins are picked up without re-registering handlers.
906
+ */
907
+ private wirePluginEventHooks;
908
+ /**
909
+ * Stop the agent
910
+ */
911
+ stop(): Promise<void>;
912
+ /**
913
+ * Stop agent subsystems (watcher, MCP, debouncer, handler, modules, bridge).
914
+ * Called by lifecycle.stop() — do NOT call directly.
915
+ */
916
+ private stopAgent;
917
+ }
918
+ /**
919
+ * Start the application
920
+ */
921
+ declare function main(configPath?: string): Promise<void>;
922
+
923
+ export { TeletonApp, main };