@fonz/tgcc 0.0.1 → 0.2.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.
@@ -0,0 +1,511 @@
1
+ // ── HTML safety & conversion ──
2
+ /** Escape characters that are special in Telegram HTML. */
3
+ export function escapeHtml(text) {
4
+ return text
5
+ .replace(/&/g, '&')
6
+ .replace(/</g, '&lt;')
7
+ .replace(/>/g, '&gt;');
8
+ }
9
+ /**
10
+ * Convert markdown-ish text to Telegram-safe HTML.
11
+ * Handles code blocks, inline code, bold, italic, strikethrough, links.
12
+ * Falls back to HTML-escaped plain text for anything it can't convert.
13
+ */
14
+ export function markdownToHtml(text) {
15
+ // First, extract code blocks to protect them from other conversions
16
+ const codeBlocks = [];
17
+ let result = text.replace(/```(\w*)\n?([\s\S]*?)```/g, (_match, lang, code) => {
18
+ const idx = codeBlocks.length;
19
+ const langAttr = lang ? ` class="language-${escapeHtml(lang)}"` : '';
20
+ codeBlocks.push(`<pre><code${langAttr}>${escapeHtml(code.replace(/\n$/, ''))}</code></pre>`);
21
+ return `\x00CODEBLOCK${idx}\x00`;
22
+ });
23
+ // Extract inline code
24
+ const inlineCodes = [];
25
+ result = result.replace(/`([^`\n]+)`/g, (_match, code) => {
26
+ const idx = inlineCodes.length;
27
+ inlineCodes.push(`<code>${escapeHtml(code)}</code>`);
28
+ return `\x00INLINE${idx}\x00`;
29
+ });
30
+ // Escape HTML in remaining text
31
+ result = escapeHtml(result);
32
+ // Convert markdown formatting
33
+ // Bold: **text** or __text__
34
+ result = result.replace(/\*\*(.+?)\*\*/g, '<b>$1</b>');
35
+ result = result.replace(/__(.+?)__/g, '<b>$1</b>');
36
+ // Italic: *text* or _text_ (but not inside words for underscore)
37
+ result = result.replace(/(?<!\w)\*([^*\n]+?)\*(?!\w)/g, '<i>$1</i>');
38
+ result = result.replace(/(?<!\w)_([^_\n]+?)_(?!\w)/g, '<i>$1</i>');
39
+ // Strikethrough: ~~text~~
40
+ result = result.replace(/~~(.+?)~~/g, '<s>$1</s>');
41
+ // Links: [text](url)
42
+ result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
43
+ // Restore code blocks and inline code
44
+ result = result.replace(/\x00CODEBLOCK(\d+)\x00/g, (_match, idx) => codeBlocks[Number(idx)]);
45
+ result = result.replace(/\x00INLINE(\d+)\x00/g, (_match, idx) => inlineCodes[Number(idx)]);
46
+ return result;
47
+ }
48
+ /**
49
+ * Make text safe for Telegram HTML parse mode during streaming.
50
+ * Closes unclosed HTML tags from partial markdown conversion.
51
+ */
52
+ export function makeHtmlSafe(text) {
53
+ return markdownToHtml(text);
54
+ }
55
+ /** @deprecated Use makeHtmlSafe instead */
56
+ export function makeMarkdownSafe(text) {
57
+ return makeHtmlSafe(text);
58
+ }
59
+ // ── Stream Accumulator ──
60
+ export class StreamAccumulator {
61
+ chatId;
62
+ sender;
63
+ editIntervalMs;
64
+ splitThreshold;
65
+ // State
66
+ tgMessageId = null;
67
+ buffer = '';
68
+ thinkingBuffer = '';
69
+ imageBase64Buffer = '';
70
+ currentBlockType = null;
71
+ lastEditTime = 0;
72
+ editTimer = null;
73
+ thinkingIndicatorShown = false;
74
+ toolIndicators = [];
75
+ messageIds = []; // all message IDs sent during this turn
76
+ finished = false;
77
+ sendQueue = Promise.resolve();
78
+ turnUsage = null;
79
+ constructor(options) {
80
+ this.chatId = options.chatId;
81
+ this.sender = options.sender;
82
+ this.editIntervalMs = options.editIntervalMs ?? 1000;
83
+ this.splitThreshold = options.splitThreshold ?? 4000;
84
+ }
85
+ get allMessageIds() { return [...this.messageIds]; }
86
+ /** Set usage stats for the current turn (called from bridge on result event) */
87
+ setTurnUsage(usage) {
88
+ this.turnUsage = usage;
89
+ }
90
+ // ── Process stream events ──
91
+ async handleEvent(event) {
92
+ switch (event.type) {
93
+ case 'message_start':
94
+ // New assistant turn — reset buffer but keep tgMessageId to edit same message
95
+ this.softReset();
96
+ break;
97
+ case 'content_block_start':
98
+ await this.onContentBlockStart(event);
99
+ break;
100
+ case 'content_block_delta':
101
+ await this.onContentBlockDelta(event);
102
+ break;
103
+ case 'content_block_stop':
104
+ if (this.currentBlockType === 'thinking' && this.thinkingBuffer) {
105
+ // Thinking block complete — store for later rendering with text
106
+ // Will be prepended as expandable blockquote when text starts or on finalize
107
+ }
108
+ else if (this.currentBlockType === 'image' && this.imageBase64Buffer) {
109
+ await this.sendImage();
110
+ }
111
+ this.currentBlockType = null;
112
+ break;
113
+ case 'message_stop':
114
+ await this.finalize();
115
+ break;
116
+ }
117
+ }
118
+ async onContentBlockStart(event) {
119
+ const blockType = event.content_block.type;
120
+ if (blockType === 'thinking') {
121
+ this.currentBlockType = 'thinking';
122
+ if (!this.thinkingIndicatorShown && !this.buffer) {
123
+ await this.sendOrEdit('<i>💭 Thinking...</i>', true);
124
+ this.thinkingIndicatorShown = true;
125
+ }
126
+ }
127
+ else if (blockType === 'text') {
128
+ this.currentBlockType = 'text';
129
+ // Clear tool indicators when real text starts
130
+ this.toolIndicators = [];
131
+ }
132
+ else if (blockType === 'tool_use') {
133
+ this.currentBlockType = 'tool_use';
134
+ const name = event.content_block.name;
135
+ this.toolIndicators.push(name);
136
+ await this.showToolIndicator(name);
137
+ }
138
+ else if (blockType === 'image') {
139
+ this.currentBlockType = 'image';
140
+ this.imageBase64Buffer = '';
141
+ }
142
+ }
143
+ async onContentBlockDelta(event) {
144
+ if (this.currentBlockType === 'text' && 'delta' in event) {
145
+ const delta = event.delta;
146
+ if (delta?.type === 'text_delta') {
147
+ this.buffer += delta.text;
148
+ await this.throttledEdit();
149
+ }
150
+ }
151
+ else if (this.currentBlockType === 'thinking' && 'delta' in event) {
152
+ const delta = event.delta;
153
+ if (delta?.type === 'thinking_delta' && delta.thinking) {
154
+ this.thinkingBuffer += delta.thinking;
155
+ }
156
+ }
157
+ else if (this.currentBlockType === 'image' && 'delta' in event) {
158
+ const delta = event.delta;
159
+ if (delta?.type === 'image_delta' && delta.data) {
160
+ this.imageBase64Buffer += delta.data;
161
+ }
162
+ }
163
+ // Ignore input_json_delta content
164
+ }
165
+ // ── TG message management ──
166
+ /** Send or edit a message. If rawHtml is true, text is already HTML-safe. */
167
+ async sendOrEdit(text, rawHtml = false) {
168
+ this.sendQueue = this.sendQueue.then(() => this._doSendOrEdit(text, rawHtml));
169
+ return this.sendQueue;
170
+ }
171
+ async _doSendOrEdit(text, rawHtml = false) {
172
+ const safeText = (rawHtml ? text : makeHtmlSafe(text)) || '...';
173
+ try {
174
+ if (!this.tgMessageId) {
175
+ this.tgMessageId = await this.sender.sendMessage(this.chatId, safeText, 'HTML');
176
+ this.messageIds.push(this.tgMessageId);
177
+ }
178
+ else {
179
+ await this.sender.editMessage(this.chatId, this.tgMessageId, safeText, 'HTML');
180
+ }
181
+ this.lastEditTime = Date.now();
182
+ }
183
+ catch (err) {
184
+ // Handle TG rate limit (429)
185
+ if (err && typeof err === 'object' && 'error_code' in err && err.error_code === 429) {
186
+ const retryAfter = err.parameters?.retry_after ?? 5;
187
+ this.editIntervalMs = Math.min(this.editIntervalMs * 2, 5000);
188
+ await sleep(retryAfter * 1000);
189
+ return this._doSendOrEdit(text);
190
+ }
191
+ // Ignore "message is not modified" errors
192
+ if (err instanceof Error && err.message.includes('message is not modified'))
193
+ return;
194
+ throw err;
195
+ }
196
+ }
197
+ async sendImage() {
198
+ if (!this.sender.sendPhoto || !this.imageBase64Buffer)
199
+ return;
200
+ try {
201
+ const imageBuffer = Buffer.from(this.imageBase64Buffer, 'base64');
202
+ const msgId = await this.sender.sendPhoto(this.chatId, imageBuffer);
203
+ this.messageIds.push(msgId);
204
+ }
205
+ catch (err) {
206
+ // Fall back to text indicator on failure
207
+ this.buffer += '\n[Image could not be sent]';
208
+ }
209
+ this.imageBase64Buffer = '';
210
+ }
211
+ async showToolIndicator(toolName) {
212
+ const bufferHtml = this.buffer ? makeHtmlSafe(this.buffer) : '';
213
+ const indicator = bufferHtml
214
+ ? `${bufferHtml}\n\n<i>Using ${escapeHtml(toolName)}...</i>`
215
+ : `<i>Using ${escapeHtml(toolName)}...</i>`;
216
+ await this.sendOrEdit(indicator, true);
217
+ }
218
+ async throttledEdit() {
219
+ const now = Date.now();
220
+ const elapsed = now - this.lastEditTime;
221
+ if (elapsed >= this.editIntervalMs) {
222
+ // Enough time passed — edit now
223
+ await this.doEdit();
224
+ }
225
+ else if (!this.editTimer) {
226
+ // Schedule an edit
227
+ const delay = this.editIntervalMs - elapsed;
228
+ this.editTimer = setTimeout(async () => {
229
+ this.editTimer = null;
230
+ if (!this.finished) {
231
+ await this.doEdit();
232
+ }
233
+ }, delay);
234
+ }
235
+ }
236
+ /** Build the full message text including thinking blockquote prefix and usage footer */
237
+ buildFullText(includeSuffix = false) {
238
+ let text = '';
239
+ if (this.thinkingBuffer) {
240
+ // Truncate thinking to 1024 chars max for the expandable blockquote
241
+ const thinkingPreview = this.thinkingBuffer.length > 1024
242
+ ? this.thinkingBuffer.slice(0, 1024) + '…'
243
+ : this.thinkingBuffer;
244
+ text += `<blockquote expandable>💭 Thinking\n${escapeHtml(thinkingPreview)}</blockquote>\n`;
245
+ }
246
+ text += this.buffer;
247
+ if (includeSuffix && this.turnUsage) {
248
+ text += '\n' + formatUsageFooter(this.turnUsage);
249
+ }
250
+ return text;
251
+ }
252
+ async doEdit() {
253
+ if (!this.buffer)
254
+ return;
255
+ const fullText = this.buildFullText();
256
+ // Check if we need to split
257
+ if (fullText.length > this.splitThreshold) {
258
+ await this.splitMessage();
259
+ return;
260
+ }
261
+ await this.sendOrEdit(fullText);
262
+ }
263
+ async splitMessage() {
264
+ // Find a good split point near the threshold
265
+ const splitAt = findSplitPoint(this.buffer, this.splitThreshold);
266
+ const firstPart = this.buffer.slice(0, splitAt);
267
+ const remainder = this.buffer.slice(splitAt);
268
+ // Finalize current message with first part
269
+ await this.sendOrEdit(firstPart);
270
+ // Start a new message for remainder
271
+ this.tgMessageId = null;
272
+ this.buffer = remainder;
273
+ if (this.buffer) {
274
+ await this.sendOrEdit(this.buffer);
275
+ }
276
+ }
277
+ async finalize() {
278
+ this.finished = true;
279
+ // Clear any pending edit timer
280
+ if (this.editTimer) {
281
+ clearTimeout(this.editTimer);
282
+ this.editTimer = null;
283
+ }
284
+ if (this.buffer) {
285
+ // Final edit with complete text including thinking blockquote and usage footer
286
+ const fullText = this.buildFullText(true);
287
+ await this.sendOrEdit(fullText);
288
+ }
289
+ else if (this.thinkingBuffer && this.thinkingIndicatorShown) {
290
+ // Only thinking happened, no text — show thinking as expandable blockquote
291
+ const thinkingPreview = this.thinkingBuffer.length > 1024
292
+ ? this.thinkingBuffer.slice(0, 1024) + '…'
293
+ : this.thinkingBuffer;
294
+ await this.sendOrEdit(`<blockquote expandable>💭 Thinking\n${escapeHtml(thinkingPreview)}</blockquote>`, true);
295
+ }
296
+ }
297
+ /** Soft reset: clear buffer/state but keep tgMessageId so next turn edits the same message */
298
+ softReset() {
299
+ this.buffer = '';
300
+ this.thinkingBuffer = '';
301
+ this.imageBase64Buffer = '';
302
+ this.currentBlockType = null;
303
+ this.lastEditTime = 0;
304
+ this.thinkingIndicatorShown = false;
305
+ this.toolIndicators = [];
306
+ this.finished = false;
307
+ this.turnUsage = null;
308
+ if (this.editTimer) {
309
+ clearTimeout(this.editTimer);
310
+ this.editTimer = null;
311
+ }
312
+ }
313
+ /** Full reset: also clears tgMessageId (next send creates a new message) */
314
+ reset() {
315
+ this.softReset();
316
+ this.tgMessageId = null;
317
+ this.messageIds = [];
318
+ this.sendQueue = Promise.resolve();
319
+ }
320
+ }
321
+ // ── Helpers ──
322
+ function findSplitPoint(text, threshold) {
323
+ // Try to split at paragraph break
324
+ const paragraphBreak = text.lastIndexOf('\n\n', threshold);
325
+ if (paragraphBreak > threshold * 0.5)
326
+ return paragraphBreak;
327
+ // Try to split at line break
328
+ const lineBreak = text.lastIndexOf('\n', threshold);
329
+ if (lineBreak > threshold * 0.5)
330
+ return lineBreak;
331
+ // Try to split at sentence end
332
+ const sentenceEnd = text.lastIndexOf('. ', threshold);
333
+ if (sentenceEnd > threshold * 0.5)
334
+ return sentenceEnd + 2;
335
+ // Fall back to threshold
336
+ return threshold;
337
+ }
338
+ function sleep(ms) {
339
+ return new Promise(resolve => setTimeout(resolve, ms));
340
+ }
341
+ /** Format token count as human-readable: 1234 → "1.2k", 500 → "500" */
342
+ function formatTokens(n) {
343
+ if (n >= 1000)
344
+ return (n / 1000).toFixed(1) + 'k';
345
+ return String(n);
346
+ }
347
+ /** Format usage stats as an HTML italic footer line */
348
+ export function formatUsageFooter(usage) {
349
+ const parts = [
350
+ `↩️ ${formatTokens(usage.inputTokens)} in`,
351
+ `${formatTokens(usage.outputTokens)} out`,
352
+ ];
353
+ if (usage.costUsd != null) {
354
+ parts.push(`$${usage.costUsd.toFixed(4)}`);
355
+ }
356
+ return `<i>${parts.join(' · ')}</i>`;
357
+ }
358
+ // ── Sub-agent detection patterns ──
359
+ const SUB_AGENT_TOOL_PATTERNS = [/agent/i, /dispatch/i, /^task$/i];
360
+ export function isSubAgentTool(toolName) {
361
+ return SUB_AGENT_TOOL_PATTERNS.some(p => p.test(toolName));
362
+ }
363
+ export class SubAgentTracker {
364
+ chatId;
365
+ sender;
366
+ getMainMessageId;
367
+ agents = new Map(); // toolUseId → info
368
+ blockToAgent = new Map(); // blockIndex → toolUseId
369
+ sendQueue = Promise.resolve();
370
+ constructor(options) {
371
+ this.chatId = options.chatId;
372
+ this.sender = options.sender;
373
+ this.getMainMessageId = options.getMainMessageId;
374
+ }
375
+ get activeAgents() {
376
+ return [...this.agents.values()];
377
+ }
378
+ async handleEvent(event) {
379
+ switch (event.type) {
380
+ case 'content_block_start':
381
+ await this.onBlockStart(event);
382
+ break;
383
+ case 'content_block_delta': {
384
+ const delta = event;
385
+ if (delta.delta?.type === 'input_json_delta') {
386
+ await this.onInputDelta(delta);
387
+ }
388
+ break;
389
+ }
390
+ case 'content_block_stop':
391
+ await this.onBlockStop(event);
392
+ break;
393
+ case 'message_start':
394
+ // New turn — reset tracker
395
+ this.reset();
396
+ break;
397
+ }
398
+ }
399
+ async onBlockStart(event) {
400
+ if (event.content_block.type !== 'tool_use')
401
+ return;
402
+ const block = event.content_block;
403
+ if (!isSubAgentTool(block.name))
404
+ return;
405
+ const info = {
406
+ toolUseId: block.id,
407
+ toolName: block.name,
408
+ blockIndex: event.index,
409
+ tgMessageId: null,
410
+ status: 'running',
411
+ inputPreview: '',
412
+ };
413
+ this.agents.set(block.id, info);
414
+ this.blockToAgent.set(event.index, block.id);
415
+ // Send reply message
416
+ const mainMsgId = this.getMainMessageId();
417
+ if (mainMsgId) {
418
+ this.sendQueue = this.sendQueue.then(async () => {
419
+ try {
420
+ const msgId = await this.sender.replyToMessage(this.chatId, `🔄 Sub-agent spawned: <code>${escapeHtml(block.name)}</code>`, mainMsgId, 'HTML');
421
+ info.tgMessageId = msgId;
422
+ }
423
+ catch (err) {
424
+ // Silently ignore — main stream continues regardless
425
+ }
426
+ });
427
+ await this.sendQueue;
428
+ }
429
+ }
430
+ async onInputDelta(event) {
431
+ const toolUseId = this.blockToAgent.get(event.index);
432
+ if (!toolUseId)
433
+ return;
434
+ const info = this.agents.get(toolUseId);
435
+ if (!info || !info.tgMessageId)
436
+ return;
437
+ info.inputPreview += event.delta.partial_json;
438
+ // Throttle: only update when we have a reasonable chunk (every 200 chars)
439
+ if (info.inputPreview.length % 200 > 50)
440
+ return;
441
+ const preview = info.inputPreview.length > 300
442
+ ? info.inputPreview.slice(0, 300) + '…'
443
+ : info.inputPreview;
444
+ this.sendQueue = this.sendQueue.then(async () => {
445
+ try {
446
+ await this.sender.editMessage(this.chatId, info.tgMessageId, `🔄 Sub-agent: <code>${escapeHtml(info.toolName)}</code>\n\n<pre>${escapeHtml(preview)}</pre>`, 'HTML');
447
+ }
448
+ catch {
449
+ // Ignore edit failures (rate limits, not modified, etc.)
450
+ }
451
+ });
452
+ await this.sendQueue;
453
+ }
454
+ async onBlockStop(event) {
455
+ const toolUseId = this.blockToAgent.get(event.index);
456
+ if (!toolUseId)
457
+ return;
458
+ const info = this.agents.get(toolUseId);
459
+ if (!info || !info.tgMessageId)
460
+ return;
461
+ info.status = 'completed';
462
+ // Extract a summary from the input preview (first ~100 chars)
463
+ let summary = '';
464
+ try {
465
+ const parsed = JSON.parse(info.inputPreview);
466
+ // Common patterns: { prompt: "..." }, { task: "..." }, { command: "..." }
467
+ summary = parsed.prompt || parsed.task || parsed.command || parsed.description || '';
468
+ if (typeof summary === 'string' && summary.length > 100) {
469
+ summary = summary.slice(0, 100) + '…';
470
+ }
471
+ }
472
+ catch {
473
+ summary = info.inputPreview.slice(0, 100);
474
+ if (info.inputPreview.length > 100)
475
+ summary += '…';
476
+ }
477
+ const text = summary
478
+ ? `✅ Sub-agent completed: <code>${escapeHtml(info.toolName)}</code>\n<i>${escapeHtml(summary)}</i>`
479
+ : `✅ Sub-agent completed: <code>${escapeHtml(info.toolName)}</code>`;
480
+ this.sendQueue = this.sendQueue.then(async () => {
481
+ try {
482
+ await this.sender.editMessage(this.chatId, info.tgMessageId, text, 'HTML');
483
+ }
484
+ catch {
485
+ // Ignore edit failures
486
+ }
487
+ });
488
+ await this.sendQueue;
489
+ }
490
+ reset() {
491
+ this.agents.clear();
492
+ this.blockToAgent.clear();
493
+ this.sendQueue = Promise.resolve();
494
+ }
495
+ }
496
+ // ── Utility: split a completed text into TG-sized chunks ──
497
+ export function splitText(text, maxLength = 4000) {
498
+ if (text.length <= maxLength)
499
+ return [text];
500
+ const chunks = [];
501
+ let remaining = text;
502
+ while (remaining.length > maxLength) {
503
+ const splitAt = findSplitPoint(remaining, maxLength);
504
+ chunks.push(remaining.slice(0, splitAt));
505
+ remaining = remaining.slice(splitAt).trimStart();
506
+ }
507
+ if (remaining)
508
+ chunks.push(remaining);
509
+ return chunks;
510
+ }
511
+ //# sourceMappingURL=streaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming.js","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ import { Bot, InlineKeyboard } from 'grammy';
2
+ import type pino from 'pino';
3
+ import type { AgentConfig } from './config.js';
4
+ export interface TelegramMessage {
5
+ type: 'text' | 'photo' | 'document' | 'voice' | 'video';
6
+ chatId: number;
7
+ userId: string;
8
+ text: string;
9
+ imageBase64?: string;
10
+ imageMediaType?: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
11
+ filePath?: string;
12
+ fileName?: string;
13
+ replyToText?: string;
14
+ }
15
+ export interface SlashCommand {
16
+ command: string;
17
+ args: string;
18
+ chatId: number;
19
+ userId: string;
20
+ }
21
+ export interface CallbackQuery {
22
+ action: string;
23
+ data: string;
24
+ chatId: number;
25
+ userId: string;
26
+ callbackQueryId: string;
27
+ }
28
+ export type MessageHandler = (msg: TelegramMessage) => void;
29
+ export type CommandHandler = (cmd: SlashCommand) => void;
30
+ export type CallbackHandler = (query: CallbackQuery) => void;
31
+ export declare const COMMANDS: {
32
+ command: string;
33
+ description: string;
34
+ }[];
35
+ export declare class TelegramBot {
36
+ readonly agentId: string;
37
+ readonly bot: Bot;
38
+ private config;
39
+ private logger;
40
+ private mediaDir;
41
+ private onMessage;
42
+ private onCommand;
43
+ private onCallback;
44
+ private replyMaps;
45
+ private running;
46
+ constructor(agentId: string, config: AgentConfig, mediaDir: string, onMessage: MessageHandler, onCommand: CommandHandler, logger: pino.Logger, onCallback?: CallbackHandler);
47
+ private isAllowed;
48
+ private getReplyMap;
49
+ trackBotMessage(chatId: number, messageId: number, text: string): void;
50
+ private setupHandlers;
51
+ private handleCallbackQuery;
52
+ private handleCommand;
53
+ private handleText;
54
+ private handlePhoto;
55
+ private handleDocument;
56
+ private handleVoice;
57
+ private handleVideo;
58
+ start(): Promise<void>;
59
+ stop(): Promise<void>;
60
+ sendText(chatId: number | string, text: string, parseMode?: string): Promise<number>;
61
+ sendTextWithKeyboard(chatId: number | string, text: string, keyboard: InlineKeyboard, parseMode?: string): Promise<number>;
62
+ answerCallbackQuery(callbackQueryId: string, text?: string): Promise<void>;
63
+ editText(chatId: number | string, messageId: number, text: string, parseMode?: string): Promise<void>;
64
+ sendFile(chatId: number | string, filePath: string, caption?: string): Promise<void>;
65
+ sendImage(chatId: number | string, filePath: string, caption?: string): Promise<void>;
66
+ sendPhotoBuffer(chatId: number | string, buffer: Buffer, caption?: string): Promise<number>;
67
+ sendVoice(chatId: number | string, filePath: string, caption?: string): Promise<void>;
68
+ replyToMessage(chatId: number | string, text: string, replyToMessageId: number, parseMode?: string): Promise<number>;
69
+ sendTyping(chatId: number | string): Promise<void>;
70
+ }