Add Telegram bot support #23

Merged
Berack96 merged 23 commits from 6-telegram-interface into main 2025-10-13 10:49:46 +02:00
6 changed files with 147 additions and 134 deletions
Showing only changes of commit b42500b067 - Show all commits

View File

@@ -3,7 +3,7 @@ import asyncio
import logging import logging
from dotenv import load_dotenv from dotenv import load_dotenv
from app.configs import AppConfig from app.configs import AppConfig
from app.interface import ChatManager, BotFunctions from app.interface import *
from app.agents import Pipeline from app.agents import Pipeline
@@ -14,14 +14,15 @@ if __name__ == "__main__":
configs = AppConfig.load() configs = AppConfig.load()
pipeline = Pipeline(configs) pipeline = Pipeline(configs)
chat = ChatManager() chat = ChatManager(pipeline)
gradio = chat.gradio_build_interface() gradio = chat.gradio_build_interface()
_app, local_url, share_url = gradio.launch(server_name="0.0.0.0", server_port=configs.port, quiet=True, prevent_thread_lock=True, share=configs.gradio_share) _app, local_url, share_url = gradio.launch(server_name="0.0.0.0", server_port=configs.port, quiet=True, prevent_thread_lock=True, share=configs.gradio_share)
logging.info(f"UPO AppAI Chat is running on {share_url or local_url}") logging.info(f"UPO AppAI Chat is running on {share_url or local_url}")
try: try:
telegram = BotFunctions.create_bot(share_url) telegram = TelegramApp(pipeline)
telegram.run_polling() telegram.add_miniapp_url(share_url)
telegram.run()
except Exception as _: except Exception as _:
logging.warning("Telegram bot could not be started. Continuing without it.") logging.warning("Telegram bot could not be started. Continuing without it.")
asyncio.get_event_loop().run_forever() asyncio.get_event_loop().run_forever()

View File

@@ -18,7 +18,8 @@ class Pipeline:
# Stato iniziale # Stato iniziale
self.leader_model = self.configs.get_model_by_name(self.configs.agents.team_leader_model) self.leader_model = self.configs.get_model_by_name(self.configs.agents.team_leader_model)
self.choose_strategy(0) self.team_model = self.configs.get_model_by_name(self.configs.agents.team_model)
self.strategy = self.configs.get_strategy_by_name(self.configs.agents.strategy)
# ====================== # ======================
# Dropdown handlers # Dropdown handlers
@@ -33,7 +34,7 @@ class Pipeline:
""" """
Sceglie la strategia da usare per il Predictor. Sceglie la strategia da usare per il Predictor.
""" """
self.strat = self.configs.strategies[index].description self.strategy = self.configs.strategies[index]
# ====================== # ======================
# Helpers # Helpers
@@ -61,14 +62,15 @@ class Pipeline:
4. Restituisce la strategia finale 4. Restituisce la strategia finale
""" """
# Step 1: Creazione Team # Step 1: Creazione Team
team_model = self.configs.get_model_by_name(self.configs.agents.team_model) team = create_team_with(self.configs, self.team_model, self.leader_model)
team = create_team_with(self.configs, team_model, self.leader_model)
# Step 1: raccolta output dai membri del Team # Step 2: raccolta output dai membri del Team
logging.info(f"Pipeline received query: {query}") logging.info(f"Pipeline received query: {query}")
# TODO migliorare prompt (?)
query = f"The user query is: {query}\n\n They requested a {self.strategy.label} investment strategy."
team_outputs = team.run(query) # type: ignore team_outputs = team.run(query) # type: ignore
# Step 2: recupero ouput # Step 3: recupero ouput
if not isinstance(team_outputs.content, str): if not isinstance(team_outputs.content, str):
logging.error(f"Team output is not a string: {team_outputs.content}") logging.error(f"Team output is not a string: {team_outputs.content}")
raise ValueError("Team output is not a string") raise ValueError("Team output is not a string")

View File

