@llblab/pi-telegram 0.16.6 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +14 -8
- package/BACKLOG.md +8 -5
- package/CHANGELOG.md +8 -0
- package/README.md +7 -5
- package/docs/README.md +2 -1
- package/docs/architecture.md +13 -11
- 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/menu-model.ts +3 -3
- package/lib/menu-settings.ts +2 -2
- package/lib/menu.ts +4 -4
- package/lib/preview.ts +150 -195
- package/lib/prompts.ts +3 -3
- package/lib/rendering.ts +3 -349
- package/lib/replies.ts +186 -31
- package/lib/routing.ts +2 -2
- package/lib/sections.ts +10 -5
- package/lib/telegram-api.ts +72 -9
- package/package.json +1 -1
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
|
@@ -193,11 +193,38 @@ export type TelegramSendMessageBody = Record<string, unknown> & {
|
|
|
193
193
|
reply_parameters?: TelegramReplyParameters;
|
|
194
194
|
};
|
|
195
195
|
|
|
196
|
+
export type TelegramInputRichMessage =
|
|
197
|
+
| {
|
|
198
|
+
markdown: string;
|
|
199
|
+
html?: never;
|
|
200
|
+
is_rtl?: boolean;
|
|
201
|
+
skip_entity_detection?: boolean;
|
|
202
|
+
}
|
|
203
|
+
| {
|
|
204
|
+
html: string;
|
|
205
|
+
markdown?: never;
|
|
206
|
+
is_rtl?: boolean;
|
|
207
|
+
skip_entity_detection?: boolean;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
export type TelegramSendRichMessageBody = Record<string, unknown> & {
|
|
211
|
+
chat_id: number;
|
|
212
|
+
rich_message: TelegramInputRichMessage;
|
|
213
|
+
reply_markup?: unknown;
|
|
214
|
+
reply_parameters?: TelegramReplyParameters;
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
export type TelegramInputRichMessageContent = {
|
|
218
|
+
rich_message: TelegramInputRichMessage;
|
|
219
|
+
};
|
|
220
|
+
|
|
196
221
|
export type TelegramEditMessageTextBody = Record<string, unknown> & {
|
|
197
222
|
chat_id: number;
|
|
198
223
|
message_id: number;
|
|
199
|
-
text
|
|
224
|
+
text?: string;
|
|
225
|
+
rich_message?: TelegramInputRichMessage;
|
|
200
226
|
parse_mode?: "HTML";
|
|
227
|
+
reply_markup?: unknown;
|
|
201
228
|
};
|
|
202
229
|
|
|
203
230
|
export type TelegramSendMessageDraftBody = Record<string, unknown> & {
|
|
@@ -209,6 +236,13 @@ export type TelegramSendMessageDraftBody = Record<string, unknown> & {
|
|
|
209
236
|
message_thread_id?: number;
|
|
210
237
|
};
|
|
211
238
|
|
|
239
|
+
export type TelegramSendRichMessageDraftBody = Record<string, unknown> & {
|
|
240
|
+
chat_id: number;
|
|
241
|
+
draft_id: number;
|
|
242
|
+
rich_message: TelegramInputRichMessage;
|
|
243
|
+
message_thread_id?: number;
|
|
244
|
+
};
|
|
245
|
+
|
|
212
246
|
interface TelegramApiResponse<T> {
|
|
213
247
|
ok: boolean;
|
|
214
248
|
result?: T;
|
|
@@ -269,7 +303,7 @@ export interface TelegramApiClient {
|
|
|
269
303
|
answerGuestQuery?: (
|
|
270
304
|
guestQueryId: string,
|
|
271
305
|
text?: string,
|
|
272
|
-
options?: { parseMode?: string },
|
|
306
|
+
options?: { parseMode?: string; richMessage?: TelegramInputRichMessage },
|
|
273
307
|
) => Promise<void>;
|
|
274
308
|
}
|
|
275
309
|
|
|
@@ -322,6 +356,12 @@ export interface TelegramBridgeApiRuntime {
|
|
|
322
356
|
},
|
|
323
357
|
) => Promise<boolean>;
|
|
324
358
|
sendMessage: (body: TelegramSendMessageBody) => Promise<TelegramSentMessage>;
|
|
359
|
+
sendRichMessage: (
|
|
360
|
+
body: TelegramSendRichMessageBody,
|
|
361
|
+
) => Promise<TelegramSentMessage>;
|
|
362
|
+
sendRichMessageDraft: (
|
|
363
|
+
body: TelegramSendRichMessageDraftBody,
|
|
364
|
+
) => Promise<boolean>;
|
|
325
365
|
editMessageText: (
|
|
326
366
|
body: TelegramEditMessageTextBody,
|
|
327
367
|
) => Promise<"edited" | "unchanged">;
|
|
@@ -332,7 +372,7 @@ export interface TelegramBridgeApiRuntime {
|
|
|
332
372
|
answerGuestQuery: (
|
|
333
373
|
guestQueryId: string,
|
|
334
374
|
text?: string,
|
|
335
|
-
options?: { parseMode?: string },
|
|
375
|
+
options?: { parseMode?: string; richMessage?: TelegramInputRichMessage },
|
|
336
376
|
) => Promise<void>;
|
|
337
377
|
deleteMessage: (chatId: number, messageId: number) => Promise<void>;
|
|
338
378
|
prepareTempDir: () => Promise<number>;
|
|
@@ -711,6 +751,25 @@ export function createTelegramChatActionSender<TAction extends string>(
|
|
|
711
751
|
return (chatId) => sendChatAction(chatId, action);
|
|
712
752
|
}
|
|
713
753
|
|
|
754
|
+
export function createTelegramNativeMarkdownDraftSender(deps: {
|
|
755
|
+
sendMessageDraft: TelegramBridgeApiRuntime["sendMessageDraft"];
|
|
756
|
+
sendRichMessageDraft: TelegramBridgeApiRuntime["sendRichMessageDraft"];
|
|
757
|
+
}): TelegramBridgeApiRuntime["sendMessageDraft"] {
|
|
758
|
+
return (chatId, draftId, text, options) => {
|
|
759
|
+
if (text === undefined) {
|
|
760
|
+
return deps.sendMessageDraft(chatId, draftId, text, options);
|
|
761
|
+
}
|
|
762
|
+
return deps.sendRichMessageDraft({
|
|
763
|
+
chat_id: chatId,
|
|
764
|
+
draft_id: draftId,
|
|
765
|
+
rich_message: { markdown: text, skip_entity_detection: true },
|
|
766
|
+
...(options?.message_thread_id !== undefined
|
|
767
|
+
? { message_thread_id: options.message_thread_id }
|
|
768
|
+
: {}),
|
|
769
|
+
});
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
|
|
714
773
|
export function createDefaultTelegramBridgeApiRuntime(deps: {
|
|
715
774
|
getBotToken: () => string | undefined;
|
|
716
775
|
recordRuntimeEvent: TelegramBridgeApiRuntimeDeps["recordRuntimeEvent"];
|
|
@@ -837,6 +896,10 @@ export function createTelegramBridgeApiRuntime(
|
|
|
837
896
|
},
|
|
838
897
|
sendMessage: (body) =>
|
|
839
898
|
callRecorded<TelegramSentMessage>("sendMessage", body),
|
|
899
|
+
sendRichMessage: (body) =>
|
|
900
|
+
callRecorded<TelegramSentMessage>("sendRichMessage", body),
|
|
901
|
+
sendRichMessageDraft: (body) =>
|
|
902
|
+
callRecorded<boolean>("sendRichMessageDraft", body),
|
|
840
903
|
editMessageText: async (body) => {
|
|
841
904
|
try {
|
|
842
905
|
await deps.client.call("editMessageText", body);
|
|
@@ -859,14 +922,14 @@ export function createTelegramBridgeApiRuntime(
|
|
|
859
922
|
answerGuestQuery: (
|
|
860
923
|
guestQueryId: string,
|
|
861
924
|
text: string | undefined,
|
|
862
|
-
options: { parseMode?: string } | undefined,
|
|
925
|
+
options: { parseMode?: string; richMessage?: TelegramInputRichMessage } | undefined,
|
|
863
926
|
) => {
|
|
864
927
|
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) {
|
|
928
|
+
if (text !== undefined || options?.richMessage) {
|
|
929
|
+
const inputContent: Record<string, unknown> = options?.richMessage
|
|
930
|
+
? { rich_message: options.richMessage }
|
|
931
|
+
: { message_text: text };
|
|
932
|
+
if (!options?.richMessage && options?.parseMode) {
|
|
870
933
|
inputContent.parse_mode = options.parseMode;
|
|
871
934
|
}
|
|
872
935
|
body.result = {
|