Update telegram interface #44
@@ -133,3 +133,41 @@ class PipelineInputs:
|
||||
social_tool = SocialAPIsTool()
|
||||
|
|
||||
social_tool.handler.set_retries(api.retry_attempts, api.retry_delay_seconds)
|
||||
return market_tool, news_tool, social_tool
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "\n".join([
|
||||
f"Query Check: {self.query_analyzer_model.label}",
|
||||
f"Team Leader: {self.team_leader_model.label}",
|
||||
f"Team: {self.team_model.label}",
|
||||
f"Report: {self.report_generation_model.label}",
|
||||
f"Strategy: {self.strategy.label}",
|
||||
f"User Query: \"{self.user_query}\"",
|
||||
])
|
||||
|
||||
|
||||
class RunMessage:
|
||||
def __init__(self, inputs: PipelineInputs, prefix: str = "", suffix: str = ""):
|
||||
self.base_message = f"Running configurations: \n{prefix}{inputs}{suffix}\n\n"
|
||||
self.emojis = ['🔳', '➡️', '✅']
|
||||
self.placeholder = '<<<>>>'
|
||||
self.current = 0
|
||||
self.steps_total = [
|
||||
(f"{self.placeholder} Query Check", 1),
|
||||
(f"{self.placeholder} Info Recovery", 0),
|
||||
(f"{self.placeholder} Report Generation", 0),
|
||||
]
|
||||
|
||||
def update(self) -> 'RunMessage':
|
||||
text_curr, state_curr = self.steps_total[self.current]
|
||||
self.steps_total[self.current] = (text_curr, state_curr + 1)
|
||||
self.current += 1
|
||||
if self.current < len(self.steps_total):
|
||||
text_curr, state_curr = self.steps_total[self.current]
|
||||
self.steps_total[self.current] = (text_curr, state_curr + 1)
|
||||
return self
|
||||
|
||||
def get_latest(self, extra: str = "") -> str:
|
||||
steps = [msg.replace(self.placeholder, self.emojis[state]) for msg, state in self.steps_total]
|
||||
if extra:
|
||||
steps[self.current] = f"{steps[self.current]}: {extra}"
|
||||
return self.base_message + "\n".join(steps)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import asyncio
|
||||
import io
|
||||
import os
|
||||
import json
|
||||
@@ -10,7 +11,7 @@ from markdown_pdf import MarkdownPdf, Section
|
||||
from telegram import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, Update, User
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, ConversationHandler, MessageHandler, filters
|
||||
from app.agents.pipeline import Pipeline, PipelineInputs
|
||||
from app.agents.pipeline import Pipeline, PipelineEvent, PipelineInputs, RunMessage
|
||||
|
||||
# per per_message di ConversationHandler che rompe sempre qualunque input tu metta
|
||||
warnings.filterwarnings("ignore")
|
||||
@@ -233,7 +234,7 @@ class TelegramApp:
|
||||
|
||||
async def __select_config(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
query, user = await self.handle_callbackquery(update)
|
||||
logging.info(f"@{user.username} --> {query.data}")
|
||||
logging.debug(f"@{user.username} --> {query.data}")
|
||||
|
||||
|
Creating async tasks with Creating async tasks with `asyncio.create_task` without awaiting or tracking them can lead to unhandled exceptions and race conditions. The task may fail silently if `msg.edit_text` raises an exception. Consider using `await` directly or implementing proper task tracking and error handling.
The f-string uses backticks for markdown code formatting, but wraps the entire expression. If The f-string uses backticks for markdown code formatting, but wraps the entire expression. If `e.agent_name` or `e.tool.tool_name` contain special MarkdownV2 characters, they should be escaped. Consider adding proper markdown escaping for user-facing content.
|
||||
req = self.user_requests[user]
|
||||
_, state, index = str(query.data).split(QUERY_SEP)
|
||||
@@ -264,36 +265,33 @@ class TelegramApp:
|
||||
msg_id = update.message.message_id - 1
|
||||
chat_id = update.message.chat_id
|
||||
|
||||
configs_str = [
|
||||
'Running with configurations: ',
|
||||
f'Check: {inputs.query_analyzer_model.label}',
|
||||
f'Leader: {inputs.team_leader_model.label}',
|
||||
f'Team: {inputs.team_model.label}',
|
||||
f'Report: {inputs.report_generation_model.label}',
|
||||
f'Strategy: {inputs.strategy.label}',
|
||||
f'Query: "{inputs.user_query}"'
|
||||
]
|
||||
full_message = f"""```\n{'\n'.join(configs_str)}\n```\n\n"""
|
||||
first_message = full_message + "Generating report, please wait"
|
||||
msg = await bot.edit_message_text(chat_id=chat_id, message_id=msg_id, text=first_message, parse_mode='MarkdownV2')
|
||||
run_message = RunMessage(inputs, prefix="```\n", suffix="\n```")
|
||||
msg = await bot.edit_message_text(chat_id=chat_id, message_id=msg_id, text=run_message.get_latest(), parse_mode='MarkdownV2')
|
||||
if isinstance(msg, bool): return
|
||||
|
||||
# Remove user query and bot message
|
||||
await bot.delete_message(chat_id=chat_id, message_id=update.message.id)
|
||||
|
||||
# TODO migliorare messaggi di attesa
|
||||
def update_user(update: bool = True, extra: str = "") -> None:
|
||||
if update: run_message.update()
|
||||
message = run_message.get_latest(extra)
|
||||
if msg.text != message:
|
||||
asyncio.create_task(msg.edit_text(message, parse_mode='MarkdownV2'))
|
||||
|
||||
await bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING)
|
||||
pipeline = Pipeline(inputs)
|
||||
report_content = await pipeline.interact_async()
|
||||
await msg.delete()
|
||||
report_content = await pipeline.interact_async(listeners=[
|
||||
(PipelineEvent.QUERY_CHECK, lambda _: update_user()),
|
||||
(PipelineEvent.TOOL_USED, lambda e: update_user(False, f"`{e.agent_name} {e.tool.tool_name}`")),
|
||||
(PipelineEvent.INFO_RECOVERY, lambda _: update_user()),
|
||||
(PipelineEvent.REPORT_GENERATION, lambda _: update_user()),
|
||||
])
|
||||
|
||||
# attach report file to the message
|
||||
pdf = MarkdownPdf(toc_level=2, optimize=True)
|
||||
pdf.add_section(Section(report_content, toc=False))
|
||||
|
||||
# TODO vedere se ha senso dare il pdf o solo il messaggio
|
||||
document = io.BytesIO()
|
||||
pdf.save_bytes(document)
|
||||
document.seek(0)
|
||||
await bot.send_document(chat_id=chat_id, document=document, filename="report.pdf", parse_mode='MarkdownV2', caption=full_message)
|
||||
|
||||
await msg.reply_document(document=document, filename="report.pdf")
|
||||
|
||||
Reference in New Issue
Block a user
Potential IndexError if
self.current >= len(steps)after all steps complete. Theupdate()method incrementsself.currentbeyond the list bounds when the last step finishes. Add bounds checking:if extra and self.current < len(steps):