from smolagents import CodeAgent, HfApiModel, load_tool, tool from dotenv import load_dotenv import datetime import requests import base64 from requests import post, get import os import pytz import yaml import json from urllib.parse import urlencode import typing from typing import List, Dict, Optional from tools.final_answer import FinalAnswerTool from tools.web_search import DuckDuckGoSearchTool from Gradio_UI import GradioUI Any = typing.Any @tool def search_youtube_guitar_tutorials(song_name: str) -> List[Dict[str, Any]]: """Searches YouTube for guitar tutorials for a specific song. Args: song_name: The name of the song to search for guitar tutorials Returns: A list of dictionaries containing information about the tutorials found, including title, channel name, view count, and URL. """ api_key = os.getenv("YOUTUBE_API_KEY") if not api_key: raise ValueError("YouTube API key not found. Please set the YOUTUBE_API_KEY environment variable.") base_url = "https://www.googleapis.com/youtube/v3/search" search_params = { 'part': 'snippet', 'q': f"{song_name} guitar tutorial how to play", 'type': 'video', 'videoDefinition': 'high', 'order': 'relevance', 'maxResults': 10, 'key': api_key } search_url = f"{base_url}?{urlencode(search_params)}" try: search_response = requests.get(search_url) search_response.raise_for_status() search_data = search_response.json() # Get video IDs video_ids = [item['id']['videoId'] for item in search_data.get('items', [])] if not video_ids: return [] # Get video details (including view counts) video_url = "https://www.googleapis.com/youtube/v3/videos" video_params = { 'part': 'snippet,statistics', 'id': ','.join(video_ids), 'key': api_key } video_details_url = f"{video_url}?{urlencode(video_params)}" video_response = requests.get(video_details_url) video_response.raise_for_status() video_data = video_response.json() # Filter for actual guitar tutorials tutorial_keywords = ['tutorial', 'lesson', 'how to play', 'guitar cover', 'chords', 'tabs'] filtered_items = [] for item in video_data.get('items', []): title_lower = item['snippet']['title'].lower() if any(keyword in title_lower for keyword in tutorial_keywords): filtered_items.append(item) # Sort by views if we have enough tutorials if len(filtered_items) >= 3: filtered_items.sort(key=lambda x: int(x['statistics'].get('viewCount', 0)), reverse=True) if not filtered_items: return "No guitar tutorials found." formatted_results = ["Here are the top guitar tutorials:"] for i, item in enumerate(filtered_items[:3], 1): views = int(item['statistics'].get('viewCount', 0)) formatted_views = f"{views:,}" if views > 0 else "N/A" formatted_results.append( f"\n{i}. {item['snippet']['title']}\n" f" Channel: {item['snippet']['channelTitle']}\n" f" Views: {formatted_views}\n" f" Link: https://www.youtube.com/watch?v={item['id']}\n" ) return "\n".join(formatted_results) except requests.exceptions.RequestException as e: print(f"Error searching YouTube: {e}") return [] # Initialize tools final_answer = FinalAnswerTool() # Initialize model with alternative endpoint model = HfApiModel( max_tokens=2096, temperature=0.5, model_id='Qwen/Qwen2.5-Coder-32B-Instruct', custom_role_conversions=None, ) # Load prompts with open("prompts.yaml", 'r') as stream: prompt_templates = yaml.safe_load(stream) # Initialize agent agent = CodeAgent( model=model, tools=[ search_youtube_guitar_tutorials, final_answer ], max_steps=6, verbosity_level=1, grammar=None, planning_interval=None, name=None, description=None, prompt_templates=prompt_templates ) # Launch UI GradioUI(agent).launch()