@llblab/pi-telegram 0.16.6 → 0.17.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/AGENTS.md +15 -9
- package/BACKLOG.md +8 -5
- package/CHANGELOG.md +12 -0
- package/README.md +7 -5
- package/docs/README.md +2 -1
- package/docs/architecture.md +16 -12
- package/docs/outbound.md +2 -2
- package/docs/public-api.md +3 -0
- package/docs/sections.md +4 -2
- package/docs/telegram-bot-api-rich-messages.md +890 -0
- package/docs/ui-style.md +1 -1
- package/index.ts +11 -2
- package/lib/commands.ts +2 -2
- package/lib/media.ts +92 -1
- package/lib/menu-model.ts +3 -3
- package/lib/menu-settings.ts +2 -2
- package/lib/menu.ts +4 -4
- package/lib/preview.ts +160 -195
- package/lib/prompts.ts +4 -4
- package/lib/rendering.ts +3 -349
- package/lib/replies.ts +227 -31
- package/lib/routing.ts +2 -2
- package/lib/sections.ts +10 -5
- package/lib/telegram-api.ts +79 -9
- package/package.json +1 -1
package/lib/routing.ts
CHANGED
|
@@ -93,13 +93,13 @@ export interface TelegramInboundRouteRuntimeDeps<
|
|
|
93
93
|
chatId: number,
|
|
94
94
|
messageId: number,
|
|
95
95
|
text: string,
|
|
96
|
-
mode: "html" | "plain",
|
|
96
|
+
mode: "markdown" | "html" | "plain",
|
|
97
97
|
replyMarkup: Menu.TelegramReplyMarkup,
|
|
98
98
|
) => Promise<void>;
|
|
99
99
|
sendInteractiveMessage?: (
|
|
100
100
|
chatId: number,
|
|
101
101
|
text: string,
|
|
102
|
-
mode: "html" | "plain",
|
|
102
|
+
mode: "markdown" | "html" | "plain",
|
|
103
103
|
replyMarkup: Menu.TelegramReplyMarkup,
|
|
104
104
|
) => Promise<number | undefined>;
|
|
105
105
|
deleteMessage?: (chatId: number, messageId: number) => Promise<void>;
|
package/lib/sections.ts
CHANGED
|
@@ -24,7 +24,12 @@ export type TelegramSectionCallbackResult = "handled" | "pass";
|
|
|
24
24
|
|
|
25
25
|
export interface TelegramSectionView {
|
|
26
26
|
text: string;
|
|
27
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Source format for companion section content.
|
|
29
|
+
* Defaults to "html" for explicit Telegram UI markup; use "markdown"
|
|
30
|
+
* when a section naturally owns Markdown content, or "plain" for text.
|
|
31
|
+
*/
|
|
32
|
+
parseMode?: "markdown" | "html" | "plain";
|
|
28
33
|
replyMarkup?: TelegramInlineKeyboardMarkup;
|
|
29
34
|
}
|
|
30
35
|
|
|
@@ -138,13 +143,13 @@ export interface TelegramSectionRuntimeDeps {
|
|
|
138
143
|
chatId: number,
|
|
139
144
|
messageId: number,
|
|
140
145
|
text: string,
|
|
141
|
-
mode: "html" | "plain",
|
|
146
|
+
mode: "markdown" | "html" | "plain",
|
|
142
147
|
replyMarkup: TelegramInlineKeyboardMarkup,
|
|
143
148
|
) => Promise<void>;
|
|
144
149
|
sendInteractiveMessage: (
|
|
145
150
|
chatId: number,
|
|
146
151
|
text: string,
|
|
147
|
-
mode: "html" | "plain",
|
|
152
|
+
mode: "markdown" | "html" | "plain",
|
|
148
153
|
replyMarkup: TelegramInlineKeyboardMarkup,
|
|
149
154
|
) => Promise<number | undefined>;
|
|
150
155
|
enqueuePrompt: (prompt: string) => Promise<void>;
|
|
@@ -505,13 +510,13 @@ export interface TelegramSectionCallbackHandlerDeps {
|
|
|
505
510
|
chatId: number,
|
|
506
511
|
messageId: number,
|
|
507
512
|
text: string,
|
|
508
|
-
mode: "html" | "plain",
|
|
513
|
+
mode: "markdown" | "html" | "plain",
|
|
509
514
|
replyMarkup: TelegramInlineKeyboardMarkup,
|
|
510
515
|
) => Promise<void>;
|
|
511
516
|
sendInteractiveMessage: (
|
|
512
517
|
chatId: number,
|
|
513
518
|
text: string,
|
|
514
|
-
mode: "html" | "plain",
|
|
519
|
+
mode: "markdown" | "html" | "plain",
|
|
515
520
|
replyMarkup: TelegramInlineKeyboardMarkup,
|
|
516
521
|
) => Promise<number | undefined>;
|
|
517
522
|
enqueuePrompt: (prompt: string) => Promise<void>;
|
package/lib/telegram-api.ts
CHANGED
|
@@ -101,12 +101,18 @@ export interface TelegramSticker {
|
|
|
101
101
|
emoji?: string;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
export interface TelegramRichMessage {
|
|
105
|
+
blocks?: unknown[];
|
|
106
|
+
is_rtl?: boolean;
|
|
107
|
+
}
|
|
108
|
+
|
|
104
109
|
export interface TelegramMessage {
|
|
105
110
|
message_id: number;
|
|
106
111
|
chat: TelegramChat;
|
|
107
112
|
from?: TelegramUser;
|
|
108
113
|
text?: string;
|
|
109
114
|
caption?: string;
|
|
115
|
+
rich_message?: TelegramRichMessage;
|
|
110
116
|
media_group_id?: string;
|
|
111
117
|
photo?: TelegramPhotoSize[];
|
|
112
118
|
document?: TelegramDocument;
|
|
@@ -160,6 +166,7 @@ export interface TelegramGuestMessage {
|
|
|
160
166
|
date: number;
|
|
161
167
|
text?: string;
|
|
162
168
|
caption?: string;
|
|
169
|
+
rich_message?: TelegramRichMessage;
|
|
163
170
|
guest_query_id: string;
|
|
164
171
|
guest_bot_caller_user?: TelegramUser;
|
|
165
172
|
guest_bot_caller_chat?: TelegramChat;
|
|
@@ -193,11 +200,38 @@ export type TelegramSendMessageBody = Record<string, unknown> & {
|
|
|
193
200
|
reply_parameters?: TelegramReplyParameters;
|
|
194
201
|
};
|
|
195
202
|
|
|
203
|
+
export type TelegramInputRichMessage =
|
|
204
|
+
| {
|
|
205
|
+
markdown: string;
|
|
206
|
+
html?: never;
|
|
207
|
+
is_rtl?: boolean;
|
|
208
|
+
skip_entity_detection?: boolean;
|
|
209
|
+
}
|
|
210
|
+
| {
|
|
211
|
+
html: string;
|
|
212
|
+
markdown?: never;
|
|
213
|
+
is_rtl?: boolean;
|
|
214
|
+
skip_entity_detection?: boolean;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export type TelegramSendRichMessageBody = Record<string, unknown> & {
|
|
218
|
+
chat_id: number;
|
|
219
|
+
rich_message: TelegramInputRichMessage;
|
|
220
|
+
reply_markup?: unknown;
|
|
221
|
+
reply_parameters?: TelegramReplyParameters;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export type TelegramInputRichMessageContent = {
|
|
225
|
+
rich_message: TelegramInputRichMessage;
|
|
226
|
+
};
|
|
227
|
+
|
|
196
228
|
export type TelegramEditMessageTextBody = Record<string, unknown> & {
|
|
197
229
|
chat_id: number;
|
|
198
230
|
message_id: number;
|
|
199
|
-
text
|
|
231
|
+
text?: string;
|
|
232
|
+
rich_message?: TelegramInputRichMessage;
|
|
200
233
|
parse_mode?: "HTML";
|
|
234
|
+
reply_markup?: unknown;
|
|
201
235
|
};
|
|
202
236
|
|
|
203
237
|
export type TelegramSendMessageDraftBody = Record<string, unknown> & {
|
|
@@ -209,6 +243,13 @@ export type TelegramSendMessageDraftBody = Record<string, unknown> & {
|
|
|
209
243
|
message_thread_id?: number;
|
|
210
244
|
};
|
|
211
245
|
|
|
246
|
+
export type TelegramSendRichMessageDraftBody = Record<string, unknown> & {
|
|
247
|
+
chat_id: number;
|
|
248
|
+
draft_id: number;
|
|
249
|
+
rich_message: TelegramInputRichMessage;
|
|
250
|
+
message_thread_id?: number;
|
|
251
|
+
};
|
|
252
|
+
|
|
212
253
|
interface TelegramApiResponse<T> {
|
|
213
254
|
ok: boolean;
|
|
214
255
|
result?: T;
|
|
@@ -269,7 +310,7 @@ export interface TelegramApiClient {
|
|
|
269
310
|
answerGuestQuery?: (
|
|
270
311
|
guestQueryId: string,
|
|
271
312
|
text?: string,
|
|
272
|
-
options?: { parseMode?: string },
|
|
313
|
+
options?: { parseMode?: string; richMessage?: TelegramInputRichMessage },
|
|
273
314
|
) => Promise<void>;
|
|
274
315
|
}
|
|
275
316
|
|
|
@@ -322,6 +363,12 @@ export interface TelegramBridgeApiRuntime {
|
|
|
322
363
|
},
|
|
323
364
|
) => Promise<boolean>;
|
|
324
365
|
sendMessage: (body: TelegramSendMessageBody) => Promise<TelegramSentMessage>;
|
|
366
|
+
sendRichMessage: (
|
|
367
|
+
body: TelegramSendRichMessageBody,
|
|
368
|
+
) => Promise<TelegramSentMessage>;
|
|
369
|
+
sendRichMessageDraft: (
|
|
370
|
+
body: TelegramSendRichMessageDraftBody,
|
|
371
|
+
) => Promise<boolean>;
|
|
325
372
|
editMessageText: (
|
|
326
373
|
body: TelegramEditMessageTextBody,
|
|
327
374
|
) => Promise<"edited" | "unchanged">;
|
|
@@ -332,7 +379,7 @@ export interface TelegramBridgeApiRuntime {
|
|
|
332
379
|
answerGuestQuery: (
|
|
333
380
|
guestQueryId: string,
|
|
334
381
|
text?: string,
|
|
335
|
-
options?: { parseMode?: string },
|
|
382
|
+
options?: { parseMode?: string; richMessage?: TelegramInputRichMessage },
|
|
336
383
|
) => Promise<void>;
|
|
337
384
|
deleteMessage: (chatId: number, messageId: number) => Promise<void>;
|
|
338
385
|
prepareTempDir: () => Promise<number>;
|
|
@@ -711,6 +758,25 @@ export function createTelegramChatActionSender<TAction extends string>(
|
|
|
711
758
|
return (chatId) => sendChatAction(chatId, action);
|
|
712
759
|
}
|
|
713
760
|
|
|
761
|
+
export function createTelegramNativeMarkdownDraftSender(deps: {
|
|
762
|
+
sendMessageDraft: TelegramBridgeApiRuntime["sendMessageDraft"];
|
|
763
|
+
sendRichMessageDraft: TelegramBridgeApiRuntime["sendRichMessageDraft"];
|
|
764
|
+
}): TelegramBridgeApiRuntime["sendMessageDraft"] {
|
|
765
|
+
return (chatId, draftId, text, options) => {
|
|
766
|
+
if (text === undefined) {
|
|
767
|
+
return deps.sendMessageDraft(chatId, draftId, text, options);
|
|
768
|
+
}
|
|
769
|
+
return deps.sendRichMessageDraft({
|
|
770
|
+
chat_id: chatId,
|
|
771
|
+
draft_id: draftId,
|
|
772
|
+
rich_message: { markdown: text, skip_entity_detection: true },
|
|
773
|
+
...(options?.message_thread_id !== undefined
|
|
774
|
+
? { message_thread_id: options.message_thread_id }
|
|
775
|
+
: {}),
|
|
776
|
+
});
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
|
|
714
780
|
export function createDefaultTelegramBridgeApiRuntime(deps: {
|
|
715
781
|
getBotToken: () => string | undefined;
|
|
716
782
|
recordRuntimeEvent: TelegramBridgeApiRuntimeDeps["recordRuntimeEvent"];
|
|
@@ -837,6 +903,10 @@ export function createTelegramBridgeApiRuntime(
|
|
|
837
903
|
},
|
|
838
904
|
sendMessage: (body) =>
|
|
839
905
|
callRecorded<TelegramSentMessage>("sendMessage", body),
|
|
906
|
+
sendRichMessage: (body) =>
|
|
907
|
+
callRecorded<TelegramSentMessage>("sendRichMessage", body),
|
|
908
|
+
sendRichMessageDraft: (body) =>
|
|
909
|
+
callRecorded<boolean>("sendRichMessageDraft", body),
|
|
840
910
|
editMessageText: async (body) => {
|
|
841
911
|
try {
|
|
842
912
|
await deps.client.call("editMessageText", body);
|
|
@@ -859,14 +929,14 @@ export function createTelegramBridgeApiRuntime(
|
|
|
859
929
|
answerGuestQuery: (
|
|
860
930
|
guestQueryId: string,
|
|
861
931
|
text: string | undefined,
|
|
862
|
-
options: { parseMode?: string } | undefined,
|
|
932
|
+
options: { parseMode?: string; richMessage?: TelegramInputRichMessage } | undefined,
|
|
863
933
|
) => {
|
|
864
934
|
const body: Record<string, unknown> = { guest_query_id: guestQueryId };
|
|
865
|
-
if (text !== undefined) {
|
|
866
|
-
const inputContent: Record<string, unknown> =
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
if (options?.parseMode) {
|
|
935
|
+
if (text !== undefined || options?.richMessage) {
|
|
936
|
+
const inputContent: Record<string, unknown> = options?.richMessage
|
|
937
|
+
? { rich_message: options.richMessage }
|
|
938
|
+
: { message_text: text };
|
|
939
|
+
if (!options?.richMessage && options?.parseMode) {
|
|
870
940
|
inputContent.parse_mode = options.parseMode;
|
|
871
941
|
}
|
|
872
942
|
body.result = {
|