import{s as os,n as ps,o as Is}from"../chunks/scheduler.37c15a92.js";import{S as is,i as Cs,g as t,s as n,r as j,A as cs,h as y,f as M,c as e,j as Us,u as U,x as J,k as Ts,y as As,a,v as T,d as w,t as o,w as p}from"../chunks/index.2bf4358c.js";import{C as ws}from"../chunks/CodeBlock.4e987730.js";import{H as D}from"../chunks/Heading.8ada512a.js";import{E as ms}from"../chunks/index.e71982be.js";function rs(Sl){let I,ll,K,sl,i,Ml,C,Ql="Ahora que has explorado el potencial y las limitaciones de la IA Agéntica en los juegos, es hora de poner manos a la obra. En esta sección, <strong>construirás tu propio Agente de IA para luchar en combates por turnos al estilo Pokémon</strong>, utilizando todo lo que has aprendido a lo largo del curso.",al,c,Vl="Dividiremos el sistema en cuatro bloques de construcción clave:",nl,A,Rl="<li><p><strong>Poke-env:</strong> Una biblioteca de Python diseñada para entrenar bots de Pokémon basados en reglas o aprendizaje por refuerzo.</p></li> <li><p><strong>Pokémon Showdown:</strong> Un simulador de batallas en línea donde luchará tu agente.</p></li> <li><p><strong>LLMAgentBase:</strong> Una clase personalizada de Python que hemos construido para conectar tu LLM con el entorno de batalla de Poke-env.</p></li> <li><p><strong>TemplateAgent:</strong> Una plantilla de inicio que completarás para crear tu propio agente de batalla único.</p></li>",el,m,Xl="Exploremos cada uno de estos componentes con más detalle.",tl,r,yl,u,zl='<img src="https://github.com/hsahovic/poke-env/raw/master/rl-gif.gif" alt="Gif de batalla"/>',Jl,b,xl=`<a href="https://github.com/hsahovic/poke-env" rel="nofollow">Poke-env</a> es una interfaz de Python construida originalmente para entrenar bots de aprendizaje por refuerzo por <a href="https://huggingface.co/hsahovic" rel="nofollow">Haris Sahovic</a>, pero la hemos adaptado para la IA Agéntica.
Permite que tu agente interactúe con Pokémon Showdown a través de una API simple.`,jl,d,ql="Proporciona una clase <code>Player</code> de la cual tu Agente heredará, cubriendo todo lo necesario para comunicarse con la interfaz gráfica.",Ul,h,Fl='<strong>Documentación</strong>: <a href="https://poke-env.readthedocs.io/en/stable/" rel="nofollow">poke-env.readthedocs.io</a> <strong>Repositorio</strong>: <a href="https://github.com/hsahovic/poke-env" rel="nofollow">github.com/hsahovic/poke-env</a>',Tl,B,wl,f,Hl=`<a href="https://pokemonshowdown.com/" rel="nofollow">Pokémon Showdown</a> es un simulador de batallas <a href="https://github.com/smogon/Pokemon-Showdown" rel="nofollow">de código abierto</a> donde tu agente jugará batallas Pokémon en vivo.
Proporciona una interfaz completa para simular y mostrar batallas en tiempo real. En nuestro desafío, tu bot actuará como un jugador humano, eligiendo movimientos turno por turno.`,ol,Z,Ll="Hemos desplegado un servidor que todos los participantes usarán para luchar. ¡Veamos quién construye el mejor Agente de batalla de IA!",pl,_,$l='<strong>Repositorio</strong>: <a href="https://github.com/smogon/Pokemon-Showdown" rel="nofollow">github.com/smogon/Pokemon-Showdown</a> <strong>Sitio web</strong>: <a href="https://pokemonshowdown.com/" rel="nofollow">pokemonshowdown.com</a>',Il,v,il,G,Pl=`<code>LLMAgentBase</code> es una clase de Python que extiende la clase <code>Player</code> de <strong>Poke-env</strong>.
Sirve como puente entre tu <strong>LLM</strong> y el <strong>simulador de batallas Pokémon</strong>, manejando el formato de entrada/salida y manteniendo el contexto de la batalla.`,Cl,k,Dl="Este agente base proporciona un conjunto de herramientas (definidas en <code>STANDARD_TOOL_SCHEMA</code>) para interactuar con el entorno, incluyendo:",cl,W,Kl="<li><code>choose_move</code>: para seleccionar un ataque durante la batalla</li> <li><code>choose_switch</code>: para cambiar de Pokémon</li>",Al,E,Ol="El LLM debe usar estas herramientas para tomar decisiones durante una partida.",ml,N,rl,Y,ls="<li><code>choose_move(battle: Battle)</code>: Este es el método principal invocado en cada turno. Toma un objeto <code>Battle</code> y devuelve una cadena de acción basada en la salida del LLM.</li>",ul,g,bl,S,ss="<li><p><code>_format_battle_state(battle)</code>: Convierte el estado actual de la batalla en una cadena, haciéndolo adecuado para enviarlo al LLM.</p></li> <li><p><code>_find_move_by_name(battle, move_name)</code>: Encuentra un movimiento por nombre, utilizado en las respuestas del LLM que llaman a <code>choose_move</code>.</p></li> <li><p><code>_find_pokemon_by_name(battle, pokemon_name)</code>: Localiza un Pokémon específico para cambiar, basado en el comando de cambio del LLM.</p></li> <li><p><code>_get_llm_decision(battle_state)</code>: Este método es abstracto en la clase base. Deberás implementarlo en tu propio agente (ver sección siguiente), donde defines cómo consultar al LLM y analizar su respuesta.</p></li>",dl,Q,Ms="Aquí hay un extracto que muestra cómo funciona esa toma de decisiones:",hl,V,Bl,R,as='<strong>Código fuente completo</strong>: <a href="https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py" rel="nofollow">agents.py</a>',fl,X,Zl,z,ns="¡Ahora viene la parte divertida! Con LLMAgentBase como tu base, es hora de implementar tu propio agente, con tu propia estrategia para escalar en la tabla de clasificación.",_l,x,es='Comenzarás desde esta plantilla y construirás tu propia lógica. También hemos proporcionado tres <a href="https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py" rel="nofollow">ejemplos completos</a> usando los modelos <strong>OpenAI</strong>, <strong>Mistral</strong> y <strong>Gemini</strong> para guiarte.',vl,q,ts="Aquí tienes una versión simplificada de la plantilla:",Gl,F,kl,H,ys="Este código no se ejecutará tal cual, es un plano para tu lógica personalizada.",Wl,L,Js="Con todas las piezas listas, es tu turno de construir un agente competitivo. En la próxima sección, mostraremos cómo desplegar tu agente en nuestro servidor y luchar contra otros en tiempo real.",El,$,js="¡Que comience la batalla! 🔥",Nl,P,Yl,O,gl;return i=new D({props:{title:"Construye tu Propio Agente de Batalla Pokémon",local:"construye-tu-propio-agente-de-batalla-pokémon",headingTag:"h1"}}),r=new D({props:{title:"🧠 Poke-env",local:"-poke-env",headingTag:"h2"}}),B=new D({props:{title:"⚔️ Pokémon Showdown",local:"-pokémon-showdown",headingTag:"h2"}}),v=new D({props:{title:"🔌 LLMAgentBase",local:"-llmagentbase",headingTag:"h2"}}),N=new D({props:{title:"🧠 Lógica Central",local:"-lógica-central",headingTag:"h3"}}),g=new D({props:{title:"🔧 Métodos Internos Clave",local:"-métodos-internos-clave",headingTag:"h3"}}),V=new ws({props:{code:" ",highlighted:`STANDARD_TOOL_SCHEMA = {
    <span class="hljs-string">&quot;choose_move&quot;</span>: {
        ...
    },
    <span class="hljs-string">&quot;choose_switch&quot;</span>: {
        ...
    },
}

<span class="hljs-keyword">class</span> <span class="hljs-title class_">LLMAgentBase</span>(<span class="hljs-title class_ inherited__">Player</span>):
    <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, *args, **kwargs</span>):
        <span class="hljs-built_in">super</span>().__init__(*args, **kwargs)
        self.standard_tools = STANDARD_TOOL_SCHEMA
        self.battle_history = []

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_format_battle_state</span>(<span class="hljs-params">self, battle: Battle</span>) -&gt; <span class="hljs-built_in">str</span>:
        active_pkmn = battle.active_pokemon
        active_pkmn_info = <span class="hljs-string">f&quot;Tu Pokémon activo: <span class="hljs-subst">{active_pkmn.species}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;(Tipo: <span class="hljs-subst">{<span class="hljs-string">&#x27;/&#x27;</span>.join(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">str</span>, active_pkmn.types))}</span>) &quot;</span> \\
                           <span class="hljs-string">f&quot;HP: <span class="hljs-subst">{active_pkmn.current_hp_fraction * <span class="hljs-number">100</span>:<span class="hljs-number">.1</span>f}</span>% &quot;</span> \\
                           <span class="hljs-string">f&quot;Estado: <span class="hljs-subst">{active_pkmn.status.name <span class="hljs-keyword">if</span> active_pkmn.status <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;Ninguno&#x27;</span>}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;Mejoras: <span class="hljs-subst">{active_pkmn.boosts}</span>&quot;</span>

        opponent_pkmn = battle.opponent_active_pokemon
        opp_info_str = <span class="hljs-string">&quot;Desconocido&quot;</span>
        <span class="hljs-keyword">if</span> opponent_pkmn:
            opp_info_str = <span class="hljs-string">f&quot;<span class="hljs-subst">{opponent_pkmn.species}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;(Tipo: <span class="hljs-subst">{<span class="hljs-string">&#x27;/&#x27;</span>.join(<span class="hljs-built_in">map</span>(<span class="hljs-built_in">str</span>, opponent_pkmn.types))}</span>) &quot;</span> \\
                           <span class="hljs-string">f&quot;HP: <span class="hljs-subst">{opponent_pkmn.current_hp_fraction * <span class="hljs-number">100</span>:<span class="hljs-number">.1</span>f}</span>% &quot;</span> \\
                           <span class="hljs-string">f&quot;Estado: <span class="hljs-subst">{opponent_pkmn.status.name <span class="hljs-keyword">if</span> opponent_pkmn.status <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;Ninguno&#x27;</span>}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;Mejoras: <span class="hljs-subst">{opponent_pkmn.boosts}</span>&quot;</span>
        opponent_pkmn_info = <span class="hljs-string">f&quot;El Pokémon activo del oponente: <span class="hljs-subst">{opp_info_str}</span>&quot;</span>

        available_moves_info = <span class="hljs-string">&quot;Movimientos disponibles:\\n&quot;</span>
        <span class="hljs-keyword">if</span> battle.available_moves:
            available_moves_info += <span class="hljs-string">&quot;\\n&quot;</span>.join(
                [<span class="hljs-string">f&quot;- <span class="hljs-subst">{move.<span class="hljs-built_in">id</span>}</span> (Tipo: <span class="hljs-subst">{move.<span class="hljs-built_in">type</span>}</span>, BP: <span class="hljs-subst">{move.base_power}</span>, Precisión: <span class="hljs-subst">{move.accuracy}</span>, PP: <span class="hljs-subst">{move.current_pp}</span>/<span class="hljs-subst">{move.max_pp}</span>, Cat: <span class="hljs-subst">{move.category.name}</span>)&quot;</span>
                 <span class="hljs-keyword">for</span> move <span class="hljs-keyword">in</span> battle.available_moves]
            )
        <span class="hljs-keyword">else</span>:
             available_moves_info += <span class="hljs-string">&quot;- Ninguno (Debes cambiar o luchar con Struggle)&quot;</span>

        available_switches_info = <span class="hljs-string">&quot;Cambios disponibles:\\n&quot;</span>
        <span class="hljs-keyword">if</span> battle.available_switches:
              available_switches_info += <span class="hljs-string">&quot;\\n&quot;</span>.join(
                  [<span class="hljs-string">f&quot;- <span class="hljs-subst">{pkmn.species}</span> (HP: <span class="hljs-subst">{pkmn.current_hp_fraction * <span class="hljs-number">100</span>:<span class="hljs-number">.1</span>f}</span>%, Estado: <span class="hljs-subst">{pkmn.status.name <span class="hljs-keyword">if</span> pkmn.status <span class="hljs-keyword">else</span> <span class="hljs-string">&#x27;Ninguno&#x27;</span>}</span>)&quot;</span>
                   <span class="hljs-keyword">for</span> pkmn <span class="hljs-keyword">in</span> battle.available_switches]
              )
        <span class="hljs-keyword">else</span>:
            available_switches_info += <span class="hljs-string">&quot;- Ninguno&quot;</span>

        state_str = <span class="hljs-string">f&quot;<span class="hljs-subst">{active_pkmn_info}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;<span class="hljs-subst">{opponent_pkmn_info}</span>\\n\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;<span class="hljs-subst">{available_moves_info}</span>\\n\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;<span class="hljs-subst">{available_switches_info}</span>\\n\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Clima: <span class="hljs-subst">{battle.weather}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Terrenos: <span class="hljs-subst">{battle.fields}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Condiciones de tu lado: <span class="hljs-subst">{battle.side_conditions}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Condiciones del lado del oponente: <span class="hljs-subst">{battle.opponent_side_conditions}</span>&quot;</span>
        <span class="hljs-keyword">return</span> state_str.strip()

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_find_move_by_name</span>(<span class="hljs-params">self, battle: Battle, move_name: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-type">Optional</span>[Move]:
        normalized_name = normalize_name(move_name)
        <span class="hljs-comment"># Prioriza la coincidencia exacta de ID</span>
        <span class="hljs-keyword">for</span> move <span class="hljs-keyword">in</span> battle.available_moves:
            <span class="hljs-keyword">if</span> move.<span class="hljs-built_in">id</span> == normalized_name:
                <span class="hljs-keyword">return</span> move
        <span class="hljs-comment"># Fallback: Verifica el nombre de visualización (menos confiable)</span>
        <span class="hljs-keyword">for</span> move <span class="hljs-keyword">in</span> battle.available_moves:
            <span class="hljs-keyword">if</span> move.name.lower() == move_name.lower():
                <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Advertencia: Coincidencia de movimiento por nombre de visualización &#x27;<span class="hljs-subst">{move.name}</span>&#x27; en lugar de ID &#x27;<span class="hljs-subst">{move.<span class="hljs-built_in">id</span>}</span>&#x27;. Entrada fue &#x27;<span class="hljs-subst">{move_name}</span>&#x27;.&quot;</span>)
                <span class="hljs-keyword">return</span> move
        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

    <span class="hljs-keyword">def</span> <span class="hljs-title function_">_find_pokemon_by_name</span>(<span class="hljs-params">self, battle: Battle, pokemon_name: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-type">Optional</span>[Pokemon]:
        normalized_name = normalize_name(pokemon_name)
        <span class="hljs-keyword">for</span> pkmn <span class="hljs-keyword">in</span> battle.available_switches:
            <span class="hljs-comment"># Normaliza el nombre de la especie para comparación</span>
            <span class="hljs-keyword">if</span> normalize_name(pkmn.species) == normalized_name:
                <span class="hljs-keyword">return</span> pkmn
        <span class="hljs-keyword">return</span> <span class="hljs-literal">None</span>

    <span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">choose_move</span>(<span class="hljs-params">self, battle: Battle</span>) -&gt; <span class="hljs-built_in">str</span>:
        battle_state_str = self._format_battle_state(battle)
        decision_result = <span class="hljs-keyword">await</span> self._get_llm_decision(battle_state_str)
        <span class="hljs-built_in">print</span>(decision_result)
        decision = decision_result.get(<span class="hljs-string">&quot;decision&quot;</span>)
        error_message = decision_result.get(<span class="hljs-string">&quot;error&quot;</span>)
        action_taken = <span class="hljs-literal">False</span>
        fallback_reason = <span class="hljs-string">&quot;&quot;</span>

        <span class="hljs-keyword">if</span> decision:
            function_name = decision.get(<span class="hljs-string">&quot;name&quot;</span>)
            args = decision.get(<span class="hljs-string">&quot;arguments&quot;</span>, {})
            <span class="hljs-keyword">if</span> function_name == <span class="hljs-string">&quot;choose_move&quot;</span>:
                move_name = args.get(<span class="hljs-string">&quot;move_name&quot;</span>)
                <span class="hljs-keyword">if</span> move_name:
                    chosen_move = self._find_move_by_name(battle, move_name)
                    <span class="hljs-keyword">if</span> chosen_move <span class="hljs-keyword">and</span> chosen_move <span class="hljs-keyword">in</span> battle.available_moves:
                        action_taken = <span class="hljs-literal">True</span>
                        chat_msg = <span class="hljs-string">f&quot;Decisión de la IA: Usando movimiento &#x27;<span class="hljs-subst">{chosen_move.<span class="hljs-built_in">id</span>}</span>&#x27;.&quot;</span>
                        <span class="hljs-built_in">print</span>(chat_msg)
                        <span class="hljs-keyword">return</span> self.create_order(chosen_move)
                    <span class="hljs-keyword">else</span>:
                        fallback_reason = <span class="hljs-string">f&quot;La IA eligió un movimiento no disponible/no válido &#x27;<span class="hljs-subst">{move_name}</span>&#x27;.&quot;</span>
                <span class="hljs-keyword">else</span>:
                     fallback_reason = <span class="hljs-string">&quot;La IA llamó a &#x27;choose_move&#x27; sin &#x27;move_name&#x27;.&quot;</span>
            <span class="hljs-keyword">elif</span> function_name == <span class="hljs-string">&quot;choose_switch&quot;</span>:
                pokemon_name = args.get(<span class="hljs-string">&quot;pokemon_name&quot;</span>)
                <span class="hljs-keyword">if</span> pokemon_name:
                    chosen_switch = self._find_pokemon_by_name(battle, pokemon_name)
                    <span class="hljs-keyword">if</span> chosen_switch <span class="hljs-keyword">and</span> chosen_switch <span class="hljs-keyword">in</span> battle.available_switches:
                        action_taken = <span class="hljs-literal">True</span>
                        chat_msg = <span class="hljs-string">f&quot;Decisión de la IA: Cambiando a &#x27;<span class="hljs-subst">{chosen_switch.species}</span>&#x27;.&quot;</span>
                        <span class="hljs-built_in">print</span>(chat_msg)
                        <span class="hljs-keyword">return</span> self.create_order(chosen_switch)
                    <span class="hljs-keyword">else</span>:
                        fallback_reason = <span class="hljs-string">f&quot;La IA eligió un cambio no disponible/no válido &#x27;<span class="hljs-subst">{pokemon_name}</span>&#x27;.&quot;</span>
                <span class="hljs-keyword">else</span>:
                    fallback_reason = <span class="hljs-string">&quot;La IA llamó a &#x27;choose_switch&#x27; sin &#x27;pokemon_name&#x27;.&quot;</span>
            <span class="hljs-keyword">else</span>:
                fallback_reason = <span class="hljs-string">f&quot;La IA llamó a una función desconocida &#x27;<span class="hljs-subst">{function_name}</span>&#x27;.&quot;</span>

        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> action_taken:
            <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> fallback_reason:
                 <span class="hljs-keyword">if</span> error_message:
                     fallback_reason = <span class="hljs-string">f&quot;Error de la API: <span class="hljs-subst">{error_message}</span>&quot;</span>
                 <span class="hljs-keyword">elif</span> decision <span class="hljs-keyword">is</span> <span class="hljs-literal">None</span>:
                      fallback_reason = <span class="hljs-string">&quot;La IA no proporcionó una llamada de función válida.&quot;</span>
                 <span class="hljs-keyword">else</span>:
                      fallback_reason = <span class="hljs-string">&quot;Error desconocido al procesar la decisión de la IA.&quot;</span>

            <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Advertencia: <span class="hljs-subst">{fallback_reason}</span> Seleccionando acción aleatoria.&quot;</span>)

            <span class="hljs-keyword">if</span> battle.available_moves <span class="hljs-keyword">or</span> battle.available_switches:
                 <span class="hljs-keyword">return</span> self.choose_random_move(battle)
            <span class="hljs-keyword">else</span>:
                 <span class="hljs-built_in">print</span>(<span class="hljs-string">&quot;Fallback de la IA: No hay movimientos ni cambios disponibles. Usando Struggle/Default.&quot;</span>)
                 <span class="hljs-keyword">return</span> self.choose_default_move(battle)

    <span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">_get_llm_decision</span>(<span class="hljs-params">self, battle_state: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]:
        <span class="hljs-keyword">raise</span> NotImplementedError(<span class="hljs-string">&quot;Las subclases deben implementar _get_llm_decision&quot;</span>)`,wrap:!1}}),X=new D({props:{title:"🧪 Plantilla de Agente",local:"-plantilla-de-agente",headingTag:"h2"}}),F=new ws({props:{code:"Y2xhc3MlMjBUZW1wbGF0ZUFnZW50KExMTUFnZW50QmFzZSklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJVdGlsaXphJTIwbGElMjBBUEklMjBkZSUyMFRlbXBsYXRlJTIwQUklMjBwYXJhJTIwdG9tYXIlMjBkZWNpc2lvbmVzLiUyMiUyMiUyMiUwQSUyMCUyMCUyMCUyMGRlZiUyMF9faW5pdF9fKHNlbGYlMkMlMjBhcGlfa2V5JTNBJTIwc3RyJTIwJTNEJTIwTm9uZSUyQyUyMG1vZGVsJTNBJTIwc3RyJTIwJTNEJTIwJTIybW9kZWwtbmFtZSUyMiUyQyUyMCphcmdzJTJDJTIwKiprd2FyZ3MpJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc3VwZXIoKS5fX2luaXRfXygqYXJncyUyQyUyMCoqa3dhcmdzKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYubW9kZWwlMjAlM0QlMjBtb2RlbCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYudGVtcGxhdGVfY2xpZW50JTIwJTNEJTIwVGVtcGxhdGVNb2RlbFByb3ZpZGVyKGFwaV9rZXklM0QuLi4pJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc2VsZi50ZW1wbGF0ZV90b29scyUyMCUzRCUyMGxpc3Qoc2VsZi5zdGFuZGFyZF90b29scy52YWx1ZXMoKSklMEElMEElMjAlMjAlMjAlMjBhc3luYyUyMGRlZiUyMF9nZXRfbGxtX2RlY2lzaW9uKHNlbGYlMkMlMjBiYXR0bGVfc3RhdGUlM0ElMjBzdHIpJTIwLSUzRSUyMERpY3QlNUJzdHIlMkMlMjBBbnklNUQlM0ElMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjIlMjIlMjJFbnYlQzMlQURhJTIwZWwlMjBlc3RhZG8lMjBhbCUyMExMTSUyMHklMjBvYnRpZW5lJTIwbGElMjBkZWNpc2klQzMlQjNuJTIwZGUlMjBsbGFtYWRhJTIwZGUlMjBmdW5jaSVDMyVCM24uJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc3lzdGVtX3Byb21wdCUyMCUzRCUyMCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJFcmVzJTIwdW4lMjAuLi4lMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdXNlcl9wcm9tcHQlMjAlM0QlMjBmJTIyLi4uJTIyJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzcG9uc2UlMjAlM0QlMjBhd2FpdCUyMHNlbGYudGVtcGxhdGVfY2xpZW50LmNoYXQuY29tcGxldGlvbnMuY3JlYXRlKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1vZGVsJTNEc2VsZi5tb2RlbCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1lc3NhZ2VzJTNEJTVCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTIycm9sZSUyMiUzQSUyMCUyMnN5c3RlbSUyMiUyQyUyMCUyMmNvbnRlbnQlMjIlM0ElMjBzeXN0ZW1fcHJvbXB0JTdEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTIycm9sZSUyMiUzQSUyMCUyMnVzZXIlMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwdXNlcl9wcm9tcHQlN0QlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWVzc2FnZSUyMCUzRCUyMHJlc3BvbnNlLmNob2ljZXMlNUIwJTVELm1lc3NhZ2UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlN0IlMjJkZWNpc2lvbiUyMiUzQSUyMCU3QiUyMm5hbWUlMjIlM0ElMjBmdW5jdGlvbl9uYW1lJTJDJTIwJTIyYXJndW1lbnRzJTIyJTNBJTIwYXJndW1lbnRzJTdEJTdEJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwRXhjZXB0aW9uJTIwYXMlMjBlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoZiUyMkVycm9yJTIwaW5lc3BlcmFkbyUyMGR1cmFudGUlMjBsYSUyMGxsYW1hZGElM0ElMjAlN0JlJTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUyMmVycm9yJTIyJTNBJTIwZiUyMkVycm9yJTIwaW5lc3BlcmFkbyUzQSUyMCU3QmUlN0QlMjIlN0Q=",highlighted:`<span class="hljs-keyword">class</span> <span class="hljs-title class_">TemplateAgent</span>(<span class="hljs-title class_ inherited__">LLMAgentBase</span>):
    <span class="hljs-string">&quot;&quot;&quot;Utiliza la API de Template AI para tomar decisiones.&quot;&quot;&quot;</span>
    <span class="hljs-keyword">def</span> <span class="hljs-title function_">__init__</span>(<span class="hljs-params">self, api_key: <span class="hljs-built_in">str</span> = <span class="hljs-literal">None</span>, model: <span class="hljs-built_in">str</span> = <span class="hljs-string">&quot;model-name&quot;</span>, *args, **kwargs</span>):
        <span class="hljs-built_in">super</span>().__init__(*args, **kwargs)
        self.model = model
        self.template_client = TemplateModelProvider(api_key=...)
        self.template_tools = <span class="hljs-built_in">list</span>(self.standard_tools.values())

    <span class="hljs-keyword">async</span> <span class="hljs-keyword">def</span> <span class="hljs-title function_">_get_llm_decision</span>(<span class="hljs-params">self, battle_state: <span class="hljs-built_in">str</span></span>) -&gt; <span class="hljs-type">Dict</span>[<span class="hljs-built_in">str</span>, <span class="hljs-type">Any</span>]:
        <span class="hljs-string">&quot;&quot;&quot;Envía el estado al LLM y obtiene la decisión de llamada de función.&quot;&quot;&quot;</span>
        system_prompt = (
            <span class="hljs-string">&quot;Eres un ...&quot;</span>
        )
        user_prompt = <span class="hljs-string">f&quot;...&quot;</span>

        <span class="hljs-keyword">try</span>:
            response = <span class="hljs-keyword">await</span> self.template_client.chat.completions.create(
                model=self.model,
                messages=[
                    {<span class="hljs-string">&quot;role&quot;</span>: <span class="hljs-string">&quot;system&quot;</span>, <span class="hljs-string">&quot;content&quot;</span>: system_prompt},
                    {<span class="hljs-string">&quot;role&quot;</span>: <span class="hljs-string">&quot;user&quot;</span>, <span class="hljs-string">&quot;content&quot;</span>: user_prompt},
                ],
            )
            message = response.choices[<span class="hljs-number">0</span>].message
            
            <span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;decision&quot;</span>: {<span class="hljs-string">&quot;name&quot;</span>: function_name, <span class="hljs-string">&quot;arguments&quot;</span>: arguments}}

        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
            <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Error inesperado durante la llamada: <span class="hljs-subst">{e}</span>&quot;</span>)
            <span class="hljs-keyword">return</span> {<span class="hljs-string">&quot;error&quot;</span>: <span class="hljs-string">f&quot;Error inesperado: <span class="hljs-subst">{e}</span>&quot;</span>}`,wrap:!1}}),P=new ms({props:{source:"https://github.com/huggingface/agents-course/blob/main/units/es/bonus-unit3/building_your_pokemon_agent.mdx"}}),{c(){I=t("meta"),ll=n(),K=t("p"),sl=n(),j(i.$$.fragment),Ml=n(),C=t("p"),C.innerHTML=Ql,al=n(),c=t("p"),c.textContent=Vl,nl=n(),A=t("ul"),A.innerHTML=Rl,el=n(),m=t("p"),m.textContent=Xl,tl=n(),j(r.$$.fragment),yl=n(),u=t("p"),u.innerHTML=zl,Jl=n(),b=t("p"),b.innerHTML=xl,jl=n(),d=t("p"),d.innerHTML=ql,Ul=n(),h=t("p"),h.innerHTML=Fl,Tl=n(),j(B.$$.fragment),wl=n(),f=t("p"),f.innerHTML=Hl,ol=n(),Z=t("p"),Z.textContent=Ll,pl=n(),_=t("p"),_.innerHTML=$l,Il=n(),j(v.$$.fragment),il=n(),G=t("p"),G.innerHTML=Pl,Cl=n(),k=t("p"),k.innerHTML=Dl,cl=n(),W=t("ul"),W.innerHTML=Kl,Al=n(),E=t("p"),E.textContent=Ol,ml=n(),j(N.$$.fragment),rl=n(),Y=t("ul"),Y.innerHTML=ls,ul=n(),j(g.$$.fragment),bl=n(),S=t("ul"),S.innerHTML=ss,dl=n(),Q=t("p"),Q.textContent=Ms,hl=n(),j(V.$$.fragment),Bl=n(),R=t("p"),R.innerHTML=as,fl=n(),j(X.$$.fragment),Zl=n(),z=t("p"),z.textContent=ns,_l=n(),x=t("p"),x.innerHTML=es,vl=n(),q=t("p"),q.textContent=ts,Gl=n(),j(F.$$.fragment),kl=n(),H=t("p"),H.textContent=ys,Wl=n(),L=t("p"),L.textContent=Js,El=n(),$=t("p"),$.textContent=js,Nl=n(),j(P.$$.fragment),Yl=n(),O=t("p"),this.h()},l(l){const s=cs("svelte-u9bgzb",document.head);I=y(s,"META",{name:!0,content:!0}),s.forEach(M),ll=e(l),K=y(l,"P",{}),Us(K).forEach(M),sl=e(l),U(i.$$.fragment,l),Ml=e(l),C=y(l,"P",{"data-svelte-h":!0}),J(C)!=="svelte-k0s4e1"&&(C.innerHTML=Ql),al=e(l),c=y(l,"P",{"data-svelte-h":!0}),J(c)!=="svelte-10oxgqi"&&(c.textContent=Vl),nl=e(l),A=y(l,"UL",{"data-svelte-h":!0}),J(A)!=="svelte-1qcm21k"&&(A.innerHTML=Rl),el=e(l),m=y(l,"P",{"data-svelte-h":!0}),J(m)!=="svelte-uvg96r"&&(m.textContent=Xl),tl=e(l),U(r.$$.fragment,l),yl=e(l),u=y(l,"P",{"data-svelte-h":!0}),J(u)!=="svelte-exhf6d"&&(u.innerHTML=zl),Jl=e(l),b=y(l,"P",{"data-svelte-h":!0}),J(b)!=="svelte-wsf1mq"&&(b.innerHTML=xl),jl=e(l),d=y(l,"P",{"data-svelte-h":!0}),J(d)!=="svelte-1ksq0nt"&&(d.innerHTML=ql),Ul=e(l),h=y(l,"P",{"data-svelte-h":!0}),J(h)!=="svelte-1ox26i7"&&(h.innerHTML=Fl),Tl=e(l),U(B.$$.fragment,l),wl=e(l),f=y(l,"P",{"data-svelte-h":!0}),J(f)!=="svelte-nuq6tl"&&(f.innerHTML=Hl),ol=e(l),Z=y(l,"P",{"data-svelte-h":!0}),J(Z)!=="svelte-erl2sb"&&(Z.textContent=Ll),pl=e(l),_=y(l,"P",{"data-svelte-h":!0}),J(_)!=="svelte-1t2c7zs"&&(_.innerHTML=$l),Il=e(l),U(v.$$.fragment,l),il=e(l),G=y(l,"P",{"data-svelte-h":!0}),J(G)!=="svelte-ywbycg"&&(G.innerHTML=Pl),Cl=e(l),k=y(l,"P",{"data-svelte-h":!0}),J(k)!=="svelte-1a0720n"&&(k.innerHTML=Dl),cl=e(l),W=y(l,"UL",{"data-svelte-h":!0}),J(W)!=="svelte-19922wv"&&(W.innerHTML=Kl),Al=e(l),E=y(l,"P",{"data-svelte-h":!0}),J(E)!=="svelte-1ilp7il"&&(E.textContent=Ol),ml=e(l),U(N.$$.fragment,l),rl=e(l),Y=y(l,"UL",{"data-svelte-h":!0}),J(Y)!=="svelte-19xjy9a"&&(Y.innerHTML=ls),ul=e(l),U(g.$$.fragment,l),bl=e(l),S=y(l,"UL",{"data-svelte-h":!0}),J(S)!=="svelte-15kgwc9"&&(S.innerHTML=ss),dl=e(l),Q=y(l,"P",{"data-svelte-h":!0}),J(Q)!=="svelte-1x2lfz1"&&(Q.textContent=Ms),hl=e(l),U(V.$$.fragment,l),Bl=e(l),R=y(l,"P",{"data-svelte-h":!0}),J(R)!=="svelte-1xrpn7q"&&(R.innerHTML=as),fl=e(l),U(X.$$.fragment,l),Zl=e(l),z=y(l,"P",{"data-svelte-h":!0}),J(z)!=="svelte-vmg64m"&&(z.textContent=ns),_l=e(l),x=y(l,"P",{"data-svelte-h":!0}),J(x)!=="svelte-1mv8345"&&(x.innerHTML=es),vl=e(l),q=y(l,"P",{"data-svelte-h":!0}),J(q)!=="svelte-1u0lrpj"&&(q.textContent=ts),Gl=e(l),U(F.$$.fragment,l),kl=e(l),H=y(l,"P",{"data-svelte-h":!0}),J(H)!=="svelte-8ywxid"&&(H.textContent=ys),Wl=e(l),L=y(l,"P",{"data-svelte-h":!0}),J(L)!=="svelte-1nq6xgm"&&(L.textContent=Js),El=e(l),$=y(l,"P",{"data-svelte-h":!0}),J($)!=="svelte-1sd5la0"&&($.textContent=js),Nl=e(l),U(P.$$.fragment,l),Yl=e(l),O=y(l,"P",{}),Us(O).forEach(M),this.h()},h(){Ts(I,"name","hf:doc:metadata"),Ts(I,"content",us)},m(l,s){As(document.head,I),a(l,ll,s),a(l,K,s),a(l,sl,s),T(i,l,s),a(l,Ml,s),a(l,C,s),a(l,al,s),a(l,c,s),a(l,nl,s),a(l,A,s),a(l,el,s),a(l,m,s),a(l,tl,s),T(r,l,s),a(l,yl,s),a(l,u,s),a(l,Jl,s),a(l,b,s),a(l,jl,s),a(l,d,s),a(l,Ul,s),a(l,h,s),a(l,Tl,s),T(B,l,s),a(l,wl,s),a(l,f,s),a(l,ol,s),a(l,Z,s),a(l,pl,s),a(l,_,s),a(l,Il,s),T(v,l,s),a(l,il,s),a(l,G,s),a(l,Cl,s),a(l,k,s),a(l,cl,s),a(l,W,s),a(l,Al,s),a(l,E,s),a(l,ml,s),T(N,l,s),a(l,rl,s),a(l,Y,s),a(l,ul,s),T(g,l,s),a(l,bl,s),a(l,S,s),a(l,dl,s),a(l,Q,s),a(l,hl,s),T(V,l,s),a(l,Bl,s),a(l,R,s),a(l,fl,s),T(X,l,s),a(l,Zl,s),a(l,z,s),a(l,_l,s),a(l,x,s),a(l,vl,s),a(l,q,s),a(l,Gl,s),T(F,l,s),a(l,kl,s),a(l,H,s),a(l,Wl,s),a(l,L,s),a(l,El,s),a(l,$,s),a(l,Nl,s),T(P,l,s),a(l,Yl,s),a(l,O,s),gl=!0},p:ps,i(l){gl||(w(i.$$.fragment,l),w(r.$$.fragment,l),w(B.$$.fragment,l),w(v.$$.fragment,l),w(N.$$.fragment,l),w(g.$$.fragment,l),w(V.$$.fragment,l),w(X.$$.fragment,l),w(F.$$.fragment,l),w(P.$$.fragment,l),gl=!0)},o(l){o(i.$$.fragment,l),o(r.$$.fragment,l),o(B.$$.fragment,l),o(v.$$.fragment,l),o(N.$$.fragment,l),o(g.$$.fragment,l),o(V.$$.fragment,l),o(X.$$.fragment,l),o(F.$$.fragment,l),o(P.$$.fragment,l),gl=!1},d(l){l&&(M(ll),M(K),M(sl),M(Ml),M(C),M(al),M(c),M(nl),M(A),M(el),M(m),M(tl),M(yl),M(u),M(Jl),M(b),M(jl),M(d),M(Ul),M(h),M(Tl),M(wl),M(f),M(ol),M(Z),M(pl),M(_),M(Il),M(il),M(G),M(Cl),M(k),M(cl),M(W),M(Al),M(E),M(ml),M(rl),M(Y),M(ul),M(bl),M(S),M(dl),M(Q),M(hl),M(Bl),M(R),M(fl),M(Zl),M(z),M(_l),M(x),M(vl),M(q),M(Gl),M(kl),M(H),M(Wl),M(L),M(El),M($),M(Nl),M(Yl),M(O)),M(I),p(i,l),p(r,l),p(B,l),p(v,l),p(N,l),p(g,l),p(V,l),p(X,l),p(F,l),p(P,l)}}}const us='{"title":"Construye tu Propio Agente de Batalla Pokémon","local":"construye-tu-propio-agente-de-batalla-pokémon","sections":[{"title":"🧠 Poke-env","local":"-poke-env","sections":[],"depth":2},{"title":"⚔️ Pokémon Showdown","local":"-pokémon-showdown","sections":[],"depth":2},{"title":"🔌 LLMAgentBase","local":"-llmagentbase","sections":[{"title":"🧠 Lógica Central","local":"-lógica-central","sections":[],"depth":3},{"title":"🔧 Métodos Internos Clave","local":"-métodos-internos-clave","sections":[],"depth":3}],"depth":2},{"title":"🧪 Plantilla de Agente","local":"-plantilla-de-agente","sections":[],"depth":2}],"depth":1}';function bs(Sl){return Is(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class _s extends is{constructor(I){super(),Cs(this,I,bs,rs,os,{})}}export{_s as component};
