diff --git a/demos/example.py b/demos/example.py index c1fa08c..35acf59 100644 --- a/demos/example.py +++ b/demos/example.py @@ -14,7 +14,7 @@ try: instructions="Use tables to display data.", markdown=True, ) - result = reasoning_agent.run("Scrivi una poesia su un gatto. Sii breve.") + result = reasoning_agent.run("Scrivi una poesia su un gatto. Sii breve.") # type: ignore print(result.content) except Exception as e: print(f"Si รจ verificato un errore: {e}") diff --git a/demos/market_providers_api_demo.py b/demos/market_providers_api_demo.py index fc05c26..caba571 100644 --- a/demos/market_providers_api_demo.py +++ b/demos/market_providers_api_demo.py @@ -32,7 +32,7 @@ from app.markets import ( CryptoCompareWrapper, BinanceWrapper, YFinanceWrapper, - BaseWrapper + MarketWrapper ) # Carica variabili d'ambiente @@ -40,21 +40,21 @@ load_dotenv() class DemoFormatter: """Classe per formattare l'output del demo in modo strutturato.""" - + @staticmethod def print_header(title: str, char: str = "=", width: int = 80): """Stampa un'intestazione formattata.""" print(f"\n{char * width}") print(f"{title:^{width}}") print(f"{char * width}") - + @staticmethod def print_subheader(title: str, char: str = "-", width: int = 60): """Stampa una sotto-intestazione formattata.""" print(f"\n{char * width}") print(f" {title}") print(f"{char * width}") - + @staticmethod def print_request_info(provider_name: str, method: str, timestamp: datetime, status: str, error: Optional[str] = None): @@ -66,83 +66,83 @@ class DemoFormatter: if error: print(f"โŒ Error: {error}") print() - + @staticmethod def print_product_table(products: List[Any], title: str = "Products"): """Stampa una tabella di prodotti.""" if not products: print(f"๐Ÿ“‹ {title}: Nessun prodotto trovato") return - + print(f"๐Ÿ“‹ {title} ({len(products)} items):") print(f"{'Symbol':<15} {'ID':<20} {'Price':<12} {'Quote':<10} {'Status':<10}") print("-" * 67) - + for product in products[:10]: # Mostra solo i primi 10 symbol = getattr(product, 'symbol', 'N/A') product_id = getattr(product, 'id', 'N/A') price = getattr(product, 'price', 0.0) quote = getattr(product, 'quote_currency', 'N/A') status = getattr(product, 'status', 'N/A') - + # Tronca l'ID se troppo lungo if len(product_id) > 18: product_id = product_id[:15] + "..." - + price_str = f"${price:.2f}" if price > 0 else "N/A" - + print(f"{symbol:<15} {product_id:<20} {price_str:<12} {quote:<10} {status:<10}") - + if len(products) > 10: print(f"... e altri {len(products) - 10} prodotti") print() - + @staticmethod def print_prices_table(prices: List[Any], title: str = "Historical Prices"): """Stampa una tabella di prezzi storici.""" if not prices: print(f"๐Ÿ’ฐ {title}: Nessun prezzo trovato") return - + print(f"๐Ÿ’ฐ {title} ({len(prices)} entries):") print(f"{'Time':<12} {'Open':<12} {'High':<12} {'Low':<12} {'Close':<12} {'Volume':<15}") print("-" * 75) - + for price in prices[:5]: # Mostra solo i primi 5 time_str = getattr(price, 'time', 'N/A') # Il time รจ giร  una stringa, non serve strftime if len(time_str) > 10: time_str = time_str[:10] # Tronca se troppo lungo - + open_price = f"${getattr(price, 'open', 0):.2f}" high_price = f"${getattr(price, 'high', 0):.2f}" low_price = f"${getattr(price, 'low', 0):.2f}" close_price = f"${getattr(price, 'close', 0):.2f}" volume = f"{getattr(price, 'volume', 0):,.0f}" - + print(f"{time_str:<12} {open_price:<12} {high_price:<12} {low_price:<12} {close_price:<12} {volume:<15}") - + if len(prices) > 5: print(f"... e altri {len(prices) - 5} prezzi") print() class ProviderTester: """Classe per testare i provider di market data.""" - + def __init__(self): self.formatter = DemoFormatter() self.test_symbols = ["BTC", "ETH", "ADA"] - - def test_provider(self, wrapper: BaseWrapper, provider_name: str) -> Dict[str, Any]: + + def test_provider(self, wrapper: MarketWrapper, provider_name: str) -> Dict[str, Any]: """Testa un provider specifico con tutti i metodi disponibili.""" - results = { + results: Dict[str, Any] = { "provider_name": provider_name, "tests": {}, "overall_status": "SUCCESS" } - + self.formatter.print_subheader(f"๐Ÿ” Testing {provider_name}") - + # Test get_product for symbol in self.test_symbols: timestamp = datetime.now() @@ -153,13 +153,13 @@ class ProviderTester: ) if product: print(f"๐Ÿ“ฆ Product: {product.symbol} (ID: {product.id})") - print(f" Price: ${product.price:.2f}, Quote: {product.quote_currency}") + print(f" Price: ${product.price:.2f}, Quote: {product.currency}") print(f" Volume 24h: {product.volume_24h:,.2f}") else: print(f"๐Ÿ“ฆ Product: Nessun prodotto trovato per {symbol}") - + results["tests"][f"get_product_{symbol}"] = "SUCCESS" - + except Exception as e: error_msg = str(e) self.formatter.print_request_info( @@ -167,7 +167,7 @@ class ProviderTester: ) results["tests"][f"get_product_{symbol}"] = f"ERROR: {error_msg}" results["overall_status"] = "PARTIAL" - + # Test get_products timestamp = datetime.now() try: @@ -177,7 +177,7 @@ class ProviderTester: ) self.formatter.print_product_table(products, f"{provider_name} Products") results["tests"]["get_products"] = "SUCCESS" - + except Exception as e: error_msg = str(e) self.formatter.print_request_info( @@ -185,7 +185,7 @@ class ProviderTester: ) results["tests"]["get_products"] = f"ERROR: {error_msg}" results["overall_status"] = "PARTIAL" - + # Test get_historical_prices timestamp = datetime.now() try: @@ -195,7 +195,7 @@ class ProviderTester: ) self.formatter.print_prices_table(prices, f"{provider_name} BTC Historical Prices") results["tests"]["get_historical_prices"] = "SUCCESS" - + except Exception as e: error_msg = str(e) self.formatter.print_request_info( @@ -203,7 +203,7 @@ class ProviderTester: ) results["tests"]["get_historical_prices"] = f"ERROR: {error_msg}" results["overall_status"] = "PARTIAL" - + return results def check_environment_variables() -> Dict[str, bool]: @@ -217,11 +217,11 @@ def check_environment_variables() -> Dict[str, bool]: } return env_vars -def initialize_providers() -> Dict[str, BaseWrapper]: +def initialize_providers() -> Dict[str, MarketWrapper]: """Inizializza tutti i provider disponibili.""" - providers = {} + providers: Dict[str, MarketWrapper] = {} env_vars = check_environment_variables() - + # CryptoCompareWrapper if env_vars["CRYPTOCOMPARE_API_KEY"]: try: @@ -231,7 +231,7 @@ def initialize_providers() -> Dict[str, BaseWrapper]: print(f"โŒ Errore nell'inizializzazione di CryptoCompareWrapper: {e}") else: print("โš ๏ธ CryptoCompareWrapper saltato: CRYPTOCOMPARE_API_KEY non trovata") - + # CoinBaseWrapper if env_vars["COINBASE_API_KEY"] and env_vars["COINBASE_API_SECRET"]: try: @@ -241,14 +241,14 @@ def initialize_providers() -> Dict[str, BaseWrapper]: print(f"โŒ Errore nell'inizializzazione di CoinBaseWrapper: {e}") else: print("โš ๏ธ CoinBaseWrapper saltato: credenziali Coinbase non complete") - + # BinanceWrapper try: providers["Binance"] = BinanceWrapper() print("โœ… BinanceWrapper inizializzato con successo") except Exception as e: print(f"โŒ Errore nell'inizializzazione di BinanceWrapper: {e}") - + # YFinanceWrapper (sempre disponibile - dati azionari e crypto gratuiti) try: providers["YFinance"] = YFinanceWrapper() @@ -261,22 +261,22 @@ def print_summary(results: List[Dict[str, Any]]): """Stampa un riassunto finale dei risultati.""" formatter = DemoFormatter() formatter.print_header("๐Ÿ“Š RIASSUNTO FINALE", "=", 80) - + total_providers = len(results) successful_providers = sum(1 for r in results if r["overall_status"] == "SUCCESS") partial_providers = sum(1 for r in results if r["overall_status"] == "PARTIAL") - + print(f"๐Ÿ”ข Provider testati: {total_providers}") print(f"โœ… Provider completamente funzionanti: {successful_providers}") print(f"โš ๏ธ Provider parzialmente funzionanti: {partial_providers}") print(f"โŒ Provider non funzionanti: {total_providers - successful_providers - partial_providers}") - + print("\n๐Ÿ“‹ Dettaglio per provider:") for result in results: provider_name = result["provider_name"] status = result["overall_status"] status_icon = "โœ…" if status == "SUCCESS" else "โš ๏ธ" if status == "PARTIAL" else "โŒ" - + print(f"\n{status_icon} {provider_name}:") for test_name, test_result in result["tests"].items(): test_icon = "โœ…" if test_result == "SUCCESS" else "โŒ" @@ -285,39 +285,39 @@ def print_summary(results: List[Dict[str, Any]]): def main(): """Funzione principale del demo.""" formatter = DemoFormatter() - + # Intestazione principale formatter.print_header("๐Ÿš€ DEMO COMPLETO MARKET DATA PROVIDERS", "=", 80) - + print(f"๐Ÿ•’ Avvio demo: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") print("๐Ÿ“ Questo demo testa tutti i wrapper BaseWrapper disponibili") print("๐Ÿ” Ogni test include timestamp, stato della richiesta e dati formattati") - + # Verifica variabili d'ambiente formatter.print_subheader("๐Ÿ” Verifica Configurazione") env_vars = check_environment_variables() - + print("Variabili d'ambiente:") for var_name, is_present in env_vars.items(): status = "โœ… Presente" if is_present else "โŒ Mancante" print(f" {var_name}: {status}") - + # Inizializza provider formatter.print_subheader("๐Ÿ—๏ธ Inizializzazione Provider") providers = initialize_providers() - + if not providers: print("โŒ Nessun provider disponibile. Verifica la configurazione.") return - + print(f"\n๐ŸŽฏ Provider disponibili per il test: {list(providers.keys())}") - + # Testa ogni provider formatter.print_header("๐Ÿงช ESECUZIONE TEST PROVIDER", "=", 80) - + tester = ProviderTester() - all_results = [] - + all_results: List[Dict[str, Any]] = [] + for provider_name, wrapper in providers.items(): try: result = tester.test_provider(wrapper, provider_name) @@ -331,22 +331,22 @@ def main(): "overall_status": "CRITICAL_ERROR", "error": str(e) }) - + # Stampa riassunto finale print_summary(all_results) - + # Informazioni aggiuntive formatter.print_header("โ„น๏ธ INFORMAZIONI AGGIUNTIVE", "=", 80) print("๐Ÿ“š Documentazione:") print(" - BaseWrapper: src/app/markets/base.py") print(" - Test completi: tests/agents/test_market.py") print(" - Configurazione: .env") - + print("\n๐Ÿ”ง Per abilitare tutti i provider:") print(" 1. Configura le credenziali nel file .env") print(" 2. Segui la documentazione di ogni provider") print(" 3. Riavvia il demo") - + print(f"\n๐Ÿ Demo completato: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") if __name__ == "__main__": diff --git a/demos/news_api.py b/demos/news_api.py index 26dab24..1497a15 100644 --- a/demos/news_api.py +++ b/demos/news_api.py @@ -9,6 +9,8 @@ from app.news import NewsApiWrapper def main(): api = NewsApiWrapper() + articles = api.get_latest_news(query="bitcoin", limit=5) + assert len(articles) > 0 print("ok") if __name__ == "__main__": diff --git a/src/app/agents/models.py b/src/app/agents/models.py index b2d23ca..79d4a26 100644 --- a/src/app/agents/models.py +++ b/src/app/agents/models.py @@ -1,5 +1,5 @@ import os -import requests +import ollama from enum import Enum from agno.agent import Agent from agno.models.base import Model @@ -30,19 +30,15 @@ class AppModels(Enum): Controlla quali provider di modelli LLM locali sono disponibili. Ritorna una lista di provider disponibili. """ - ollama_host = os.getenv("OLLAMA_HOST", "http://localhost:11434") - result = requests.get(f"{ollama_host}/api/tags") - if result.status_code != 200: - log_warning(f"Ollama is not running or not reachable {result}") + try: + models_list = ollama.list() + availables = [model['model'] for model in models_list['models']] + app_models = [model for model in AppModels if model.name.startswith("OLLAMA")] + return [model for model in app_models if model.value in availables] + except Exception as e: + log_warning(f"Ollama is not running or not reachable: {e}") return [] - availables: list[AppModels] = [] - result = result.text - for model in [model for model in AppModels if model.name.startswith("OLLAMA")]: - if model.value in result: - availables.append(model) - return availables - @staticmethod def availables_online() -> list['AppModels']: """ diff --git a/src/app/agents/team.py b/src/app/agents/team.py index 01ad5cf..27b9cae 100644 --- a/src/app/agents/team.py +++ b/src/app/agents/team.py @@ -29,7 +29,6 @@ def create_team_with(models: AppModels, coordinator: AppModels | None = None) -> members=[market_agent, news_agent, social_agent], ) -# TODO: migliorare le istruzioni del team COORDINATOR_INSTRUCTIONS = """ You are the expert coordinator of a financial analysis team specializing in cryptocurrencies.