@@ -4,7 +4,7 @@ import ollama
import yaml import yaml
import logging.config import logging.config
import agno.utils.log # type: ignore import agno.utils.log # type: ignore
from typing import Any from typing import Any, ClassVar
from pydantic import BaseModel from pydantic import BaseModel
from agno.agent import Agent from agno.agent import Agent
from agno.tools import Toolkit from agno.tools import Toolkit
@@ -88,7 +88,7 @@ class AppConfig(BaseModel):
models: ModelsConfig = ModelsConfig() models: ModelsConfig = ModelsConfig()
agents: AgentsConfigs = AgentsConfigs() agents: AgentsConfigs = AgentsConfigs()
__lock = threading.Lock() _lock: ClassVar[threading.Lock] = threading.Lock()
@classmethod @classmethod
def load(cls, file_path: str = "configs.yaml") -> 'AppConfig': def load(cls, file_path: str = "configs.yaml") -> 'AppConfig':
@@ -110,7 +110,7 @@ class AppConfig(BaseModel):
return configs return configs
def __new__(cls, *args: Any, **kwargs: Any) -> 'AppConfig': def __new__(cls, *args: Any, **kwargs: Any) -> 'AppConfig':
with cls.__lock: with cls._lock:
if not hasattr(cls, 'instance'): if not hasattr(cls, 'instance'):
cls.instance = super(AppConfig, cls).__new__(cls) cls.instance = super(AppConfig, cls).__new__(cls)
return cls.instance return cls.instance
@@ -145,6 +145,17 @@ class AppConfig(BaseModel):
return strat return strat
raise ValueError(f"Strategy with name '{name}' not found.") raise ValueError(f"Strategy with name '{name}' not found.")
def get_defaults(self) -> tuple[AppModel, AppModel, Strategy]:
"""
Retrieve the default team model, leader model, and strategy.
Returns:
A tuple containing the default team model (AppModel), leader model (AppModel), and strategy (Strategy).
"""
team_model = self.get_model_by_name(self.agents.team_model)
leader_model = self.get_model_by_name(self.agents.team_leader_model)
strategy = self.get_strategy_by_name(self.agents.strategy)
return team_model, leader_model, strategy
def set_logging_level(self) -> None: def set_logging_level(self) -> None:
""" """
Set the logging level based on the configuration. Set the logging level based on the configuration.

View File

@@ -1,4 +1,4 @@
from app.interface.chat import ChatManager from app.interface.chat import ChatManager
from app.interface.telegram_app import BotFunctions from app.interface.telegram_app import TelegramApp
__all__ = ["ChatManager", "BotFunctions"] __all__ = ["ChatManager", "TelegramApp"]

View File

@@ -12,9 +12,9 @@ class ChatManager:
- salva e ricarica le chat - salva e ricarica le chat
""" """
def __init__(self): def __init__(self, pipeline: Pipeline):
self.history: list[dict[str, str]] = [] # [{"role": "user"/"assistant", "content": "..."}] self.history: list[dict[str, str]] = [] # [{"role": "user"/"assistant", "content": "..."}]
self.pipeline = Pipeline() self.pipeline = pipeline
def send_message(self, message: str) -> None: def send_message(self, message: str) -> None:
""" """
@@ -106,7 +106,7 @@ class ChatManager:
type="index", type="index",
label="Stile di investimento" label="Stile di investimento"
) )
style.change(fn=self.pipeline.choose_style, inputs=style, outputs=None) style.change(fn=self.pipeline.choose_strategy, inputs=style, outputs=None)
chatbot = gr.Chatbot(label="Conversazione", height=500, type="messages") chatbot = gr.Chatbot(label="Conversazione", height=500, type="messages")
msg = gr.Textbox(label="Scrivi la tua richiesta", placeholder="Es: Quali sono le crypto interessanti oggi?") msg = gr.Textbox(label="Scrivi la tua richiesta", placeholder="Es: Quali sono le crypto interessanti oggi?")

View File

