Refactoring architetturale e spostamento classi base
- Eliminazione del file __init__.py obsoleto che importava ChatManager e Pipeline - Spostamento della classe Pipeline in agents/pipeline.py - Spostamento della classe ChatManager in utils/chat_manager.py - Aggiornamento di __main__.py per importare da app.utils e app.agents, e modifica della logica per utilizzare Pipeline invece di chat per la selezione di provider e stile - Creazione della cartella base con classi base comuni: markets.py (ProductInfo, Price, MarketWrapper), news.py (Article, NewsWrapper), social.py (SocialPost, SocialComment, SocialWrapper) - Aggiornamento di tutti gli import nel progetto (markets/, news/, social/, utils/, tests/) per utilizzare la nuova struttura base/
This commit is contained in:
@@ -1,4 +0,0 @@
|
||||
from app.chat_manager import ChatManager
|
||||
from app.pipeline import Pipeline
|
||||
|
||||
__all__ = ["ChatManager", "Pipeline"]
|
||||
@@ -1,19 +1,23 @@
|
||||
import gradio as gr
|
||||
from agno.utils.log import log_info #type: ignore
|
||||
from dotenv import load_dotenv
|
||||
from app import ChatManager
|
||||
from agno.utils.log import log_info #type: ignore
|
||||
from app.utils import ChatManager
|
||||
from app.agents import Pipeline
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Inizializzazioni
|
||||
load_dotenv()
|
||||
pipeline = Pipeline()
|
||||
chat = ChatManager()
|
||||
|
||||
########################################
|
||||
# Funzioni Gradio
|
||||
########################################
|
||||
def respond(message: str, history: list[dict[str, str]]) -> tuple[list[dict[str, str]], list[dict[str, str]], str]:
|
||||
response = chat.send_message(message)
|
||||
chat.send_message(message)
|
||||
response = pipeline.interact(message)
|
||||
chat.receive_message(response)
|
||||
history.append({"role": "user", "content": message})
|
||||
history.append({"role": "assistant", "content": response})
|
||||
return history, history, ""
|
||||
@@ -42,18 +46,18 @@ if __name__ == "__main__":
|
||||
# Dropdown provider e stile
|
||||
with gr.Row():
|
||||
provider = gr.Dropdown(
|
||||
choices=chat.list_providers(),
|
||||
choices=pipeline.list_providers(),
|
||||
type="index",
|
||||
label="Modello da usare"
|
||||
)
|
||||
provider.change(fn=chat.choose_provider, inputs=provider, outputs=None)
|
||||
provider.change(fn=pipeline.choose_predictor, inputs=provider, outputs=None)
|
||||
|
||||
style = gr.Dropdown(
|
||||
choices=chat.list_styles(),
|
||||
choices=pipeline.list_styles(),
|
||||
type="index",
|
||||
label="Stile di investimento"
|
||||
)
|
||||
style.change(fn=chat.choose_style, inputs=style, outputs=None)
|
||||
style.change(fn=pipeline.choose_style, inputs=style, outputs=None)
|
||||
|
||||
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?")
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from app.agents.models import AppModels
|
||||
from app.agents.predictor import PredictorInput, PredictorOutput, PredictorStyle, PREDICTOR_INSTRUCTIONS
|
||||
from app.agents.team import create_team_with
|
||||
from app.agents.pipeline import Pipeline
|
||||
|
||||
__all__ = ["AppModels", "PredictorInput", "PredictorOutput", "PredictorStyle", "PREDICTOR_INSTRUCTIONS", "create_team_with"]
|
||||
__all__ = ["AppModels", "PredictorInput", "PredictorOutput", "PredictorStyle", "PREDICTOR_INSTRUCTIONS", "create_team_with", "Pipeline"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from agno.run.agent import RunOutput
|
||||
from app.agents import AppModels
|
||||
from app.agents.models import AppModels
|
||||
from app.agents.team import create_team_with
|
||||
from app.agents.predictor import PREDICTOR_INSTRUCTIONS, PredictorInput, PredictorOutput, PredictorStyle
|
||||
from app.markets.base import ProductInfo
|
||||
from app.base.markets import ProductInfo
|
||||
|
||||
|
||||
class Pipeline:
|
||||
@@ -1,6 +1,6 @@
|
||||
from enum import Enum
|
||||
from pydantic import BaseModel, Field
|
||||
from app.markets.base import ProductInfo
|
||||
from app.base.markets import ProductInfo
|
||||
|
||||
|
||||
class PredictorStyle(Enum):
|
||||
|
||||
0
src/app/base/__init__.py
Normal file
0
src/app/base/__init__.py
Normal file
@@ -1,5 +1,5 @@
|
||||
from agno.tools import Toolkit
|
||||
from app.markets.base import MarketWrapper, Price, ProductInfo
|
||||
from app.base.markets import MarketWrapper, Price, ProductInfo
|
||||
from app.markets.binance import BinanceWrapper
|
||||
from app.markets.coinbase import CoinBaseWrapper
|
||||
from app.markets.cryptocompare import CryptoCompareWrapper
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from typing import Any
|
||||
from binance.client import Client # type: ignore
|
||||
from app.markets.base import ProductInfo, MarketWrapper, Price
|
||||
from app.base.markets import ProductInfo, MarketWrapper, Price
|
||||
|
||||
|
||||
def extract_product(currency: str, ticker_data: dict[str, Any]) -> ProductInfo:
|
||||
|
||||
@@ -3,7 +3,7 @@ from enum import Enum
|
||||
from datetime import datetime, timedelta
|
||||
from coinbase.rest import RESTClient # type: ignore
|
||||
from coinbase.rest.types.product_types import Candle, GetProductResponse, Product # type: ignore
|
||||
from app.markets.base import ProductInfo, MarketWrapper, Price
|
||||
from app.base.markets import ProductInfo, MarketWrapper, Price
|
||||
|
||||
|
||||
def extract_product(product_data: GetProductResponse | Product) -> ProductInfo:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from typing import Any
|
||||
import requests
|
||||
from app.markets.base import ProductInfo, MarketWrapper, Price
|
||||
from app.base.markets import ProductInfo, MarketWrapper, Price
|
||||
|
||||
|
||||
def extract_product(asset_data: dict[str, Any]) -> ProductInfo:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import json
|
||||
from agno.tools.yfinance import YFinanceTools
|
||||
from app.markets.base import MarketWrapper, ProductInfo, Price
|
||||
from app.base.markets import MarketWrapper, ProductInfo, Price
|
||||
|
||||
|
||||
def extract_product(stock_data: dict[str, str]) -> ProductInfo:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from agno.tools import Toolkit
|
||||
from app.utils import WrapperHandler
|
||||
from app.news.base import NewsWrapper, Article
|
||||
from app.base.news import NewsWrapper, Article
|
||||
from app.news.news_api import NewsApiWrapper
|
||||
from app.news.googlenews import GoogleNewsWrapper
|
||||
from app.news.cryptopanic_api import CryptoPanicWrapper
|
||||
|
||||
@@ -2,7 +2,7 @@ import os
|
||||
from typing import Any
|
||||
import requests
|
||||
from enum import Enum
|
||||
from app.news.base import NewsWrapper, Article
|
||||
from app.base.news import NewsWrapper, Article
|
||||
|
||||
|
||||
class CryptoPanicFilter(Enum):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
from typing import Any
|
||||
from agno.tools.duckduckgo import DuckDuckGoTools
|
||||
from app.news.base import Article, NewsWrapper
|
||||
from app.base.news import Article, NewsWrapper
|
||||
|
||||
|
||||
def extract_article(result: dict[str, Any]) -> Article:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Any
|
||||
from gnews import GNews # type: ignore
|
||||
from app.news.base import Article, NewsWrapper
|
||||
from app.base.news import Article, NewsWrapper
|
||||
|
||||
|
||||
def extract_article(result: dict[str, Any]) -> Article:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from typing import Any
|
||||
import newsapi # type: ignore
|
||||
from app.news.base import Article, NewsWrapper
|
||||
from app.base.news import Article, NewsWrapper
|
||||
|
||||
|
||||
def extract_article(result: dict[str, Any]) -> Article:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from agno.tools import Toolkit
|
||||
from app.utils import WrapperHandler
|
||||
from app.social.base import SocialPost, SocialWrapper
|
||||
from app.base.social import SocialPost, SocialWrapper
|
||||
from app.social.reddit import RedditWrapper
|
||||
|
||||
__all__ = ["SocialAPIsTool", "RedditWrapper", "SocialPost"]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
from praw import Reddit # type: ignore
|
||||
from praw.models import Submission, MoreComments # type: ignore
|
||||
from app.social.base import SocialWrapper, SocialPost, SocialComment
|
||||
from app.base.social import SocialWrapper, SocialPost, SocialComment
|
||||
|
||||
|
||||
MAX_COMMENTS = 5
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
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
|
||||
|
||||
__all__ = ["aggregate_history_prices", "aggregate_product_info", "WrapperHandler"]
|
||||
__all__ = ["aggregate_history_prices", "aggregate_product_info", "WrapperHandler", "ChatManager"]
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
import json
|
||||
import os
|
||||
from app import Pipeline
|
||||
|
||||
SAVE_DIR = os.path.join(os.path.dirname(__file__), "..", "saves")
|
||||
os.makedirs(SAVE_DIR, exist_ok=True)
|
||||
|
||||
|
||||
class ChatManager:
|
||||
"""
|
||||
@@ -15,19 +10,19 @@ class ChatManager:
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.pipeline = Pipeline()
|
||||
self.history: list[dict[str, str]] = [] # [{"role": "user"/"assistant", "content": "..."}]
|
||||
|
||||
def send_message(self, message: str) -> str:
|
||||
def send_message(self, message: str) -> None:
|
||||
"""
|
||||
Aggiunge un messaggio utente, chiama la Pipeline e salva la risposta nello storico.
|
||||
"""
|
||||
# Aggiungi messaggio utente allo storico
|
||||
self.history.append({"role": "user", "content": message})
|
||||
|
||||
# Pipeline elabora la query
|
||||
response = self.pipeline.interact(message)
|
||||
|
||||
def receive_message(self, response: str) -> str:
|
||||
"""
|
||||
Riceve un messaggio dalla pipeline e lo aggiunge allo storico.
|
||||
"""
|
||||
# Aggiungi risposta assistente allo storico
|
||||
self.history.append({"role": "assistant", "content": response})
|
||||
|
||||
@@ -37,19 +32,17 @@ class ChatManager:
|
||||
"""
|
||||
Salva la chat corrente in src/saves/<filename>.
|
||||
"""
|
||||
path = os.path.join(SAVE_DIR, filename)
|
||||
with open(path, "w", encoding="utf-8") as f:
|
||||
with open(filename, "w", encoding="utf-8") as f:
|
||||
json.dump(self.history, f, ensure_ascii=False, indent=2)
|
||||
|
||||
def load_chat(self, filename: str = "chat.json") -> None:
|
||||
"""
|
||||
Carica una chat salvata da src/saves/<filename>.
|
||||
"""
|
||||
path = os.path.join(SAVE_DIR, filename)
|
||||
if not os.path.exists(path):
|
||||
if not os.path.exists(filename):
|
||||
self.history = []
|
||||
return
|
||||
with open(path, "r", encoding="utf-8") as f:
|
||||
with open(filename, "r", encoding="utf-8") as f:
|
||||
self.history = json.load(f)
|
||||
|
||||
def reset_chat(self) -> None:
|
||||
@@ -63,16 +56,3 @@ class ChatManager:
|
||||
Restituisce lo storico completo della chat.
|
||||
"""
|
||||
return self.history
|
||||
|
||||
# Facciamo pass-through di provider e style, così Gradio può usarli
|
||||
def choose_provider(self, index: int):
|
||||
self.pipeline.choose_predictor(index)
|
||||
|
||||
def choose_style(self, index: int):
|
||||
self.pipeline.choose_style(index)
|
||||
|
||||
def list_providers(self) -> list[str]:
|
||||
return self.pipeline.list_providers()
|
||||
|
||||
def list_styles(self) -> list[str]:
|
||||
return self.pipeline.list_styles()
|
||||
@@ -1,5 +1,5 @@
|
||||
import statistics
|
||||
from app.markets.base import ProductInfo, Price
|
||||
from app.base.markets import ProductInfo, Price
|
||||
|
||||
|
||||
def aggregate_history_prices(prices: dict[str, list[Price]]) -> list[Price]:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import pytest
|
||||
from app.agents import AppModels
|
||||
from app.agents.predictor import PREDICTOR_INSTRUCTIONS, PredictorInput, PredictorOutput, PredictorStyle
|
||||
from app.markets.base import ProductInfo
|
||||
from app.base.markets import ProductInfo
|
||||
|
||||
def unified_checks(model: AppModels, input):
|
||||
llm = model.get_agent(PREDICTOR_INSTRUCTIONS, output=PredictorOutput) # type: ignore[arg-type]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import pytest
|
||||
from app.markets.base import ProductInfo, Price
|
||||
from app.base.markets import ProductInfo, Price
|
||||
from app.utils.market_aggregation import aggregate_history_prices, aggregate_product_info
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user