Aggiunto il supporto per la gestione del bot Telegram e aggiornata la configurazione del pipeline
This commit is contained in:
@@ -3,12 +3,17 @@ from dotenv import load_dotenv
|
||||
from agno.utils.log import log_info #type: ignore
|
||||
from app.utils import ChatManager
|
||||
from app.agents import Pipeline
|
||||
from app.utils.telegram_app import BotFunctions
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Inizializzazioni
|
||||
load_dotenv()
|
||||
pipeline = Pipeline()
|
||||
# Disabilita TUTTI i log di livello inferiore a WARNING
|
||||
# La maggior parte arrivano da httpx
|
||||
import logging
|
||||
logging.getLogger().setLevel(logging.WARNING)
|
||||
|
||||
|
||||
|
||||
def gradio_app(pipeline: Pipeline, server: str = "0.0.0.0", port: int = 8000) -> str:
|
||||
chat = ChatManager()
|
||||
|
||||
########################################
|
||||
@@ -73,7 +78,18 @@ if __name__ == "__main__":
|
||||
save_btn.click(save_current_chat, inputs=None, outputs=None)
|
||||
load_btn.click(load_previous_chat, inputs=None, outputs=[chatbot, chatbot])
|
||||
|
||||
server, port = ("0.0.0.0", 8000) # 0.0.0.0 per accesso esterno (Docker)
|
||||
server_log = "localhost" if server == "0.0.0.0" else server
|
||||
log_info(f"Starting UPO AppAI Chat on http://{server_log}:{port}") # noqa
|
||||
demo.launch(server_name=server, server_port=port, quiet=True)
|
||||
_app, local, share = demo.launch(server_name=server, server_port=port, quiet=True, prevent_thread_lock=True)
|
||||
log_info(f"UPO AppAI Chat is running on {local} and {share}")
|
||||
return share
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
load_dotenv() # Carica le variabili d'ambiente dal file .env
|
||||
|
||||
pipeline = Pipeline()
|
||||
url = gradio_app(pipeline)
|
||||
|
||||
telegram = BotFunctions.create_bot(pipeline, url)
|
||||
telegram.run_polling()
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from app.utils.market_aggregation import aggregate_history_prices, aggregate_product_info
|
||||
from app.utils.wrapper_handler import WrapperHandler
|
||||
from app.utils.chat_manager import ChatManager
|
||||
from app.utils.telegram_app import BotFunctions
|
||||
|
||||
__all__ = ["aggregate_history_prices", "aggregate_product_info", "WrapperHandler", "ChatManager"]
|
||||
__all__ = ["aggregate_history_prices", "aggregate_product_info", "WrapperHandler", "ChatManager", "BotFunctions"]
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import os
|
||||
import json
|
||||
import httpx
|
||||
from enum import Enum
|
||||
from typing import Any
|
||||
from agno.utils.log import log_info # type: ignore
|
||||
@@ -6,6 +8,7 @@ from telegram import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup,
|
||||
from telegram.constants import ChatAction
|
||||
from telegram.ext import Application, CallbackQueryHandler, CommandHandler, ContextTypes, ConversationHandler, ExtBot, JobQueue, MessageHandler, filters
|
||||
from app.agents import AppModels, PredictorStyle
|
||||
from app.agents.pipeline import Pipeline
|
||||
|
||||
# Lo stato cambia in base al valore di ritorno delle funzioni async
|
||||
# END state è già definito in telegram.ext.ConversationHandler
|
||||
@@ -29,9 +32,9 @@ class ConfigsChat(Enum):
|
||||
|
||||
class ConfigsRun:
|
||||
def __init__(self):
|
||||
self.model_team = BotFunctions.app_models[0]
|
||||
self.model_output = BotFunctions.app_models[0]
|
||||
self.strategy = PredictorStyle.CONSERVATIVE
|
||||
self.model_team = BotFunctions.pipeline.available_models[0]
|
||||
self.model_output = BotFunctions.pipeline.available_models[0]
|
||||
self.strategy = BotFunctions.pipeline.all_styles[0]
|
||||
self.user_query = ""
|
||||
|
||||
|
||||
@@ -39,13 +42,12 @@ class ConfigsRun:
|
||||
class BotFunctions:
|
||||
|
||||
# In theory this is already thread-safe if run with CPython
|
||||
users_req: dict[User, ConfigsRun] = {}
|
||||
app_models: list[AppModels] = AppModels.availables()
|
||||
strategies: list[PredictorStyle] = list(PredictorStyle)
|
||||
users_req: dict[User, ConfigsRun]
|
||||
pipeline: Pipeline
|
||||
|
||||
# che incubo di typing
|
||||
@staticmethod
|
||||
def create_bot() -> Application[ExtBot[None], ContextTypes.DEFAULT_TYPE, dict[str, Any], dict[str, Any], dict[str, Any], JobQueue[ContextTypes.DEFAULT_TYPE]]:
|
||||
def create_bot(pipeline: Pipeline, 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.
|
||||
@@ -54,10 +56,13 @@ class BotFunctions:
|
||||
Raises:
|
||||
AssertionError: If the TELEGRAM_BOT_TOKEN environment variable is not set.
|
||||
"""
|
||||
BotFunctions.users_req = {}
|
||||
BotFunctions.pipeline = pipeline
|
||||
|
||||
token = os.getenv("TELEGRAM_BOT_TOKEN", '')
|
||||
assert token, "TELEGRAM_BOT_TOKEN environment variable not set"
|
||||
|
||||
if miniapp_url: BotFunctions.update_miniapp_url(miniapp_url, token)
|
||||
app = Application.builder().token(token).build()
|
||||
|
||||
conv_handler = ConversationHandler(
|
||||
@@ -113,7 +118,7 @@ class BotFunctions:
|
||||
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 BotFunctions.app_models]
|
||||
models = [(m.name, f"__select_config:{state}:{m.name}") for m in BotFunctions.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))
|
||||
@@ -131,6 +136,20 @@ class BotFunctions:
|
||||
assert update.message and update.message.from_user, "Update message or user is None"
|
||||
return update.message, update.message.from_user
|
||||
|
||||
@staticmethod
|
||||
def update_miniapp_url(url: str, token: str) -> None:
|
||||
try:
|
||||
endpoint = f"https://api.telegram.org/bot{token}/setChatMenuButton"
|
||||
payload = {"menu_button": json.dumps({
|
||||
"type": "web_app",
|
||||
"text": "Apri Mini App", # Il testo che appare sul pulsante
|
||||
"web_app": {
|
||||
"url": url
|
||||
}
|
||||
})}
|
||||
httpx.post(endpoint, data=payload)
|
||||
except httpx.HTTPError as e:
|
||||
log_info(f"Failed to update mini app URL: {e}")
|
||||
|
||||
#########################################
|
||||
# Funzioni async per i comandi e messaggi
|
||||
@@ -154,7 +173,7 @@ class BotFunctions:
|
||||
async def __strategy(update: Update, context: ContextTypes.DEFAULT_TYPE) -> int:
|
||||
query, _ = await BotFunctions.handle_callbackquery(update)
|
||||
|
||||
strategies = [(s.name, f"__select_config:{ConfigsChat.STRATEGY}:{s.name}") for s in BotFunctions.strategies]
|
||||
strategies = [(s.name, f"__select_config:{ConfigsChat.STRATEGY}:{s.name}") for s in BotFunctions.pipeline.all_styles]
|
||||
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))
|
||||
@@ -238,13 +257,3 @@ class BotFunctions:
|
||||
document = io.BytesIO(report_content.encode('utf-8'))
|
||||
await bot.send_document(chat_id=chat_id, document=document, filename="report.md", parse_mode='MarkdownV2', caption=full_message)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from dotenv import load_dotenv
|
||||
load_dotenv()
|
||||
bot_app = BotFunctions.create_bot()
|
||||
bot_app.run_polling()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user