Spaces:
Sleeping
Sleeping
| from smolagents import CodeAgent, HfApiModel, load_tool, tool | |
| import datetime | |
| import requests | |
| import pytz | |
| import yaml | |
| import os | |
| from dotenv import load_dotenv | |
| from tools.final_answer import FinalAnswerTool | |
| from Gradio_UI import GradioUI | |
| # Load environment variables | |
| load_dotenv() | |
| # API Configuration | |
| THERUNDOWN_API_KEY = os.getenv('THERUNDOWN_API_KEY') | |
| if not THERUNDOWN_API_KEY: | |
| raise ValueError("THERUNDOWN_API_KEY not found in environment variables") | |
| def get_current_time_in_timezone(timezone: str) -> str: | |
| """ | |
| A tool that fetches the current local time in a specified timezone. | |
| Args: | |
| timezone: A valid timezone string (e.g., 'America/New_York'). | |
| """ | |
| try: | |
| tz = pytz.timezone(timezone) | |
| local_time = datetime.datetime.now(tz).strftime("%Y-%m-%d %H:%M:%S") | |
| return f"The current local time in {timezone} is: {local_time}" | |
| except Exception as e: | |
| return f"Error fetching time for timezone '{timezone}': {str(e)}" | |
| def get_nba_matches(target_date: str = None) -> str: | |
| """ | |
| A tool that retrieves upcoming NBA matches using TheRundown API. | |
| Uses the /openers endpoint for the specified date. | |
| Args: | |
| target_date: Optional date string in YYYY-MM-DD format. If not provided, uses today's date. | |
| Returns: | |
| A human-readable string listing the upcoming NBA matches with detailed odds information. | |
| For special events like the All-Star Game, includes additional event details. | |
| """ | |
| import requests | |
| import datetime | |
| from typing import Dict, Any | |
| import json | |
| # Use provided date or today's date | |
| if target_date is None: | |
| target_date = datetime.date.today().strftime("%Y-%m-%d") | |
| # API configuration | |
| url = f"https://api.apilayer.com/therundown/sports/4/openers/{target_date}" | |
| params = { | |
| "offset": "0", | |
| "include": "scores" | |
| } | |
| headers = { | |
| "apikey": THERUNDOWN_API_KEY | |
| } | |
| try: | |
| response = requests.get(url, headers=headers, params=params) | |
| response.raise_for_status() | |
| data = response.json() | |
| if not data.get("events"): | |
| return f"No NBA matches found for {target_date}." | |
| matches = [] | |
| is_special_event = False | |
| event_type = "Regular Season" | |
| for event in data["events"]: | |
| # Extract event date and time | |
| event_date = event.get("event_date", "N/A") | |
| if event_date != "N/A": | |
| try: | |
| dt = datetime.datetime.strptime(event_date, "%Y-%m-%dT%H:%M:%SZ") | |
| event_date = dt.strftime("%Y-%m-%d %H:%M UTC") | |
| except ValueError: | |
| pass | |
| # Get schedule information | |
| schedule = event.get("schedule", {}) | |
| event_headline = schedule.get("event_headline", "") | |
| # Check if this is a special event | |
| if "All-Star" in event_headline: | |
| is_special_event = True | |
| event_type = "NBA All-Star Game" | |
| # Extract basic game info | |
| teams = event.get("teams_normalized", []) | |
| if not teams: | |
| teams = event.get("teams", []) | |
| if len(teams) < 2: | |
| continue | |
| away_team = teams[0] if teams[0].get("is_away") else teams[1] | |
| home_team = teams[1] if teams[0].get("is_away") else teams[0] | |
| # Get the lines info (odds) | |
| lines = event.get("lines", {}) | |
| # Try different bookmakers in order of preference | |
| bookmaker = None | |
| for bookmaker_id in ["3", "2", "12", "22", "23"]: | |
| if bookmaker_id in lines: | |
| bookmaker = lines[bookmaker_id] | |
| break | |
| if not bookmaker: | |
| bookmaker = next(iter(lines.values())) if lines else {} | |
| # Extract odds information | |
| spread_info = bookmaker.get("spread", {}) | |
| total_info = bookmaker.get("total", {}) | |
| moneyline_info = bookmaker.get("moneyline", {}) | |
| # Get venue and broadcast information | |
| score_info = event.get("score", {}) | |
| venue_name = score_info.get("venue_name", "N/A") | |
| venue_location = score_info.get("venue_location", "N/A") | |
| broadcast = score_info.get("broadcast", "N/A") | |
| # Format game information | |
| game_info = [] | |
| # Add event type header if it's a special event | |
| if is_special_event and event_headline: | |
| game_info.extend([ | |
| "🏀 " + "=" * 30 + " NBA ALL-STAR GAME " + "=" * 30 + " 🏀", | |
| f"Event: {event_headline}", | |
| f"Date: {event_date}", | |
| ]) | |
| else: | |
| game_info.extend([ | |
| "🏀 " + "=" * 35 + " NBA GAME " + "=" * 35 + " 🏀", | |
| f"Date: {event_date}", | |
| ]) | |
| # Add team information | |
| game_info.append( | |
| f"Teams: {away_team.get('name', 'Unknown')} vs {home_team.get('name', 'Unknown')}" | |
| ) | |
| # Add venue and broadcast | |
| game_info.extend([ | |
| f"Venue: {venue_name} ({venue_location})", | |
| f"Broadcast: {broadcast}", | |
| ]) | |
| # Add betting information if available | |
| if any(v != 0.0001 for v in [ | |
| moneyline_info.get("moneyline_away", 0), | |
| moneyline_info.get("moneyline_home", 0), | |
| spread_info.get("point_spread_away", 0), | |
| total_info.get("total_over", 0) | |
| ]): | |
| game_info.append("\nBetting Lines:") | |
| if moneyline_info.get("moneyline_away", 0) != 0.0001: | |
| game_info.append( | |
| f"Moneyline: {away_team.get('name')} ({moneyline_info.get('moneyline_away', 'N/A')}) | " | |
| f"{home_team.get('name')} ({moneyline_info.get('moneyline_home', 'N/A')})" | |
| ) | |
| if spread_info.get("point_spread_away", 0) != 0.0001: | |
| game_info.append( | |
| f"Spread: {away_team.get('name')} {spread_info.get('point_spread_away', 'N/A')} " | |
| f"({spread_info.get('point_spread_away_money', 'N/A')})" | |
| ) | |
| if total_info.get("total_over", 0) != 0.0001: | |
| game_info.append( | |
| f"Total: O/U {total_info.get('total_over', 'N/A')} " | |
| f"(Over: {total_info.get('total_over_money', 'N/A')} | " | |
| f"Under: {total_info.get('total_under_money', 'N/A')})" | |
| ) | |
| game_info.append("=" * 80) | |
| matches.append("\n".join(game_info)) | |
| if matches: | |
| # Create a detailed response with all match information | |
| response = [ | |
| f"\n🏀 NBA Schedule for {target_date} - {event_type} 🏀", | |
| "=" * 80, | |
| "", # Empty line for better readability | |
| "\n\n".join(matches) # All match details | |
| ] | |
| matches_str = "\n".join(response) | |
| # Print for execution logs and return the same string | |
| print(f"NBA Matches for {target_date}:\n{matches_str}") | |
| return matches_str | |
| else: | |
| no_matches_msg = f"No NBA matches found with complete information for {target_date}." | |
| print(no_matches_msg) | |
| return no_matches_msg | |
| except requests.exceptions.RequestException as e: | |
| error_msg = f"Error retrieving NBA matches: {str(e)}" | |
| print(error_msg) | |
| return error_msg | |
| except (KeyError, json.JSONDecodeError) as e: | |
| error_msg = f"Error parsing NBA data: {str(e)}" | |
| print(error_msg) | |
| return error_msg | |
| def predict_nba_match(match_info: str) -> str: | |
| """ | |
| A tool that generates a prediction for an NBA match. | |
| Args: | |
| match_info: A string containing match details in the format "TeamA vs TeamB". | |
| Returns: | |
| A string with the prediction (e.g., "The prediction is that TeamA will win."). | |
| """ | |
| import random | |
| teams = match_info.split(" vs ") | |
| if len(teams) == 2: | |
| prediction = random.choice(teams) | |
| return f"The prediction is that {prediction} will win." | |
| else: | |
| return "Invalid match format. Please provide details in the format 'TeamA vs TeamB'." | |
| # Instantiate the final_answer tool. | |
| final_answer = FinalAnswerTool() | |
| # Configure the model. | |
| model = HfApiModel( | |
| max_tokens=2096, | |
| temperature=0.5, | |
| model_id='Qwen/Qwen2.5-Coder-32B-Instruct', | |
| custom_role_conversions=None, | |
| ) | |
| # Load prompt templates. | |
| with open("prompts.yaml", 'r') as stream: | |
| prompt_templates = yaml.safe_load(stream) | |
| # Initialize the agent with all necessary tools. | |
| agent = CodeAgent( | |
| model=model, | |
| tools=[final_answer, get_current_time_in_timezone, get_nba_matches, predict_nba_match], | |
| max_steps=6, | |
| verbosity_level=2, # Increased verbosity to show more details | |
| grammar=None, | |
| planning_interval=None, | |
| name="NBA Match Assistant", | |
| description="An assistant that provides detailed NBA match information and predictions", | |
| prompt_templates=prompt_templates | |
| ) | |
| # Use the existing Gradio UI configuration | |
| gradio_ui = GradioUI(agent) | |
| gradio_ui.launch() |