import{s as Ts,n as ws,o as is}from"../chunks/scheduler.37c15a92.js";import{S as Cs,i as As,g as n,s as a,r as U,A as cs,h as j,f as M,c as t,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.0aa3753f.js";function rs(Yl){let i,ll,D,sl,C,Ml,A,Xl="Maintenant que vous avez exploré le potentiel et les limitations de l’IA agentique dans les jeux vidéos, il est temps de passer à la pratique. Dans cette section, vous allez <strong>construire votre propre agent pour combattre dans un combat au tour par tour dans le style de Pokémon</strong>, en utilisant tout ce que vous avez appris à travers le cours.",el,c,Vl="Nous décomposerons le système en quatre blocs de construction clés :",al,I,Ql="<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 combattra.</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 <em>template</em> de démarrage que vous compléterez pour créer votre propre agent de combat personnalisé.</p></li>",tl,m,zl="Explorons chacun de ces composants plus en détail.",nl,r,jl,u,ql='<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, le 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 de combat !",wl,Z,$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,B,Cl,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.`,Al,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> : 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,X,Ms="Voici un extrait montrant comment cette prise de décision fonctionne :",dl,V,fl,Q,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,z,_l,q,as="Maintenant vient la partie amusante ! Avec <code>LLMAgentBase</code> comme fondation, il est temps d’implémenter votre propre agent, avec votre propre stratégie pour grimper dans le classement.",Zl,x,ts='Vous commencerez à partir de ce <em>template</em> 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.',Bl,R,ns="Voici une version simplifiée du <em>template</em> :",Gl,F,kl,L,js="Ce code ne fonctionnera pas directement, c’est un plan pour votre cas personnalisé.",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 C=new K({props:{title:"Construire un agent de combat Pokémon",local:"construire-un-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"}}),B=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"}}),V=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}}),z=new K({props:{title:"🧪 TemplateAgent",local:"-templateagent",headingTag:"h2"}}),F=new Js({props:{code:"Y2xhc3MlMjBUZW1wbGF0ZUFnZW50KExMTUFnZW50QmFzZSklM0ElMEElMjAlMjAlMjAlMjAlMjIlMjIlMjJVdGlsaXNlJTIwbCdBUEklMjBUZW1wbGF0ZSUyMEFJJTIwcG91ciUyMHByZW5kcmUlMjBkZXMlMjBkJUMzJUE5Y2lzaW9ucy4lMjIlMjIlMjIlMEElMjAlMjAlMjAlMjBkZWYlMjBfX2luaXRfXyhzZWxmJTJDJTIwYXBpX2tleSUzQSUyMHN0ciUyMCUzRCUyME5vbmUlMkMlMjBtb2RlbCUzQSUyMHN0ciUyMCUzRCUyMCUyMm1vZGVsLW5hbWUlMjIlMkMlMjAqYXJncyUyQyUyMCoqa3dhcmdzKSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHN1cGVyKCkuX19pbml0X18oKmFyZ3MlMkMlMjAqKmt3YXJncyklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzZWxmLm1vZGVsJTIwJTNEJTIwbW9kZWwlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBzZWxmLnRlbXBsYXRlX2NsaWVudCUyMCUzRCUyMFRlbXBsYXRlTW9kZWxQcm92aWRlcihhcGlfa2V5JTNELi4uKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHNlbGYudGVtcGxhdGVfdG9vbHMlMjAlM0QlMjBsaXN0KHNlbGYuc3RhbmRhcmRfdG9vbHMudmFsdWVzKCkpJTBBJTBBJTIwJTIwJTIwJTIwYXN5bmMlMjBkZWYlMjBfZ2V0X2xsbV9kZWNpc2lvbihzZWxmJTJDJTIwYmF0dGxlX3N0YXRlJTNBJTIwc3RyKSUyMC0lM0UlMjBEaWN0JTVCc3RyJTJDJTIwQW55JTVEJTNBJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIyJTIyJTIyRW52b2llJTIwbCclQzMlQTl0YXQlMjBhdSUyMExMTSUyMGV0JTIwcmUlQzMlQTdvaXQlMjBlbiUyMHJldG91ciUyMGxhJTIwZCVDMyVBOWNpc2lvbiUyMHJlbGF0aXZlJTIwJUMzJUEwJTIwbCdhcHBlbCUyMGRlJTIwZm9uY3Rpb24uJTIyJTIyJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwc3lzdGVtX3Byb21wdCUyMCUzRCUyMCglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjJZb3UlMjBhcmUlMjBhJTIwLi4uJTIyJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHVzZXJfcHJvbXB0JTIwJTNEJTIwZiUyMi4uLiUyMiUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHRyeSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHJlc3BvbnNlJTIwJTNEJTIwYXdhaXQlMjBzZWxmLnRlbXBsYXRlX2NsaWVudC5jaGF0LmNvbXBsZXRpb25zLmNyZWF0ZSglMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBtb2RlbCUzRHNlbGYubW9kZWwlMkMlMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjBtZXNzYWdlcyUzRCU1QiUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUyMnJvbGUlMjIlM0ElMjAlMjJzeXN0ZW0lMjIlMkMlMjAlMjJjb250ZW50JTIyJTNBJTIwc3lzdGVtX3Byb21wdCU3RCUyQyUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU3QiUyMnJvbGUlMjIlM0ElMjAlMjJ1c2VyJTIyJTJDJTIwJTIyY29udGVudCUyMiUzQSUyMHVzZXJfcHJvbXB0JTdEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTVEJTJDJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwKSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMG1lc3NhZ2UlMjAlM0QlMjByZXNwb25zZS5jaG9pY2VzJTVCMCU1RC5tZXNzYWdlJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTBBJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwcmV0dXJuJTIwJTdCJTIyZGVjaXNpb24lMjIlM0ElMjAlN0IlMjJuYW1lJTIyJTNBJTIwZnVuY3Rpb25fbmFtZSUyQyUyMCUyMmFyZ3VtZW50cyUyMiUzQSUyMGFyZ3VtZW50cyU3RCU3RCUwQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMGV4Y2VwdCUyMEV4Y2VwdGlvbiUyMGFzJTIwZSUzQSUwQSUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMHByaW50KGYlMjJVbmV4cGVjdGVkJTIwZXJyb3IlMjBkdXJpbmclMjBjYWxsJTNBJTIwJTdCZSU3RCUyMiklMEElMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjAlMjByZXR1cm4lMjAlN0IlMjJlcnJvciUyMiUzQSUyMGYlMjJVbmV4cGVjdGVkJTIwZXJyb3IlM0ElMjAlN0JlJTdEJTIyJTdE",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;Utilise l&#x27;API Template AI pour prendre des décisions.&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;Envoie l&#x27;état au LLM et reçoit en retour la décision relative à l&#x27;appel de fonction.&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=a(),D=n("p"),sl=a(),U(C.$$.fragment),Ml=a(),A=n("p"),A.innerHTML=Xl,el=a(),c=n("p"),c.textContent=Vl,al=a(),I=n("ul"),I.innerHTML=Ql,tl=a(),m=n("p"),m.textContent=zl,nl=a(),U(r.$$.fragment),jl=a(),u=n("p"),u.innerHTML=ql,yl=a(),b=n("p"),b.innerHTML=xl,Ul=a(),h=n("p"),h.innerHTML=Rl,ol=a(),d=n("p"),d.innerHTML=Fl,pl=a(),U(f.$$.fragment),Jl=a(),v=n("p"),v.innerHTML=Ll,Tl=a(),_=n("p"),_.textContent=Hl,wl=a(),Z=n("p"),Z.innerHTML=$l,il=a(),U(B.$$.fragment),Cl=a(),G=n("p"),G.innerHTML=Pl,Al=a(),k=n("p"),k.innerHTML=Kl,cl=a(),N=n("ul"),N.innerHTML=Dl,Il=a(),E=n("p"),E.textContent=Ol,ml=a(),U(g.$$.fragment),rl=a(),W=n("ul"),W.innerHTML=ls,ul=a(),U(S.$$.fragment),bl=a(),Y=n("ul"),Y.innerHTML=ss,hl=a(),X=n("p"),X.textContent=Ms,dl=a(),U(V.$$.fragment),fl=a(),Q=n("p"),Q.innerHTML=es,vl=a(),U(z.$$.fragment),_l=a(),q=n("p"),q.innerHTML=as,Zl=a(),x=n("p"),x.innerHTML=ts,Bl=a(),R=n("p"),R.innerHTML=ns,Gl=a(),U(F.$$.fragment),kl=a(),L=n("p"),L.textContent=js,Nl=a(),H=n("p"),H.textContent=ys,El=a(),$=n("p"),$.textContent=Us,gl=a(),U(P.$$.fragment),Wl=a(),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=t(l),D=j(l,"P",{}),os(D).forEach(M),sl=t(l),o(C.$$.fragment,l),Ml=t(l),A=j(l,"P",{"data-svelte-h":!0}),y(A)!=="svelte-wmfs0g"&&(A.innerHTML=Xl),el=t(l),c=j(l,"P",{"data-svelte-h":!0}),y(c)!=="svelte-1w30ga3"&&(c.textContent=Vl),al=t(l),I=j(l,"UL",{"data-svelte-h":!0}),y(I)!=="svelte-1dz3dmc"&&(I.innerHTML=Ql),tl=t(l),m=j(l,"P",{"data-svelte-h":!0}),y(m)!=="svelte-exm2qv"&&(m.textContent=zl),nl=t(l),o(r.$$.fragment,l),jl=t(l),u=j(l,"P",{"data-svelte-h":!0}),y(u)!=="svelte-a0rkmd"&&(u.innerHTML=ql),yl=t(l),b=j(l,"P",{"data-svelte-h":!0}),y(b)!=="svelte-11u8ybn"&&(b.innerHTML=xl),Ul=t(l),h=j(l,"P",{"data-svelte-h":!0}),y(h)!=="svelte-py24ty"&&(h.innerHTML=Rl),ol=t(l),d=j(l,"P",{"data-svelte-h":!0}),y(d)!=="svelte-1fgpek"&&(d.innerHTML=Fl),pl=t(l),o(f.$$.fragment,l),Jl=t(l),v=j(l,"P",{"data-svelte-h":!0}),y(v)!=="svelte-1387zj3"&&(v.innerHTML=Ll),Tl=t(l),_=j(l,"P",{"data-svelte-h":!0}),y(_)!=="svelte-14ed5ah"&&(_.textContent=Hl),wl=t(l),Z=j(l,"P",{"data-svelte-h":!0}),y(Z)!=="svelte-ze2ab1"&&(Z.innerHTML=$l),il=t(l),o(B.$$.fragment,l),Cl=t(l),G=j(l,"P",{"data-svelte-h":!0}),y(G)!=="svelte-117r6ko"&&(G.innerHTML=Pl),Al=t(l),k=j(l,"P",{"data-svelte-h":!0}),y(k)!=="svelte-11a3y6o"&&(k.innerHTML=Kl),cl=t(l),N=j(l,"UL",{"data-svelte-h":!0}),y(N)!=="svelte-143qr66"&&(N.innerHTML=Dl),Il=t(l),E=j(l,"P",{"data-svelte-h":!0}),y(E)!=="svelte-18f7si8"&&(E.textContent=Ol),ml=t(l),o(g.$$.fragment,l),rl=t(l),W=j(l,"UL",{"data-svelte-h":!0}),y(W)!=="svelte-1hjv8jo"&&(W.innerHTML=ls),ul=t(l),o(S.$$.fragment,l),bl=t(l),Y=j(l,"UL",{"data-svelte-h":!0}),y(Y)!=="svelte-118z7tx"&&(Y.innerHTML=ss),hl=t(l),X=j(l,"P",{"data-svelte-h":!0}),y(X)!=="svelte-751o44"&&(X.textContent=Ms),dl=t(l),o(V.$$.fragment,l),fl=t(l),Q=j(l,"P",{"data-svelte-h":!0}),y(Q)!=="svelte-yyn6ov"&&(Q.innerHTML=es),vl=t(l),o(z.$$.fragment,l),_l=t(l),q=j(l,"P",{"data-svelte-h":!0}),y(q)!=="svelte-4gn3eb"&&(q.innerHTML=as),Zl=t(l),x=j(l,"P",{"data-svelte-h":!0}),y(x)!=="svelte-bw746n"&&(x.innerHTML=ts),Bl=t(l),R=j(l,"P",{"data-svelte-h":!0}),y(R)!=="svelte-13ktzb7"&&(R.innerHTML=ns),Gl=t(l),o(F.$$.fragment,l),kl=t(l),L=j(l,"P",{"data-svelte-h":!0}),y(L)!=="svelte-1khl54i"&&(L.textContent=js),Nl=t(l),H=j(l,"P",{"data-svelte-h":!0}),y(H)!=="svelte-1s6hwk"&&(H.textContent=ys),El=t(l),$=j(l,"P",{"data-svelte-h":!0}),y($)!=="svelte-osxebq"&&($.textContent=Us),gl=t(l),o(P.$$.fragment,l),Wl=t(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(C,l,s),e(l,Ml,s),e(l,A,s),e(l,el,s),e(l,c,s),e(l,al,s),e(l,I,s),e(l,tl,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,Z,s),e(l,il,s),p(B,l,s),e(l,Cl,s),e(l,G,s),e(l,Al,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,X,s),e(l,dl,s),p(V,l,s),e(l,fl,s),e(l,Q,s),e(l,vl,s),p(z,l,s),e(l,_l,s),e(l,q,s),e(l,Zl,s),e(l,x,s),e(l,Bl,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(C.$$.fragment,l),J(r.$$.fragment,l),J(f.$$.fragment,l),J(B.$$.fragment,l),J(g.$$.fragment,l),J(S.$$.fragment,l),J(V.$$.fragment,l),J(z.$$.fragment,l),J(F.$$.fragment,l),J(P.$$.fragment,l),Sl=!0)},o(l){T(C.$$.fragment,l),T(r.$$.fragment,l),T(f.$$.fragment,l),T(B.$$.fragment,l),T(g.$$.fragment,l),T(S.$$.fragment,l),T(V.$$.fragment,l),T(z.$$.fragment,l),T(F.$$.fragment,l),T(P.$$.fragment,l),Sl=!1},d(l){l&&(M(ll),M(D),M(sl),M(Ml),M(A),M(el),M(c),M(al),M(I),M(tl),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(Z),M(il),M(Cl),M(G),M(Al),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(X),M(dl),M(fl),M(Q),M(vl),M(_l),M(q),M(Zl),M(x),M(Bl),M(R),M(Gl),M(kl),M(L),M(Nl),M(H),M(El),M($),M(gl),M(Wl),M(O)),M(i),w(C,l),w(r,l),w(f,l),w(B,l),w(g,l),w(S,l),w(V,l),w(z,l),w(F,l),w(P,l)}}}const us='{"title":"Construire un agent de combat Pokémon","local":"construire-un-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 Zs extends Cs{constructor(i){super(),As(this,i,bs,rs,Ts,{})}}export{Zs as component};
