import{s as Ts,n as ws,o as is}from"../chunks/scheduler.37c15a92.js";import{S as As,i as Cs,g as n,s as t,r as U,A as cs,h as j,f as M,c as a,j as os,u as o,x as y,k as ps,y as Is,a as e,v as p,d as J,t as T,w}from"../chunks/index.2bf4358c.js";import{C as Js}from"../chunks/CodeBlock.4e987730.js";import{H as K}from"../chunks/Heading.8ada512a.js";import{E as ms}from"../chunks/getInferenceSnippets.d4d07d1e.js";function rs(Yl){let i,ll,D,sl,A,Ml,C,Ql="Maintenant que vous avez exploré le potentiel et les limitations de l’IA Agentique dans les jeux, il est temps de passer à la pratique. Dans cette section, vous <strong>construirez votre propre Agent IA pour combattre dans un combat au tour par tour de style Pokémon</strong>, en utilisant tout ce que vous avez appris à travers le cours.",el,c,Xl="Nous décomposerons le système en quatre blocs de construction clés :",tl,I,Vl="<li><p><strong>Poke-env :</strong> Une bibliothèque Python conçue pour entraîner des bots Pokémon basés sur des règles ou par apprentissage par renforcement.</p></li> <li><p><strong>Pokémon Showdown :</strong> Un simulateur de combat en ligne où votre agent se battra.</p></li> <li><p><strong>LLMAgentBase :</strong> Une classe Python personnalisée que nous avons construite pour connecter votre LLM avec l’environnement de combat <em>Poke-env</em>.</p></li> <li><p><strong>TemplateAgent :</strong> Un template de démarrage que vous compléterez pour créer votre propre agent de combat unique.</p></li>",al,m,ql="Explorons chacun de ces composants plus en détail.",nl,r,jl,u,zl='<img src="https://github.com/hsahovic/poke-env/raw/master/rl-gif.gif" alt="Battle gif"/>',yl,b,xl=`<a href="https://github.com/hsahovic/poke-env" rel="nofollow">Poke-env</a> est une interface Python originellement construite pour entraîner des bots d’apprentissage par renforcement par <a href="https://huggingface.co/hsahovic" rel="nofollow">Haris Sahovic</a>, mais nous l’avons réutilisée pour l’IA Agentique.<br/>
Elle permet à votre agent d’interagir avec <em>Pokémon Showdown</em> à travers une API simple.`,Ul,h,Rl="Elle fournit une classe <code>Player</code> de laquelle votre Agent héritera, couvrant tout ce qui est nécessaire pour communiquer avec l’interface graphique.",ol,d,Fl='<strong>Documentation</strong> : <a href="https://poke-env.readthedocs.io/en/stable/" rel="nofollow">poke-env.readthedocs.io</a><br/> <strong>Dépôt</strong> : <a href="https://github.com/hsahovic/poke-env" rel="nofollow">github.com/hsahovic/poke-env</a>',pl,f,Jl,v,Ll=`<a href="https://pokemonshowdown.com/" rel="nofollow">Pokémon Showdown</a> est un simulateur de combat <a href="https://github.com/smogon/Pokemon-Showdown" rel="nofollow"><em>open-source</em></a> où votre agent jouera des combats Pokémon en direct.<br/>
Il fournit une interface complète pour simuler et afficher des combats en temps réel. Dans notre défi, votre bot agira exactement comme un joueur humain, choisissant des mouvements tour par tour.`,Tl,_,Hl="Nous avons déployé un serveur que tous les participants utiliseront pour combattre. Voyons qui construit le meilleur Agent IA de combat !",wl,B,$l='<strong>Dépôt</strong> : <a href="https://github.com/smogon/Pokemon-Showdown" rel="nofollow">github.com/smogon/Pokemon-Showdown</a><br/> <strong>Site web</strong> : <a href="https://pokemonshowdown.com/" rel="nofollow">pokemonshowdown.com</a>',il,Z,Al,G,Pl=`<code>LLMAgentBase</code> est une classe Python qui étend la classe <code>Player</code> de <strong>Poke-env</strong>.<br/>
Elle sert de pont entre votre <strong>LLM</strong> et le <strong>simulateur de combat Pokémon</strong>, gérant le formatage d’entrée/sortie et maintenant le contexte de combat.`,Cl,k,Kl="Cet agent de base fournit un ensemble d’outils (définis dans <code>STANDARD_TOOL_SCHEMA</code>) pour interagir avec l’environnement, incluant :",cl,N,Dl="<li><code>choose_move</code> : pour sélectionner une attaque pendant le combat</li> <li><code>choose_switch</code> : pour changer de Pokémon</li>",Il,E,Ol="Le LLM devrait utiliser ces outils pour prendre des décisions pendant un match.",ml,g,rl,W,ls="<li><code>choose_move(battle: Battle)</code> : C’est la méthode principale invoquée à chaque tour. Elle prend un objet <code>Battle</code> et retourne une chaîne d’action basée sur la sortie du LLM.</li>",ul,S,bl,Y,ss="<li><p><code>_format_battle_state(battle)</code> : Convertit l’état actuel du combat en chaîne, la rendant adaptée pour l’envoi au LLM.</p></li> <li><p><code>_find_move_by_name(battle, move_name)</code> : Trouve un mouvement par nom, utilisé dans les réponses LLM qui appellent <code>choose_move</code>.</p></li> <li><p><code>_find_pokemon_by_name(battle, pokemon_name)</code> : Localise un Pokémon spécifique vers lequel changer, basé sur la commande de changement du LLM.</p></li> <li><p><code>_get_llm_decision(battle_state)</code> : Cette méthode est abstraite dans la classe de base. Vous devrez l’implémenter dans votre propre agent (voir prochaine section), où vous définissez comment interroger le LLM et analyser sa réponse.</p></li>",hl,Q,Ms="Voici un extrait montrant comment cette prise de décision fonctionne :",dl,X,fl,V,es='<strong>Code source complet</strong> : <a href="https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py" rel="nofollow">agents.py</a>',vl,q,_l,z,ts="Maintenant vient la partie amusante ! Avec <em>LLMAgentBase</em> comme votre fondation, il est temps d’implémenter votre propre agent, avec votre propre stratégie pour grimper dans le classement.",Bl,x,as='Vous commencerez à partir de ce template et construirez votre propre logique. Nous avons aussi fourni trois <a href="https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py" rel="nofollow">exemples complets</a> utilisant les modèles <strong>OpenAI</strong>, <strong>Mistral</strong> et <strong>Gemini</strong> pour vous guider.',Zl,R,ns="Voici une version simplifiée du template :",Gl,F,kl,L,js="Ce code ne fonctionnera pas directement, c’est un blueprint pour votre logique personnalisée.",Nl,H,ys="Avec toutes les pièces prêtes, c’est à votre tour de construire un agent compétitif. Dans la prochaine section, nous montrerons comment déployer votre agent sur notre serveur et combattre d’autres en temps réel.",El,$,Us="Que le combat commence ! 🔥",gl,P,Wl,O,Sl;return A=new K({props:{title:"Construisez votre propre Agent de Combat Pokémon",local:"construisez-votre-propre-agent-de-combat-pokémon",headingTag:"h1"}}),r=new K({props:{title:"🧠 Poke-env",local:"-poke-env",headingTag:"h2"}}),f=new K({props:{title:"⚔️ Pokémon Showdown",local:"-pokémon-showdown",headingTag:"h2"}}),Z=new K({props:{title:"🔌 LLMAgentBase",local:"-llmagentbase",headingTag:"h2"}}),g=new K({props:{title:"🧠 Logique centrale",local:"-logique-centrale",headingTag:"h3"}}),S=new K({props:{title:"🔧 Méthodes internes clés",local:"-méthodes-internes-clés",headingTag:"h3"}}),X=new Js({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;Your active Pokemon: <span class="hljs-subst">{active_pkmn.species}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;(Type: <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;Status: <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;None&#x27;</span>}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;Boosts: <span class="hljs-subst">{active_pkmn.boosts}</span>&quot;</span>

        opponent_pkmn = battle.opponent_active_pokemon
        opp_info_str = <span class="hljs-string">&quot;Unknown&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;(Type: <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;Status: <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;None&#x27;</span>}</span> &quot;</span> \\
                           <span class="hljs-string">f&quot;Boosts: <span class="hljs-subst">{opponent_pkmn.boosts}</span>&quot;</span>
        opponent_pkmn_info = <span class="hljs-string">f&quot;Opponent&#x27;s active Pokemon: <span class="hljs-subst">{opp_info_str}</span>&quot;</span>

        available_moves_info = <span class="hljs-string">&quot;Available moves:\\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> (Type: <span class="hljs-subst">{move.<span class="hljs-built_in">type</span>}</span>, BP: <span class="hljs-subst">{move.base_power}</span>, Acc: <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;- None (Must switch or Struggle)&quot;</span>

        available_switches_info = <span class="hljs-string">&quot;Available switches:\\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>%, Status: <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;None&#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;- None&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;Weather: <span class="hljs-subst">{battle.weather}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Terrains: <span class="hljs-subst">{battle.fields}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Your Side Conditions: <span class="hljs-subst">{battle.side_conditions}</span>\\n&quot;</span> \\
                    <span class="hljs-string">f&quot;Opponent Side Conditions: <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"># Prioriser la correspondance exacte d&#x27;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"># Solution de secours : Vérifier le nom d&#x27;affichage (moins fiable)</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;Warning: Matched move by display name &#x27;<span class="hljs-subst">{move.name}</span>&#x27; instead of ID &#x27;<span class="hljs-subst">{move.<span class="hljs-built_in">id</span>}</span>&#x27;. Input was &#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"># Normaliser le nom d&#x27;espèce pour la comparaison</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;AI Decision: Using move &#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;LLM chose unavailable/invalid move &#x27;<span class="hljs-subst">{move_name}</span>&#x27;.&quot;</span>
                <span class="hljs-keyword">else</span>:
                     fallback_reason = <span class="hljs-string">&quot;LLM &#x27;choose_move&#x27; called without &#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;AI Decision: Switching to &#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;LLM chose unavailable/invalid switch &#x27;<span class="hljs-subst">{pokemon_name}</span>&#x27;.&quot;</span>
                <span class="hljs-keyword">else</span>:
                    fallback_reason = <span class="hljs-string">&quot;LLM &#x27;choose_switch&#x27; called without &#x27;pokemon_name&#x27;.&quot;</span>
            <span class="hljs-keyword">else</span>:
                fallback_reason = <span class="hljs-string">f&quot;LLM called unknown function &#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;API Error: <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;LLM did not provide a valid function call.&quot;</span>
                 <span class="hljs-keyword">else</span>:
                      fallback_reason = <span class="hljs-string">&quot;Unknown error processing LLM decision.&quot;</span>

            <span class="hljs-built_in">print</span>(<span class="hljs-string">f&quot;Warning: <span class="hljs-subst">{fallback_reason}</span> Choosing random action.&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;AI Fallback: No moves or switches available. Using 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;Subclasses must implement _get_llm_decision&quot;</span>)`,wrap:!1}}),q=new K({props:{title:"🧪 TemplateAgent",local:"-templateagent",headingTag:"h2"}}),F=new Js({props:{code:"Y2xhc3MlMjBUZW1wbGF0ZUFnZW50KExMTUFnZW50QmFzZSklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJVc2VzJTIwVGVtcGxhdGUlMjBBSSUyMEFQSSUyMGZvciUyMGRlY2lzaW9ucy4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBkZWYlMjBfX2luaXRfXyhzZWxmJTJDJTIwYXBpX2tleSUzQSUyMHN0ciUyMCUzRCUyME5vbmUlMkMlMjBtb2RlbCUzQSUyMHN0ciUyMCUzRCUyMCUyMm1vZGVsLW5hbWUlMjIlMkMlMjAqYXJncyUyQyUyMCoqa3dhcmdzKSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHN1cGVyKCkuX19pbml0X18oKmFyZ3MlMkMlMjAqKmt3YXJncyklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzZWxmLm1vZGVsJTIwJTNEJTIwbW9kZWwlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzZWxmLnRlbXBsYXRlX2NsaWVudCUyMCUzRCUyMFRlbXBsYXRlTW9kZWxQcm92aWRlcihhcGlfa2V5JTNELi4uKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYudGVtcGxhdGVfdG9vbHMlMjAlM0QlMjBsaXN0KHNlbGYuc3RhbmRhcmRfdG9vbHMudmFsdWVzKCkpJTBBJTBBJTIwJTIwJTIwJTIwYXN5bmMlMjBkZWYlMjBfZ2V0X2xsbV9kZWNpc2lvbihzZWxmJTJDJTIwYmF0dGxlX3N0YXRlJTNBJTIwc3RyKSUyMC0lM0UlMjBEaWN0JTVCc3RyJTJDJTIwQW55JTVEJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyJTIyJTIyU2VuZHMlMjBzdGF0ZSUyMHRvJTIwdGhlJTIwTExNJTIwYW5kJTIwZ2V0cyUyMGJhY2slMjB0aGUlMjBmdW5jdGlvbiUyMGNhbGwlMjBkZWNpc2lvbi4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzeXN0ZW1fcHJvbXB0JTIwJTNEJTIwKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMllvdSUyMGFyZSUyMGElMjAuLi4lMjIlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdXNlcl9wcm9tcHQlMjAlM0QlMjBmJTIyLi4uJTIyJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwdHJ5JTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmVzcG9uc2UlMjAlM0QlMjBhd2FpdCUyMHNlbGYudGVtcGxhdGVfY2xpZW50LmNoYXQuY29tcGxldGlvbnMuY3JlYXRlKCUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1vZGVsJTNEc2VsZi5tb2RlbCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1lc3NhZ2VzJTNEJTVCJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTIycm9sZSUyMiUzQSUyMCUyMnN5c3RlbSUyMiUyQyUyMCUyMmNvbnRlbnQlMjIlM0ElMjBzeXN0ZW1fcHJvbXB0JTdEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTdCJTIycm9sZSUyMiUzQSUyMCUyMnVzZXIlMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwdXNlcl9wcm9tcHQlN0QlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlNUQlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjApJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwbWVzc2FnZSUyMCUzRCUyMHJlc3BvbnNlLmNob2ljZXMlNUIwJTVELm1lc3NhZ2UlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlN0IlMjJkZWNpc2lvbiUyMiUzQSUyMCU3QiUyMm5hbWUlMjIlM0ElMjBmdW5jdGlvbl9uYW1lJTJDJTIwJTIyYXJndW1lbnRzJTIyJTNBJTIwYXJndW1lbnRzJTdEJTdEJTBBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwZXhjZXB0JTIwRXhjZXB0aW9uJTIwYXMlMjBlJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcHJpbnQoZiUyMlVuZXhwZWN0ZWQlMjBlcnJvciUyMGR1cmluZyUyMGNhbGwlM0ElMjAlN0JlJTdEJTIyKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJldHVybiUyMCU3QiUyMmVycm9yJTIyJTNBJTIwZiUyMlVuZXhwZWN0ZWQlMjBlcnJvciUzQSUyMCU3QmUlN0QlMjIlN0Q=",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;Uses Template AI API for decisions.&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;Sends state to the LLM and gets back the function call decision.&quot;&quot;&quot;</span>
        system_prompt = (
            <span class="hljs-string">&quot;You are a ...&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;Unexpected error during call: <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;Unexpected error: <span class="hljs-subst">{e}</span>&quot;</span>}`,wrap:!1}}),P=new ms({props:{source:"https://github.com/huggingface/agents-course/blob/main/units/fr/bonus-unit3/building_your_pokemon_agent.mdx"}}),{c(){i=n("meta"),ll=t(),D=n("p"),sl=t(),U(A.$$.fragment),Ml=t(),C=n("p"),C.innerHTML=Ql,el=t(),c=n("p"),c.textContent=Xl,tl=t(),I=n("ul"),I.innerHTML=Vl,al=t(),m=n("p"),m.textContent=ql,nl=t(),U(r.$$.fragment),jl=t(),u=n("p"),u.innerHTML=zl,yl=t(),b=n("p"),b.innerHTML=xl,Ul=t(),h=n("p"),h.innerHTML=Rl,ol=t(),d=n("p"),d.innerHTML=Fl,pl=t(),U(f.$$.fragment),Jl=t(),v=n("p"),v.innerHTML=Ll,Tl=t(),_=n("p"),_.textContent=Hl,wl=t(),B=n("p"),B.innerHTML=$l,il=t(),U(Z.$$.fragment),Al=t(),G=n("p"),G.innerHTML=Pl,Cl=t(),k=n("p"),k.innerHTML=Kl,cl=t(),N=n("ul"),N.innerHTML=Dl,Il=t(),E=n("p"),E.textContent=Ol,ml=t(),U(g.$$.fragment),rl=t(),W=n("ul"),W.innerHTML=ls,ul=t(),U(S.$$.fragment),bl=t(),Y=n("ul"),Y.innerHTML=ss,hl=t(),Q=n("p"),Q.textContent=Ms,dl=t(),U(X.$$.fragment),fl=t(),V=n("p"),V.innerHTML=es,vl=t(),U(q.$$.fragment),_l=t(),z=n("p"),z.innerHTML=ts,Bl=t(),x=n("p"),x.innerHTML=as,Zl=t(),R=n("p"),R.textContent=ns,Gl=t(),U(F.$$.fragment),kl=t(),L=n("p"),L.textContent=js,Nl=t(),H=n("p"),H.textContent=ys,El=t(),$=n("p"),$.textContent=Us,gl=t(),U(P.$$.fragment),Wl=t(),O=n("p"),this.h()},l(l){const s=cs("svelte-u9bgzb",document.head);i=j(s,"META",{name:!0,content:!0}),s.forEach(M),ll=a(l),D=j(l,"P",{}),os(D).forEach(M),sl=a(l),o(A.$$.fragment,l),Ml=a(l),C=j(l,"P",{"data-svelte-h":!0}),y(C)!=="svelte-1iq737v"&&(C.innerHTML=Ql),el=a(l),c=j(l,"P",{"data-svelte-h":!0}),y(c)!=="svelte-1w30ga3"&&(c.textContent=Xl),tl=a(l),I=j(l,"UL",{"data-svelte-h":!0}),y(I)!=="svelte-3j2rn0"&&(I.innerHTML=Vl),al=a(l),m=j(l,"P",{"data-svelte-h":!0}),y(m)!=="svelte-exm2qv"&&(m.textContent=ql),nl=a(l),o(r.$$.fragment,l),jl=a(l),u=j(l,"P",{"data-svelte-h":!0}),y(u)!=="svelte-a0rkmd"&&(u.innerHTML=zl),yl=a(l),b=j(l,"P",{"data-svelte-h":!0}),y(b)!=="svelte-1y5pwo3"&&(b.innerHTML=xl),Ul=a(l),h=j(l,"P",{"data-svelte-h":!0}),y(h)!=="svelte-1j5eevq"&&(h.innerHTML=Rl),ol=a(l),d=j(l,"P",{"data-svelte-h":!0}),y(d)!=="svelte-1fgpek"&&(d.innerHTML=Fl),pl=a(l),o(f.$$.fragment,l),Jl=a(l),v=j(l,"P",{"data-svelte-h":!0}),y(v)!=="svelte-ik564a"&&(v.innerHTML=Ll),Tl=a(l),_=j(l,"P",{"data-svelte-h":!0}),y(_)!=="svelte-1pn0ap7"&&(_.textContent=Hl),wl=a(l),B=j(l,"P",{"data-svelte-h":!0}),y(B)!=="svelte-ze2ab1"&&(B.innerHTML=$l),il=a(l),o(Z.$$.fragment,l),Al=a(l),G=j(l,"P",{"data-svelte-h":!0}),y(G)!=="svelte-117r6ko"&&(G.innerHTML=Pl),Cl=a(l),k=j(l,"P",{"data-svelte-h":!0}),y(k)!=="svelte-11a3y6o"&&(k.innerHTML=Kl),cl=a(l),N=j(l,"UL",{"data-svelte-h":!0}),y(N)!=="svelte-143qr66"&&(N.innerHTML=Dl),Il=a(l),E=j(l,"P",{"data-svelte-h":!0}),y(E)!=="svelte-18f7si8"&&(E.textContent=Ol),ml=a(l),o(g.$$.fragment,l),rl=a(l),W=j(l,"UL",{"data-svelte-h":!0}),y(W)!=="svelte-1e3ili8"&&(W.innerHTML=ls),ul=a(l),o(S.$$.fragment,l),bl=a(l),Y=j(l,"UL",{"data-svelte-h":!0}),y(Y)!=="svelte-118z7tx"&&(Y.innerHTML=ss),hl=a(l),Q=j(l,"P",{"data-svelte-h":!0}),y(Q)!=="svelte-751o44"&&(Q.textContent=Ms),dl=a(l),o(X.$$.fragment,l),fl=a(l),V=j(l,"P",{"data-svelte-h":!0}),y(V)!=="svelte-yyn6ov"&&(V.innerHTML=es),vl=a(l),o(q.$$.fragment,l),_l=a(l),z=j(l,"P",{"data-svelte-h":!0}),y(z)!=="svelte-1phwj2h"&&(z.innerHTML=ts),Bl=a(l),x=j(l,"P",{"data-svelte-h":!0}),y(x)!=="svelte-1jn70cw"&&(x.innerHTML=as),Zl=a(l),R=j(l,"P",{"data-svelte-h":!0}),y(R)!=="svelte-z3uu5k"&&(R.textContent=ns),Gl=a(l),o(F.$$.fragment,l),kl=a(l),L=j(l,"P",{"data-svelte-h":!0}),y(L)!=="svelte-whn2nw"&&(L.textContent=js),Nl=a(l),H=j(l,"P",{"data-svelte-h":!0}),y(H)!=="svelte-1s6hwk"&&(H.textContent=ys),El=a(l),$=j(l,"P",{"data-svelte-h":!0}),y($)!=="svelte-osxebq"&&($.textContent=Us),gl=a(l),o(P.$$.fragment,l),Wl=a(l),O=j(l,"P",{}),os(O).forEach(M),this.h()},h(){ps(i,"name","hf:doc:metadata"),ps(i,"content",us)},m(l,s){Is(document.head,i),e(l,ll,s),e(l,D,s),e(l,sl,s),p(A,l,s),e(l,Ml,s),e(l,C,s),e(l,el,s),e(l,c,s),e(l,tl,s),e(l,I,s),e(l,al,s),e(l,m,s),e(l,nl,s),p(r,l,s),e(l,jl,s),e(l,u,s),e(l,yl,s),e(l,b,s),e(l,Ul,s),e(l,h,s),e(l,ol,s),e(l,d,s),e(l,pl,s),p(f,l,s),e(l,Jl,s),e(l,v,s),e(l,Tl,s),e(l,_,s),e(l,wl,s),e(l,B,s),e(l,il,s),p(Z,l,s),e(l,Al,s),e(l,G,s),e(l,Cl,s),e(l,k,s),e(l,cl,s),e(l,N,s),e(l,Il,s),e(l,E,s),e(l,ml,s),p(g,l,s),e(l,rl,s),e(l,W,s),e(l,ul,s),p(S,l,s),e(l,bl,s),e(l,Y,s),e(l,hl,s),e(l,Q,s),e(l,dl,s),p(X,l,s),e(l,fl,s),e(l,V,s),e(l,vl,s),p(q,l,s),e(l,_l,s),e(l,z,s),e(l,Bl,s),e(l,x,s),e(l,Zl,s),e(l,R,s),e(l,Gl,s),p(F,l,s),e(l,kl,s),e(l,L,s),e(l,Nl,s),e(l,H,s),e(l,El,s),e(l,$,s),e(l,gl,s),p(P,l,s),e(l,Wl,s),e(l,O,s),Sl=!0},p:ws,i(l){Sl||(J(A.$$.fragment,l),J(r.$$.fragment,l),J(f.$$.fragment,l),J(Z.$$.fragment,l),J(g.$$.fragment,l),J(S.$$.fragment,l),J(X.$$.fragment,l),J(q.$$.fragment,l),J(F.$$.fragment,l),J(P.$$.fragment,l),Sl=!0)},o(l){T(A.$$.fragment,l),T(r.$$.fragment,l),T(f.$$.fragment,l),T(Z.$$.fragment,l),T(g.$$.fragment,l),T(S.$$.fragment,l),T(X.$$.fragment,l),T(q.$$.fragment,l),T(F.$$.fragment,l),T(P.$$.fragment,l),Sl=!1},d(l){l&&(M(ll),M(D),M(sl),M(Ml),M(C),M(el),M(c),M(tl),M(I),M(al),M(m),M(nl),M(jl),M(u),M(yl),M(b),M(Ul),M(h),M(ol),M(d),M(pl),M(Jl),M(v),M(Tl),M(_),M(wl),M(B),M(il),M(Al),M(G),M(Cl),M(k),M(cl),M(N),M(Il),M(E),M(ml),M(rl),M(W),M(ul),M(bl),M(Y),M(hl),M(Q),M(dl),M(fl),M(V),M(vl),M(_l),M(z),M(Bl),M(x),M(Zl),M(R),M(Gl),M(kl),M(L),M(Nl),M(H),M(El),M($),M(gl),M(Wl),M(O)),M(i),w(A,l),w(r,l),w(f,l),w(Z,l),w(g,l),w(S,l),w(X,l),w(q,l),w(F,l),w(P,l)}}}const us='{"title":"Construisez votre propre Agent de Combat Pokémon","local":"construisez-votre-propre-agent-de-combat-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":"🧠 Logique centrale","local":"-logique-centrale","sections":[],"depth":3},{"title":"🔧 Méthodes internes clés","local":"-méthodes-internes-clés","sections":[],"depth":3}],"depth":2},{"title":"🧪 TemplateAgent","local":"-templateagent","sections":[],"depth":2}],"depth":1}';function bs(Yl){return is(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class Bs extends As{constructor(i){super(),Cs(this,i,bs,rs,Ts,{})}}export{Bs as component};