@@ -5,12 +5,12 @@ import httpx
import logging import logging
import warnings import warnings
from enum import Enum from enum import Enum
from typing import Any
from markdown_pdf import MarkdownPdf, Section from markdown_pdf import MarkdownPdf, Section
from telegram import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, Update, User from telegram import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, Message, Update, User
from telegram.constants import ChatAction from telegram.constants import ChatAction
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, ConversationHandler, ExtBot, JobQueue, MessageHandler, filters from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, ConversationHandler, MessageHandler, filters
from app.agents.pipeline import Pipeline from app.agents.pipeline import Pipeline
from app.configs import AppConfig
# per per_message di ConversationHandler che rompe sempre qualunque input tu metta # per per_message di ConversationHandler che rompe sempre qualunque input tu metta
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
@@ -32,73 +32,83 @@ logging = logging.getLogger(__name__)
# ╚═══> END # ╚═══> END
CONFIGS, SELECT_CONFIG = range(2) CONFIGS, SELECT_CONFIG = range(2)
# Usato per separare la query arrivata da Telegram
QUERY_SEP = "|==|"
class ConfigsChat(Enum): class ConfigsChat(Enum):
MODEL_TEAM = "Team Model" MODEL_TEAM = "Team Model"
MODEL_OUTPUT = "Output Model" MODEL_OUTPUT = "Output Model"
STRATEGY = "Strategy" STRATEGY = "Strategy"
class ConfigsRun: class ConfigsRun:
def __init__(self): def __init__(self, configs: AppConfig):
self.model_team = Pipeline.available_models[0] team, leader, strategy = configs.get_defaults()
self.model_output = Pipeline.available_models[0] self.team_model = team
self.strategy = Pipeline.all_styles[0] self.leader_model = leader
self.strategy = strategy
self.user_query = "" self.user_query = ""
class TelegramApp:
class BotFunctions: def __init__(self, pipeline: Pipeline):
token = os.getenv("TELEGRAM_BOT_TOKEN")
# In theory this is already thread-safe if run with CPython
users_req: dict[User, ConfigsRun]
# che incubo di typing
@staticmethod
def create_bot(miniapp_url: str | None = None) -> Application[ExtBot[None], ContextTypes.DEFAULT_TYPE, dict[str, Any], dict[str, Any], dict[str, Any], JobQueue[ContextTypes.DEFAULT_TYPE]]:
"""
Create a Telegram bot application instance.
Assumes the TELEGRAM_BOT_TOKEN environment variable is set.
Returns:
Application: The Telegram bot application instance.
Raises:
AssertionError: If the TELEGRAM_BOT_TOKEN environment variable is not set.
"""
BotFunctions.users_req = {}
token = os.getenv("TELEGRAM_BOT_TOKEN", '')
assert token, "TELEGRAM_BOT_TOKEN environment variable not set" assert token, "TELEGRAM_BOT_TOKEN environment variable not set"
if miniapp_url: BotFunctions.update_miniapp_url(miniapp_url, token) self.user_requests: dict[User, ConfigsRun] = {}
app = Application.builder().token(token).build() self.pipeline = pipeline
self.token = token
self.create_bot()
def add_miniapp_url(self, url: str) -> None:
try:
endpoint = f"https://api.telegram.org/bot{self.token}/setChatMenuButton"
payload = {"menu_button": json.dumps({
"type": "web_app",
"text": "MiniApp",
"web_app": { "url": url }
})}
httpx.post(endpoint, data=payload)
except httpx.HTTPError as e:
logging.info(f"Failed to update mini app URL: {e}")
def create_bot(self) -> None:
"""
Initialize the Telegram bot and set up the conversation handler.
"""
app = Application.builder().token(self.token).build()
app.add_error_handler(self.__error_handler)
app.add_handler(ConversationHandler( app.add_handler(ConversationHandler(
per_message=False, # capire a cosa serve perchè da un warning quando parte il server per_message=False, # capire a cosa serve perchè da un warning quando parte il server
copilot-pull-request-reviewer[bot] commented 2025-10-09 13:55:41 +02:00 (Migrated from github.com)
Review

Comment is in Italian. Consider translating to English: '# understand what this does because it gives a warning when the server starts'

            per_message=False, # understand what this does because it gives a warning when the server starts
Comment is in Italian. Consider translating to English: '# understand what this does because it gives a warning when the server starts' ```suggestion per_message=False, # understand what this does because it gives a warning when the server starts ```
copilot-pull-request-reviewer[bot] commented 2025-10-12 20:27:13 +02:00 (Migrated from github.com)
Review

Corrected spelling of 'perchè' to 'perché' in Italian comment.

            per_message=False, # capire a cosa serve perché da un warning quando parte il server
Corrected spelling of 'perchè' to 'perché' in Italian comment. ```suggestion per_message=False, # capire a cosa serve perché da un warning quando parte il server ```
entry_points=[CommandHandler('start', BotFunctions.__start)], entry_points=[CommandHandler('start', self.__start)],
states={ states={
CONFIGS: [ CONFIGS: [
CallbackQueryHandler(BotFunctions.__model_team, pattern=ConfigsChat.MODEL_TEAM.name), CallbackQueryHandler(self.__model_team, pattern=ConfigsChat.MODEL_TEAM.name),
CallbackQueryHandler(BotFunctions.__model_output, pattern=ConfigsChat.MODEL_OUTPUT.name), CallbackQueryHandler(self.__model_output, pattern=ConfigsChat.MODEL_OUTPUT.name),
CallbackQueryHandler(BotFunctions.__strategy, pattern=ConfigsChat.STRATEGY.name), CallbackQueryHandler(self.__strategy, pattern=ConfigsChat.STRATEGY.name),
CallbackQueryHandler(BotFunctions.__cancel, pattern='^cancel$'), CallbackQueryHandler(self.__cancel, pattern='^cancel$'),
MessageHandler(filters.TEXT, BotFunctions.__start_team) # Any text message MessageHandler(filters.TEXT, self.__start_team) # Any text message
], ],
SELECT_CONFIG: [ SELECT_CONFIG: [
CallbackQueryHandler(BotFunctions.__select_config, pattern='^__select_config:.*$'), CallbackQueryHandler(self.__select_config, pattern=f"^__select_config{QUERY_SEP}.*$"),
] ]
}, },
fallbacks=[CommandHandler('start', BotFunctions.__start)], fallbacks=[CommandHandler('start', self.__start)],
)) ))
return app self.app = app
def run(self) -> None:
self.app.run_polling()
######################################## ########################################
# Funzioni di utilità # Funzioni di utilità
######################################## ########################################
@staticmethod async def start_message(self, user: User, query: CallbackQuery | Message) -> None:
async def start_message(user: User, query: CallbackQuery | Message) -> None: confs = self.user_requests.setdefault(user, ConfigsRun(self.pipeline.configs))
confs = BotFunctions.users_req.setdefault(user, ConfigsRun())
str_model_team = f"{ConfigsChat.MODEL_TEAM.value}: {confs.model_team.name}" str_model_team = f"{ConfigsChat.MODEL_TEAM.value}: {confs.team_model.label}"
str_model_output = f"{ConfigsChat.MODEL_OUTPUT.value}: {confs.model_output.name}" str_model_output = f"{ConfigsChat.MODEL_OUTPUT.value}: {confs.leader_model.label}"
str_strategy = f"{ConfigsChat.STRATEGY.value}: {confs.strategy.name}" str_strategy = f"{ConfigsChat.STRATEGY.value}: {confs.strategy.label}"
msg, keyboard = ( msg, keyboard = (
"Please choose an option or write your query", "Please choose an option or write your query",
@@ -115,113 +125,103 @@ class BotFunctions:
else: else:
await query.reply_text(msg, reply_markup=keyboard, parse_mode='MarkdownV2') await query.reply_text(msg, reply_markup=keyboard, parse_mode='MarkdownV2')
@staticmethod async def handle_callbackquery(self, update: Update) -> tuple[CallbackQuery, User]:
async def handle_configs(update: Update, state: ConfigsChat, msg: str | None = None) -> int:
query, _ = await BotFunctions.handle_callbackquery(update)
models = [(m.name, f"__select_config:{state}:{m.name}") for m in Pipeline.available_models]
inline_btns = [[InlineKeyboardButton(name, callback_data=callback_data)] for name, callback_data in models]
await query.edit_message_text(msg or state.value, reply_markup=InlineKeyboardMarkup(inline_btns))
return SELECT_CONFIG
@staticmethod
async def handle_callbackquery(update: Update) -> tuple[CallbackQuery, User]:
assert update.callback_query and update.callback_query.from_user, "Update callback_query or user is None" assert update.callback_query and update.callback_query.from_user, "Update callback_query or user is None"
query = update.callback_query query = update.callback_query
await query.answer() # Acknowledge the callback query await query.answer() # Acknowledge the callback query
return query, query.from_user return query, query.from_user
@staticmethod async def handle_message(self, update: Update) -> tuple[Message, User]:
async def handle_message(update: Update) -> tuple[Message, User]:
assert update.message and update.message.from_user, "Update message or user is None" assert update.message and update.message.from_user, "Update message or user is None"
return update.message, update.message.from_user return update.message, update.message.from_user
@staticmethod def callback_data(self, strings: list[str]) -> str:
def update_miniapp_url(url: str, token: str) -> None: return QUERY_SEP.join(strings)
async def __error_handler(self, update: object, context: ContextTypes.DEFAULT_TYPE) -> None:
try: try:
endpoint = f"https://api.telegram.org/bot{token}/setChatMenuButton" logging.exception(f"Unhandled exception in Telegram handler {context.error}")
payload = {"menu_button": json.dumps({
"type": "web_app", # Try to notify the user in chat if possible
"text": "MiniApp", if isinstance(update, Update) and update.effective_chat:
"web_app": { chat_id = update.effective_chat.id
"url": url msg = "Si è verificato un errore inatteso. Gli sviluppatori sono stati avvisati."
} await context.bot.send_message(chat_id=chat_id, text=msg)
})}
httpx.post(endpoint, data=payload) except Exception:
except httpx.HTTPError as e: # Ensure we never raise from the error handler itself
logging.info(f"Failed to update mini app URL: {e}") logging.exception("Exception in the error handler")
######################################### #########################################
# Funzioni async per i comandi e messaggi # Funzioni async per i comandi e messaggi
######################################### #########################################
@staticmethod async def __start(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: message, user = await self.handle_message(update)
message, user = await BotFunctions.handle_message(update)
logging.info(f"@{user.username} started the conversation.") logging.info(f"@{user.username} started the conversation.")
await BotFunctions.start_message(user, message) await self.start_message(user, message)
return CONFIGS return CONFIGS
@staticmethod async def __model_team(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __model_team(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: return await self._model_select(update, ConfigsChat.MODEL_TEAM)
return await BotFunctions.handle_configs(update, ConfigsChat.MODEL_TEAM)
@staticmethod async def __model_output(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __model_output(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: return await self._model_select(update, ConfigsChat.MODEL_OUTPUT)
return await BotFunctions.handle_configs(update, ConfigsChat.MODEL_OUTPUT)
@staticmethod async def _model_select(self, update: Update, state: ConfigsChat, msg: str | None = None) -> int:
async def __strategy(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: query, _ = await self.handle_callbackquery(update)
query, _ = await BotFunctions.handle_callbackquery(update)
strategies = [(s.name, f"__select_config:{ConfigsChat.STRATEGY}:{s.name}") for s in Pipeline.all_styles] models = [(m.label, self.callback_data([f"__select_config", str(state), m.name])) for m in self.pipeline.configs.models.all_models]
inline_btns = [[InlineKeyboardButton(name, callback_data=callback_data)] for name, callback_data in models]
await query.edit_message_text(msg or state.value, reply_markup=InlineKeyboardMarkup(inline_btns))
return SELECT_CONFIG
async def __strategy(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
query, _ = await self.handle_callbackquery(update)
strategies = [(s.label, self.callback_data([f"__select_config", str(ConfigsChat.STRATEGY), s.name])) for s in self.pipeline.configs.strategies]
inline_btns = [[InlineKeyboardButton(name, callback_data=callback_data)] for name, callback_data in strategies] inline_btns = [[InlineKeyboardButton(name, callback_data=callback_data)] for name, callback_data in strategies]
await query.edit_message_text("Select a strategy", reply_markup=InlineKeyboardMarkup(inline_btns)) await query.edit_message_text("Select a strategy", reply_markup=InlineKeyboardMarkup(inline_btns))
return SELECT_CONFIG return SELECT_CONFIG
@staticmethod async def __select_config(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __select_config(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: query, user = await self.handle_callbackquery(update)
query, user = await BotFunctions.handle_callbackquery(update) logging.debug(f"@{user.username} --> {query.data}")
logging.info(f"@{user.username} --> {query.data}")
req = BotFunctions.users_req[user] req = self.user_requests[user]
_, state, model_name = str(query.data).split(QUERY_SEP)
_, state, model_name = str(query.data).split(':')
if state == str(ConfigsChat.MODEL_TEAM): if state == str(ConfigsChat.MODEL_TEAM):
req.model_team = AppModels[model_name] req.team_model = self.pipeline.configs.get_model_by_name(model_name)
if state == str(ConfigsChat.MODEL_OUTPUT): if state == str(ConfigsChat.MODEL_OUTPUT):
req.model_output = AppModels[model_name] req.leader_model = self.pipeline.configs.get_model_by_name(model_name)
if state == str(ConfigsChat.STRATEGY): if state == str(ConfigsChat.STRATEGY):
req.strategy = PredictorStyle[model_name] req.strategy = self.pipeline.configs.get_strategy_by_name(model_name)
await BotFunctions.start_message(user, query) await self.start_message(user, query)
return CONFIGS return CONFIGS
@staticmethod async def __start_team(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __start_team(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: message, user = await self.handle_message(update)
message, user = await BotFunctions.handle_message(update)
confs = BotFunctions.users_req[user] confs = self.user_requests[user]
confs.user_query = message.text or "" confs.user_query = message.text or ""
logging.info(f"@{user.username} started the team with [{confs.model_team}, {confs.model_output}, {confs.strategy}]") logging.info(f"@{user.username} started the team with [{confs.team_model}, {confs.leader_model}, {confs.strategy}]")
await BotFunctions.__run_team(update, confs) await self.__run_team(update, confs)
logging.info(f"@{user.username} team finished.") logging.info(f"@{user.username} team finished.")
return ConversationHandler.END return ConversationHandler.END
@staticmethod async def __cancel(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
async def __cancel(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int: query, user = await self.handle_callbackquery(update)
query, user = await BotFunctions.handle_callbackquery(update)
logging.info(f"@{user.username} canceled the conversation.") logging.info(f"@{user.username} canceled the conversation.")
if user in BotFunctions.users_req: if user in self.user_requests:
del BotFunctions.users_req[user] del self.user_requests[user]
await query.edit_message_text("Conversation canceled. Use /start to begin again.") await query.edit_message_text("Conversation canceled. Use /start to begin again.")
return ConversationHandler.END return ConversationHandler.END
@staticmethod async def __run_team(self, update: Update, confs: ConfigsRun) -> None:
async def __run_team(update: Update, confs: ConfigsRun) -> None:
if not update.message: return if not update.message: return
copilot-pull-request-reviewer[bot] commented 2025-10-12 20:27:13 +02:00 (Migrated from github.com)
Review

[nitpick] Consider using explicit None return for better code clarity: 'return None' instead of bare 'return'.

        if not update.message: return None
[nitpick] Consider using explicit None return for better code clarity: 'return None' instead of bare 'return'. ```suggestion if not update.message: return None ```
bot = update.get_bot() bot = update.get_bot()
@@ -230,9 +230,9 @@ class BotFunctions:
configs_str = [ configs_str = [
'Running with configurations: ', 'Running with configurations: ',
f'Team: {confs.model_team.name}', f'Team: {confs.team_model.label}',
f'Output: {confs.model_output.name}', f'Output: {confs.leader_model.label}',
f'Strategy: {confs.strategy.name}', f'Strategy: {confs.strategy.label}',
f'Query: "{confs.user_query}"' f'Query: "{confs.user_query}"'
] ]
full_message = f"""```\n{'\n'.join(configs_str)}\n```\n\n""" full_message = f"""```\n{'\n'.join(configs_str)}\n```\n\n"""
@@ -242,14 +242,13 @@ class BotFunctions:
# Remove user query and bot message # Remove user query and bot message
await bot.delete_message(chat_id=chat_id, message_id=update.message.id) await bot.delete_message(chat_id=chat_id, message_id=update.message.id)
# TODO settare correttamente i modelli self.pipeline.leader_model = confs.leader_model
pipeline = Pipeline() self.pipeline.team_model = confs.team_model
#pipeline.choose_predictor(Pipeline.available_models.index(confs.model_team)) self.pipeline.strategy = confs.strategy
pipeline.choose_style(Pipeline.all_styles.index(confs.strategy))
# TODO migliorare messaggi di attesa # TODO migliorare messaggi di attesa
await bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING) await bot.send_chat_action(chat_id=chat_id, action=ChatAction.TYPING)
report_content = pipeline.interact(confs.user_query) report_content = self.pipeline.interact(confs.user_query)
await msg.delete() await msg.delete()
# attach report file to the message # attach report file to the message