refactor(telegram): optimize message handling and unify system context

- handler.py: Cleaned up. All functions and imports are now actively used. - _enqueue_user_message: Refactored to handle both messages and callback queries, eliminating duplicate building logic. - _20_telegram_context.py: Now the single source of truth for injecting agent_instructions and system_context_reply. - File Cleanup: Deleted unused fw.telegram.system_context.md and fw.telegram.cleared.md. - fix: Corrected bot invocation logic within group chats.

keyboardstaff committed Mar 22, 2026 at 10:05 UTC d6811c1ec4926fb9b8f645b3bddb93eda8fec56e
7 files changed +20 -22
plugins/_telegram_integration/extensions/python/job_loop/_10_telegram_bot.py
+2 -1
@@ -53,7 +53,8 @@ class TelegramBotManager(Extension):
53 inst = running[name]
54 current_mode = bot_cfg.get("mode", "polling")
55 running_mode = "webhook" if inst.webhook_active else "polling"
56 - if current_mode == running_mode:
56 + current_group_mode = bot_cfg.get("group_mode", "mention")
57 + if current_mode == running_mode and current_group_mode == inst.group_mode:
58 # Same mode and still alive → skip
59 if (inst.task and not inst.task.done()) or inst.webhook_active:
60 continue
plugins/_telegram_integration/extensions/python/system_prompt/_20_telegram_context.py
+12 -1
@@ -1,6 +1,6 @@
1 from helpers.extension import Extension
2 from agent import LoopData
3 -from plugins._telegram_integration.helpers.handler import CTX_TG_BOT
3 +from plugins._telegram_integration.helpers.handler import CTX_TG_BOT, CTX_TG_BOT_CFG
4
5
6 class TelegramContextPrompt(Extension):
@@ -18,3 +18,14 @@ class TelegramContextPrompt(Extension):
18 system_prompt.append(
19 self.agent.read_prompt("fw.telegram.system_context_reply.md")
20 )
21 +
22 + # Inject per-bot agent instructions (once in system prompt)
23 + bot_cfg = self.agent.context.data.get(CTX_TG_BOT_CFG, {})
24 + instructions = bot_cfg.get("agent_instructions", "")
25 + if instructions:
26 + system_prompt.append(
27 + self.agent.read_prompt(
28 + "fw.telegram.user_message_instructions.md",
29 + instructions=instructions,
30 + )
31 + )
plugins/_telegram_integration/extensions/python/tool_execute_after/_50_telegram_response.py
-1
@@ -1,5 +1,4 @@
1 from helpers.extension import Extension
2 -from helpers.print_style import PrintStyle
2 from helpers.tool import Response
3 from plugins._telegram_integration.helpers.handler import (
4 CTX_TG_BOT,
plugins/_telegram_integration/helpers/bot_manager.py
+3 -2
@@ -6,7 +6,7 @@ from aiogram import Bot, Dispatcher, Router, F
6 from aiogram.client.default import DefaultBotProperties
7 from aiogram.enums import ParseMode, ChatType
8 from aiogram.filters import Command, CommandStart
9 -from aiogram.types import Message, CallbackQuery
9 +from aiogram.types import Message
10
11 from helpers.errors import format_error
12 from helpers.print_style import PrintStyle
@@ -22,6 +22,7 @@ class BotInstance:
22 task: asyncio.Task | None = None # polling task
23 webhook_active: bool = False # True when webhook mode is registered
24 webhook_secret: str = "" # secret for webhook verification
25 + group_mode: str = "mention" # current group_mode setting
26 bot_info: object | None = None # cached result of bot.get_me()
27
28 # Bot registry (singleton, persists across module reloads)
@@ -77,7 +78,7 @@ def create_bot(
78 router.message.register(on_message)
79
80 dp.include_router(router)
80 - instance = BotInstance(name=name, bot=bot, dispatcher=dp, router=router)
81 + instance = BotInstance(name=name, bot=bot, dispatcher=dp, router=router, group_mode=group_mode)
82 _bots[name] = instance
83 return instance
84
plugins/_telegram_integration/helpers/handler.py
+3 -10
@@ -29,6 +29,7 @@ STATE_FILE = "usr/telegram/state.json"
29
30 # Context data keys
31 CTX_TG_BOT = "telegram_bot"
32 +CTX_TG_BOT_CFG = "telegram_bot_cfg"
33 CTX_TG_CHAT_ID = "telegram_chat_id"
34 CTX_TG_USER_ID = "telegram_user_id"
35 CTX_TG_USERNAME = "telegram_username"
@@ -232,19 +233,9 @@ async def handle_message(message: TgMessage, bot_name: str, bot_cfg: dict):
233 body=text,
234 )
235
235 - instructions = bot_cfg.get("agent_instructions", "")
236 - if instructions:
237 - user_msg += agent.read_prompt(
238 - "fw.telegram.user_message_instructions.md",
239 - instructions=instructions,
240 - )
241 -
242 - system_ctx = agent.read_prompt("fw.telegram.system_context.md")
243 -
236 mq.log_user_message(context, user_msg, attachments, source=" (telegram)")
237 context.communicate(UserMessage(
238 message=user_msg,
247 - system_message=[system_ctx],
239 attachments=attachments,
240 ))
241
@@ -331,6 +322,7 @@ async def _get_or_create_context_from_user(
322 if ctx_id:
323 ctx = AgentContext.get(ctx_id)
324 if ctx:
325 + ctx.data[CTX_TG_CHAT_ID] = chat_id # always track latest chat
326 return ctx
327 # Context was garbage collected, remove stale mapping
328 chats.pop(key, None)
@@ -342,6 +334,7 @@ async def _get_or_create_context_from_user(
334 ctx = AgentContext(config, name=f"Telegram: {display_name}")
335
336 ctx.data[CTX_TG_BOT] = bot_name
337 + ctx.data[CTX_TG_BOT_CFG] = bot_cfg
338 ctx.data[CTX_TG_CHAT_ID] = chat_id
339 ctx.data[CTX_TG_USER_ID] = user_id
340 ctx.data[CTX_TG_USERNAME] = username or ""
plugins/_telegram_integration/prompts/fw.telegram.cleared.md deleted
-3
@@ -1,3 +0,0 @@
1 -chat cleared by user via /clear command
2 -previous context has been reset
3 -greet user and wait for new input
\ No newline at end of file
plugins/_telegram_integration/prompts/fw.telegram.system_context.md deleted
-4
@@ -1,4 +0,0 @@
1 -telegram session user communicates via Telegram
2 -response tool sends the message to the user dont use python code
3 -break_loop true > stop working and wait for user reply
4 -break_loop false > only for mid-task progress updates then keep working
\ No newline at end of file