Spaces:
Sleeping
Sleeping
| import json | |
| from smolagents import CodeAgent, tool, LiteLLMModel | |
| import requests | |
| import yaml | |
| import os | |
| from collections import defaultdict | |
| from tools.final_answer import FinalAnswerTool | |
| import gradio as gr | |
| def get_pokedex_entry(pokemon_name: str) -> str: | |
| """ | |
| Fetches the English Pokédex entry (flavor text) for the given Pokémon. | |
| Args: | |
| pokemon_name: Name or ID of the Pokémon (e.g., 'pikachu'). | |
| Returns: | |
| A string containing the Pokémon's English Pokédex entry or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon-species/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| flavor_texts = [ | |
| entry["flavor_text"] | |
| for entry in data.get("flavor_text_entries", []) | |
| if entry["language"]["name"] == "en" | |
| ] | |
| if not flavor_texts: | |
| return f"No English Pokédex entry available for '{pokemon_name}'." | |
| entry = flavor_texts[0].replace("\n", " ").replace("\f", " ") | |
| title = pokemon_name.strip().title() | |
| return f"{title}: {entry}" | |
| def get_pokemon_basic_info(pokemon_name: str) -> str: | |
| """ | |
| Fetches basic information about a Pokémon, such as its ID, height, weight, and types. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon (e.g., 'pikachu'). | |
| Returns: | |
| A string summarizing the Pokémon's ID, height, weight, and types, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| types = ', '.join([t['type']['name'].title() for t in data.get('types', [])]) | |
| return ( | |
| f"{data['name'].title()} (ID: {data['id']}):\n" | |
| f"Height: {data['height']} Weight: {data['weight']}\n" | |
| f"Types: {types}" | |
| ) | |
| def get_pokemon_abilities(pokemon_name: str) -> str: | |
| """ | |
| Retrieves a list of abilities for a given Pokémon, distinguishing between normal and hidden abilities. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing the Pokémon's abilities, labeled as Normal or Hidden, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| abilities = [] | |
| for ability_info in data.get('abilities', []): | |
| ability_name = ability_info['ability']['name'].replace('-', ' ').title() | |
| label = "Hidden" if ability_info.get('is_hidden', False) else "Normal" | |
| abilities.append(f"{ability_name} ({label})") | |
| if not abilities: | |
| return f"No abilities found for '{pokemon_name}'." | |
| return f"{pokemon_name.title()}'s abilities:\n" + "\n".join(abilities) | |
| def get_pokemon_base_stats(pokemon_name: str) -> str: | |
| """ | |
| Fetches the base stats (HP, Attack, Defense, etc.) of a Pokémon. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string summarizing the Pokémon's base stats or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| stats = {s['stat']['name'].replace('-', ' ').title(): s['base_stat'] for s in data.get('stats', [])} | |
| if not stats: | |
| return f"No base stats found for '{pokemon_name}'." | |
| stats_str = ', '.join([f"{k}: {v}" for k, v in stats.items()]) | |
| return f"{pokemon_name.title()}'s base stats: {stats_str}" | |
| def get_pokemon_evolutions(pokemon_name: str) -> str: | |
| """ | |
| Retrieves the evolution chain for a given Pokémon. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing the evolution chain or an error message. | |
| """ | |
| species_url = f"https://pokeapi.co/api/v2/pokemon-species/{pokemon_name.strip().lower()}/" | |
| species_response = requests.get(species_url, timeout=5) | |
| if species_response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {species_response.status_code})." | |
| species_data = species_response.json() | |
| evo_chain_url = species_data.get('evolution_chain', {}).get('url') | |
| if not evo_chain_url: | |
| return f"No evolution chain found for '{pokemon_name}'." | |
| evo_response = requests.get(evo_chain_url, timeout=5) | |
| if evo_response.status_code != 200: | |
| return f"Error fetching evolution chain (HTTP {evo_response.status_code})." | |
| evo_data = evo_response.json() | |
| def extract_chain(chain): | |
| names = [chain['species']['name'].title()] | |
| for evo in chain.get('evolves_to', []): | |
| names.extend(extract_chain(evo)) | |
| return names | |
| evo_names = extract_chain(evo_data['chain']) | |
| return f"Evolution chain: {' → '.join(evo_names)}" | |
| def get_pokemon_moves_grouped(pokemon_name: str) -> str: | |
| """ | |
| Lists all moves a Pokémon can learn, grouped by move name, showing the minimum level, | |
| all learning methods, and all game versions. Egg moves are listed separately. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing the Pokémon's moves, grouped by name, with levels, methods, and versions. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| moves_dict = defaultdict(lambda: {'level': None, 'versions': set(), 'methods': set()}) | |
| egg_moves_dict = defaultdict(set) | |
| for move in data.get('moves', []): | |
| move_name = move['move']['name'].replace('-', ' ').title() | |
| for detail in move.get('version_group_details', []): | |
| method = detail['move_learn_method']['name'].replace('-', ' ').title() | |
| version = detail['version_group']['name'].replace('-', ' ').title() | |
| level = detail['level_learned_at'] | |
| if method == "Egg": | |
| egg_moves_dict[move_name].add(version) | |
| else: | |
| moves_dict[move_name]['methods'].add(method) | |
| moves_dict[move_name]['versions'].add(version) | |
| if method == "Level Up" and ( | |
| moves_dict[move_name]['level'] is None or level < moves_dict[move_name]['level']): | |
| moves_dict[move_name]['level'] = level | |
| moves_lines = [] | |
| for move_name, info in sorted(moves_dict.items()): | |
| versions_str = ', '.join(sorted(info['versions'])) | |
| methods_str = ', '.join(sorted(info['methods'])) | |
| if info['level'] is not None: | |
| moves_lines.append(f"{move_name} (Level {info['level']}, Versions: {versions_str})") | |
| else: | |
| moves_lines.append(f"{move_name} (Methods: {methods_str}, Versions: {versions_str})") | |
| egg_lines = [f"{move_name} (Egg Move in: {', '.join(sorted(versions))})" for move_name, versions in | |
| sorted(egg_moves_dict.items())] | |
| moves_preview = '\n'.join(moves_lines[:20]) | |
| more_moves = f"\n...and {len(moves_lines) - 20} more moves." if len(moves_lines) > 20 else "" | |
| egg_moves_output = '\n'.join(egg_lines) if egg_lines else 'None' | |
| return ( | |
| f"{pokemon_name.title()} can learn these moves grouped by name with versions and levels:\n" | |
| f"{moves_preview}{more_moves}\n\n" | |
| f"Egg moves:\n{egg_moves_output}" | |
| ) | |
| def get_pokemon_sprite(pokemon_name: str) -> str: | |
| """ | |
| Fetches the default front sprite URL for a Pokémon. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string containing the sprite URL or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| sprite_url = data.get('sprites', {}).get('front_default') | |
| if not sprite_url: | |
| return f"No sprite found for '{pokemon_name}'." | |
| return f"{pokemon_name.title()} sprite: {sprite_url}" | |
| def get_pokemon_held_items(pokemon_name: str) -> str: | |
| """ | |
| Fetches the items a Pokémon can hold in the wild, including rarity and game versions. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing the Pokémon's held items, their rarity, and versions, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| held_items = data.get('held_items', []) | |
| if not held_items: | |
| return f"No held items found for '{pokemon_name}'." | |
| item_lines = [] | |
| for item in held_items: | |
| item_name = item['item']['name'].replace('-', ' ').title() | |
| versions = ', '.join([v['version']['name'].title() for v in item['version_details']]) | |
| rarity = item['version_details'][0]['rarity'] | |
| item_lines.append(f"{item_name} (Rarity: {rarity}%, Versions: {versions})") | |
| return f"{pokemon_name.title()}'s held items:\n" + "\n".join(item_lines) | |
| def get_pokemon_encounter_locations(pokemon_name: str) -> str: | |
| """ | |
| Fetches the locations where a Pokémon can be encountered in different game versions. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing the Pokémon's encounter locations by game version, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| encounters_url = data.get('location_area_encounters') | |
| if not encounters_url: | |
| return f"No encounter data found for '{pokemon_name}'." | |
| response = requests.get(encounters_url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error fetching encounter data (HTTP {response.status_code})." | |
| encounters = response.json() | |
| location_dict = defaultdict(list) | |
| for encounter in encounters: | |
| location = encounter['location_area']['name'].replace('-', ' ').title() | |
| for version_detail in encounter['version_details']: | |
| version = version_detail['version']['name'].title() | |
| location_dict[version].append(location) | |
| output = [] | |
| for version, locations in sorted(location_dict.items()): | |
| locations_str = ', '.join(sorted(set(locations))) | |
| output.append(f"{version}: {locations_str}") | |
| if not output: | |
| return f"No encounter locations found for '{pokemon_name}'." | |
| return f"{pokemon_name.title()}'s encounter locations:\n" + "\n".join(output) | |
| def get_pokemon_type_effectiveness(pokemon_name: str) -> str: | |
| """ | |
| Fetches the type effectiveness (weaknesses, resistances, immunities) for a Pokémon's types. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string summarizing the Pokémon's type effectiveness, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| types = [t['type']['url'] for t in data.get('types', [])] | |
| effectiveness = {'2x': set(), '0.5x': set(), '0x': set()} | |
| for type_url in types: | |
| response = requests.get(type_url, timeout=5) | |
| if response.status_code != 200: | |
| continue | |
| type_data = response.json() | |
| damage_relations = type_data['damage_relations'] | |
| for t in damage_relations['double_damage_from']: | |
| effectiveness['2x'].add(t['name'].title()) | |
| for t in damage_relations['half_damage_from']: | |
| effectiveness['0.5x'].add(t['name'].title()) | |
| for t in damage_relations['no_damage_from']: | |
| effectiveness['0x'].add(t['name'].title()) | |
| output = [] | |
| for key, types in effectiveness.items(): | |
| if types: | |
| output.append(f"{key}: {', '.join(sorted(types))}") | |
| if not output: | |
| return f"No type effectiveness data found for '{pokemon_name}'." | |
| return f"{pokemon_name.title()}'s type effectiveness:\n" + "\n".join(output) | |
| def get_pokemon_ability_description(pokemon_name: str) -> str: | |
| """ | |
| Fetches the descriptions of a Pokémon's abilities from the ability endpoint. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string listing each ability and its English description, or an error message. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/pokemon/{name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Pokémon '{pokemon_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| abilities = data.get('abilities', []) | |
| output = [] | |
| for ability_info in abilities: | |
| ability_name = ability_info['ability']['name'].replace('-', ' ').title() | |
| label = "Hidden" if ability_info['is_hidden'] else "Normal" | |
| ability_url = ability_info['ability']['url'] | |
| response = requests.get(ability_url, timeout=5) | |
| if response.status_code != 200: | |
| continue | |
| ability_data = response.json() | |
| effect = next((e['effect'] for e in ability_data['effect_entries'] if e['language']['name'] == 'en'), | |
| 'No description available.') | |
| output.append(f"{ability_name} ({label}): {effect}") | |
| if not output: | |
| return f"No ability descriptions found for '{pokemon_name}'." | |
| return f"{pokemon_name.title()}'s ability descriptions:\n" + "\n".join(output) | |
| def list_pokemon_by_type(type_name: str, limit: int = 10) -> str: | |
| """ | |
| Lists Pokémon that have a specific type, up to a specified limit. | |
| Args: | |
| type_name: The name of the type (e.g., 'normal'). | |
| limit: Maximum number of Pokémon to list (default: 10). | |
| Returns: | |
| A string listing Pokémon with the specified type, or an error message. | |
| """ | |
| type_name = type_name.strip().lower() | |
| url = f"https://pokeapi.co/api/v2/type/{type_name}/" | |
| response = requests.get(url, timeout=5) | |
| if response.status_code != 200: | |
| return f"Error: Type '{type_name}' not found (HTTP {response.status_code})." | |
| data = response.json() | |
| pokemon_list = [p['pokemon']['name'].title() for p in data.get('pokemon', [])][:limit] | |
| if not pokemon_list: | |
| return f"No Pokémon found with type '{type_name}'." | |
| return f"Pokémon with {type_name.title()} type (up to {limit}):\n" + "\n".join(pokemon_list) | |
| def get_pokemon_full_profile(pokemon_name: str) -> str: | |
| """ | |
| Fetches a complete profile for a Pokémon, including all available data. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string with a comprehensive Pokémon profile. | |
| """ | |
| name = pokemon_name.strip().lower() | |
| profile = [ | |
| get_pokedex_entry(pokemon_name=name), | |
| get_pokemon_basic_info(pokemon_name=name), | |
| get_pokemon_abilities(pokemon_name=name), | |
| get_pokemon_base_stats(pokemon_name=name), | |
| get_pokemon_evolutions(pokemon_name=name), | |
| get_pokemon_moves_grouped(pokemon_name=name), | |
| get_pokemon_held_items(pokemon_name=name), | |
| get_pokemon_encounter_locations(pokemon_name=name), | |
| get_pokemon_type_effectiveness(pokemon_name=name), | |
| get_pokemon_ability_description(pokemon_name=name), | |
| get_pokemon_sprite(pokemon_name=name) | |
| ] | |
| return f"{name.title()} Profile:\n\n" + "\n\n".join(profile) | |
| def get_pokemon_evolution_visual(pokemon_name: str) -> str: | |
| """ | |
| Fetches the evolution chain for a Pokémon and generates an HTML visualization with sprites and basic info. | |
| This tool should be called directly without any code generation. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string with the evolution chain and instructions to view the HTML visualization. | |
| """ | |
| def generate_evolution_html(pokemon_name: str, evolution_data: list) -> str: | |
| html_template = """ | |
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>{title} Evolution Chain</title> | |
| <style> | |
| body {{ | |
| font-family: Arial, sans-serif; | |
| text-align: center; | |
| }} | |
| h1 {{ | |
| color: #121212; | |
| }} | |
| .evolution-container {{ | |
| display: flex; | |
| justify-content: center; | |
| gap: 20px; | |
| margin: 20px; | |
| color: #121212; | |
| }} | |
| .pokemon {{ | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| background-color: #fff; | |
| padding: 10px; | |
| border-radius: 10px; | |
| box-shadow: 0 0 10px rgba(0,0,0,0.1); | |
| }} | |
| .pokemon img {{ | |
| width: 100px; | |
| height: 100px; | |
| }} | |
| .pokemon p {{ | |
| margin: 5px 0; | |
| font-weight: bold; | |
| color: #121212 !important; | |
| }} | |
| </style> | |
| </head> | |
| <body> | |
| <h1>{title} Evolution Chain</h1> | |
| <div class="evolution-container"> | |
| {pokemon_entries} | |
| </div> | |
| </body> | |
| </html> | |
| """ | |
| pokemon_entries = "" | |
| for name, sprite_url, info in evolution_data: | |
| pokemon_entries += f""" | |
| <div class="pokemon"> | |
| <p>{name}</p> | |
| <img src="{sprite_url}" alt="{name}"> | |
| <p>{info}</p> | |
| </div> | |
| """ | |
| return html_template.format(title=pokemon_name.title(), pokemon_entries=pokemon_entries) | |
| evolution_chain = get_pokemon_evolutions(pokemon_name=pokemon_name) | |
| if "Error" in evolution_chain or "No evolution chain" in evolution_chain: | |
| return evolution_chain | |
| names = [name.strip().title() for name in evolution_chain.replace("Evolution chain: ", "").split("→")] | |
| evolution_data = [] | |
| for name in names: | |
| sprite_result = get_pokemon_sprite(pokemon_name=name.lower()) | |
| sprite_url = sprite_result.split(": ")[1] if "sprite:" in sprite_result else "https://via.placeholder.com/100" | |
| info_result = get_pokemon_basic_info(pokemon_name=name.lower()) | |
| info = info_result.replace(f"{name} (", "(").replace("\n", | |
| ", ") if "Error" not in info_result else "No info available" | |
| evolution_data.append((name, sprite_url, info)) | |
| html_content = generate_evolution_html(pokemon_name, evolution_data) | |
| html_filename = f"{pokemon_name.lower()}_evolution.html" | |
| with open(html_filename, "w", encoding="utf-8") as f: | |
| f.write(html_content) | |
| return ( | |
| f"{evolution_chain}\n\n" | |
| f"Evolution visualization saved to '{html_filename}'.\n" | |
| f"The HTML shows each stage with its sprite and basic info (ID, height, weight, types)." | |
| ) | |
| def get_evolution_stats_chart(pokemon_name: str) -> str: | |
| """ | |
| Generates a Chart.js radar chart comparing base stats for a Pokémon's evolution chain. | |
| This tool should be called directly without any code generation. | |
| Args: | |
| pokemon_name: The name or ID of the Pokémon. | |
| Returns: | |
| A string with instructions to view the chart JSON. | |
| """ | |
| evolution_chain = get_pokemon_evolutions(pokemon_name=pokemon_name) | |
| if "Error" in evolution_chain or "No evolution chain" in evolution_chain: | |
| return evolution_chain | |
| names = [name.strip().title() for name in evolution_chain.replace("Evolution chain: ", "").split("→")] | |
| datasets = [] | |
| colors = [ | |
| {"bg": "rgba(255, 206, 86, 0.2)", "border": "rgba(255, 206, 86, 1)"}, | |
| {"bg": "rgba(255, 99, 132, 0.2)", "border": "rgba(255, 99, 132, 1)"}, | |
| {"bg": "rgba(54, 162, 235, 0.2)", "border": "rgba(54, 162, 235, 1)"} | |
| ] | |
| for idx, name in enumerate(names): | |
| stats_result = get_pokemon_base_stats(pokemon_name=name.lower()) | |
| if "Error" in stats_result: | |
| continue | |
| stats_dict = {k.split(": ")[0]: int(k.split(": ")[1]) for k in stats_result.split(": ", 1)[1].split(", ")} | |
| stats_data = [ | |
| stats_dict.get("Hp", 0), | |
| stats_dict.get("Attack", 0), | |
| stats_dict.get("Defense", 0), | |
| stats_dict.get("Special Attack", 0), | |
| stats_dict.get("Special Defense", 0), | |
| stats_dict.get("Speed", 0) | |
| ] | |
| datasets.append({ | |
| "label": name, | |
| "data": stats_data, | |
| "backgroundColor": colors[idx % len(colors)]["bg"], | |
| "borderColor": colors[idx % len(colors)]["border"], | |
| "borderWidth": 1 | |
| }) | |
| chart_config = { | |
| "type": "radar", | |
| "data": { | |
| "labels": ["HP", "Attack", "Defense", "Special Attack", "Special Defense", "Speed"], | |
| "datasets": datasets | |
| }, | |
| "options": { | |
| "scales": { | |
| "r": { | |
| "beginAtZero": True, | |
| "max": 150 | |
| } | |
| }, | |
| "plugins": { | |
| "title": { | |
| "display": True, | |
| "text": f"{pokemon_name.title()} Evolution Chain Base Stats" | |
| } | |
| } | |
| } | |
| } | |
| chart_filename = f"{pokemon_name.lower()}_evolution_stats.json" | |
| with open(chart_filename, "w") as f: | |
| json.dump(chart_config, f, indent=2) | |
| return f"Radar chart for {pokemon_name.title()}'s evolution chain stats saved to '{chart_filename}'." | |
| final_answer = FinalAnswerTool() | |
| model = LiteLLMModel( | |
| model_id="ollama_chat/qwen2:7b", | |
| api_base="http://127.0.0.1:11434", | |
| num_ctx=8192, | |
| ) | |
| # Create improved prompt templates | |
| improved_prompts = { | |
| "system_prompt": """You are a helpful Pokémon information assistant. You have access to many tools to get Pokémon data. | |
| IMPORTANT INSTRUCTIONS: | |
| 1. Always use the available tools directly - never try to write code or import modules | |
| 2. When asked to call get_pokemon_evolution_visual or get_evolution_stats_chart, call those tools directly | |
| 3. Never attempt to write Python code, import statements, or create visualizations yourself | |
| 4. Simply call the appropriate tool function with the pokemon name as argument | |
| 5. Return the result from the tool call as your final answer | |
| Available tools: | |
| - get_pokemon_evolution_visual: Creates HTML evolution visualization | |
| - get_evolution_stats_chart: Creates radar chart comparing evolution stats | |
| - get_pokemon_basic_info: Gets basic Pokémon info | |
| - get_pokemon_evolutions: Gets evolution chain | |
| - get_pokemon_base_stats: Gets base stats | |
| - And many more Pokémon data tools | |
| When a user asks you to use a specific tool, call that tool directly.""", | |
| "user_prompt": """Human request: {task} | |
| Remember: Use the available tools directly. Do not write code or try to import anything.""", | |
| "code_execution_system_prompt": """You are a helpful assistant that can execute code to help users. When executing code, be direct and use available tools without attempting to import external modules.""" | |
| } | |
| agent = CodeAgent( | |
| model=model, | |
| tools=[ | |
| final_answer, | |
| get_pokedex_entry, | |
| get_pokemon_basic_info, | |
| get_pokemon_abilities, | |
| get_pokemon_base_stats, | |
| get_pokemon_evolutions, | |
| get_pokemon_moves_grouped, | |
| get_pokemon_sprite, | |
| get_pokemon_held_items, | |
| get_pokemon_encounter_locations, | |
| get_pokemon_type_effectiveness, | |
| get_pokemon_ability_description, | |
| list_pokemon_by_type, | |
| get_pokemon_full_profile, | |
| get_pokemon_evolution_visual, | |
| get_evolution_stats_chart | |
| ], | |
| max_steps=3, # Reduced from 6 to force more direct tool usage | |
| verbosity_level=2, | |
| prompt_templates=improved_prompts | |
| ) | |
| def pokemon_ui(pokemon_name): | |
| if not pokemon_name: | |
| return "Please enter a Pokémon name (e.g., pikachu).", "", "" | |
| try: | |
| # Get evolution chain and stats | |
| evo_result = get_pokemon_evolution_visual(pokemon_name) | |
| chart_result = get_evolution_stats_chart(pokemon_name) | |
| # Combine text results | |
| text_output = f"Evolution Result:\n{evo_result}\n\nChart Result:\n{chart_result}" | |
| # Read evolution HTML | |
| html_filename = f"{pokemon_name.lower()}_evolution.html" | |
| evolution_html = "" | |
| try: | |
| if os.path.exists(html_filename): | |
| with open(html_filename, "r", encoding="utf-8") as f: | |
| evolution_html = f.read() | |
| else: | |
| evolution_html = "<p>Evolution HTML file not found.</p>" | |
| except Exception as e: | |
| evolution_html = f"<p>Error reading evolution HTML: {str(e)}</p>" | |
| # Read chart JSON and create chart HTML | |
| chart_filename = f"{pokemon_name.lower()}_evolution_stats.json" | |
| chart_html = "" | |
| try: | |
| if os.path.exists(chart_filename): | |
| with open(chart_filename, "r") as f: | |
| chart_config = json.load(f) | |
| # Create proper chart HTML | |
| chart_html = f""" | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script> | |
| </head> | |
| <body> | |
| <div style="width: 600px; height: 400px; margin: auto;"> | |
| <canvas id="statsChart"></canvas> | |
| </div> | |
| <script> | |
| const ctx = document.getElementById('statsChart').getContext('2d'); | |
| const chartConfig = {json.dumps(chart_config, indent=2)}; | |
| new Chart(ctx, chartConfig); | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| else: | |
| chart_html = "<p>Chart JSON file not found.</p>" | |
| except Exception as e: | |
| chart_html = f"<p>Error creating chart HTML: {str(e)}</p>" | |
| return text_output, evolution_html, chart_html | |
| except Exception as e: | |
| return f"Error processing {pokemon_name}: {str(e)}", "", "" | |
| # Also fix the Gradio interface | |
| if __name__ == "__main__": | |
| iface = gr.Interface( | |
| fn=pokemon_ui, | |
| inputs=gr.Textbox(label="Pokemon Name", placeholder="Enter Pokemon name (e.g., pikachu)"), | |
| outputs=[ | |
| gr.Textbox(label="Results", lines=6), # Changed from HTML to Textbox for the text output | |
| gr.HTML(label="Evolution Visualization"), | |
| gr.HTML(label="Evolution Stats Chart"), | |
| ], | |
| title="Pokemon Evolution Visualizer", | |
| description="Enter a Pokemon name to see its evolution chain and stats comparison" | |
| ) | |
| iface.launch(share=True) |