import{s as is,n as Cs,o as As}from"../chunks/scheduler.505acc25.js";import{S as cs,i as ms,e as n,s as a,c as U,h as Is,a as j,d as M,b as t,f as Js,g as p,j as y,k as Ts,l as rs,m as e,n as o,t as J,o as T,p as w}from"../chunks/index.b1175496.js";import{C as us,H as D}from"../chunks/Heading.988e52fa.js";import{C as ws}from"../chunks/CodeBlock.ed64aebc.js";import{E as bs}from"../chunks/MermaidChart.svelte_svelte_type_style_lang.3d47a398.js";function hs(Vl){let i,sl,O,Ml,C,el,A,al,c,Ql="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.",tl,m,zl="Nous décomposerons le système en quatre blocs de construction clés :",nl,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>",jl,r,xl="Explorons chacun de ces composants plus en détail.",yl,u,Ul,b,Rl='<img src="https://github.com/hsahovic/poke-env/raw/master/rl-gif.gif" alt="Battle gif"/>',pl,h,Fl=`<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.`,ol,d,Ll="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.",Jl,f,Hl='<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>',Tl,v,wl,_,$l=`<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.`,il,Z,Pl="Nous avons déployé un serveur que tous les participants utiliseront pour combattre. Voyons qui construit le meilleur agent de combat !",Cl,B,Kl='<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>',Al,G,cl,k,Dl=`<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.`,ml,N,Ol="Cet agent de base fournit un ensemble d’outils (définis dans <code>STANDARD_TOOL_SCHEMA</code>) pour interagir avec l’environnement, incluant :",Il,g,ls="<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>",rl,E,ss="Le LLM devrait utiliser ces outils pour prendre des décisions pendant un match.",ul,W,bl,S,Ms="<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>",hl,Y,dl,X,es="<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>",fl,V,as="Voici un extrait montrant comment cette prise de décision fonctionne :",vl,Q,_l,z,ts='<strong>Code source complet</strong> : <a href="https://huggingface.co/spaces/Jofthomas/twitch_streaming/blob/main/agents.py" rel="nofollow">agents.py</a>',Zl,q,Bl,x,ns="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.",Gl,R,js='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.',kl,F,ys="Voici une version simplifiée du <em>template</em> :",Nl,L,gl,H,Us="Ce code ne fonctionnera pas directement, c’est un plan pour votre cas personnalisé.",El,$,ps="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.",Wl,P,os="Que le combat commence ! 🔥",Sl,K,Yl,ll,Xl;return C=new us({props:{containerStyle:"float: right; margin-left: 10px; display: inline-flex; position: relative; z-index: 10;"}}),A=new D({props:{title:"Construire un agent de combat Pokémon",local:"construire-un-agent-de-combat-pokémon",headingTag:"h1"}}),u=new D({props:{title:"🧠 Poke-env",local:"-poke-env",headingTag:"h2"}}),v=new D({props:{title:"⚔️ Pokémon Showdown",local:"-pokémon-showdown",headingTag:"h2"}}),G=new D({props:{title:"🔌 LLMAgentBase",local:"-llmagentbase",headingTag:"h2"}}),W=new D({props:{title:"🧠 Logique centrale",local:"-logique-centrale",headingTag:"h3"}}),Y=new D({props:{title:"🔧 Méthodes internes clés",local:"-méthodes-internes-clés",headingTag:"h3"}}),Q=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;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 D({props:{title:"🧪 TemplateAgent",local:"-templateagent",headingTag:"h2"}}),L=new ws({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}}),K=new bs({props:{source:"https://github.com/huggingface/agents-course/blob/main/units/fr/bonus-unit3/building_your_pokemon_agent.mdx"}}),{c(){i=n("meta"),sl=a(),O=n("p"),Ml=a(),U(C.$$.fragment),el=a(),U(A.$$.fragment),al=a(),c=n("p"),c.innerHTML=Ql,tl=a(),m=n("p"),m.textContent=zl,nl=a(),I=n("ul"),I.innerHTML=ql,jl=a(),r=n("p"),r.textContent=xl,yl=a(),U(u.$$.fragment),Ul=a(),b=n("p"),b.innerHTML=Rl,pl=a(),h=n("p"),h.innerHTML=Fl,ol=a(),d=n("p"),d.innerHTML=Ll,Jl=a(),f=n("p"),f.innerHTML=Hl,Tl=a(),U(v.$$.fragment),wl=a(),_=n("p"),_.innerHTML=$l,il=a(),Z=n("p"),Z.textContent=Pl,Cl=a(),B=n("p"),B.innerHTML=Kl,Al=a(),U(G.$$.fragment),cl=a(),k=n("p"),k.innerHTML=Dl,ml=a(),N=n("p"),N.innerHTML=Ol,Il=a(),g=n("ul"),g.innerHTML=ls,rl=a(),E=n("p"),E.textContent=ss,ul=a(),U(W.$$.fragment),bl=a(),S=n("ul"),S.innerHTML=Ms,hl=a(),U(Y.$$.fragment),dl=a(),X=n("ul"),X.innerHTML=es,fl=a(),V=n("p"),V.textContent=as,vl=a(),U(Q.$$.fragment),_l=a(),z=n("p"),z.innerHTML=ts,Zl=a(),U(q.$$.fragment),Bl=a(),x=n("p"),x.innerHTML=ns,Gl=a(),R=n("p"),R.innerHTML=js,kl=a(),F=n("p"),F.innerHTML=ys,Nl=a(),U(L.$$.fragment),gl=a(),H=n("p"),H.textContent=Us,El=a(),$=n("p"),$.textContent=ps,Wl=a(),P=n("p"),P.textContent=os,Sl=a(),U(K.$$.fragment),Yl=a(),ll=n("p"),this.h()},l(l){const s=Is("svelte-u9bgzb",document.head);i=j(s,"META",{name:!0,content:!0}),s.forEach(M),sl=t(l),O=j(l,"P",{}),Js(O).forEach(M),Ml=t(l),p(C.$$.fragment,l),el=t(l),p(A.$$.fragment,l),al=t(l),c=j(l,"P",{"data-svelte-h":!0}),y(c)!=="svelte-wmfs0g"&&(c.innerHTML=Ql),tl=t(l),m=j(l,"P",{"data-svelte-h":!0}),y(m)!=="svelte-1w30ga3"&&(m.textContent=zl),nl=t(l),I=j(l,"UL",{"data-svelte-h":!0}),y(I)!=="svelte-1dz3dmc"&&(I.innerHTML=ql),jl=t(l),r=j(l,"P",{"data-svelte-h":!0}),y(r)!=="svelte-exm2qv"&&(r.textContent=xl),yl=t(l),p(u.$$.fragment,l),Ul=t(l),b=j(l,"P",{"data-svelte-h":!0}),y(b)!=="svelte-a0rkmd"&&(b.innerHTML=Rl),pl=t(l),h=j(l,"P",{"data-svelte-h":!0}),y(h)!=="svelte-11u8ybn"&&(h.innerHTML=Fl),ol=t(l),d=j(l,"P",{"data-svelte-h":!0}),y(d)!=="svelte-py24ty"&&(d.innerHTML=Ll),Jl=t(l),f=j(l,"P",{"data-svelte-h":!0}),y(f)!=="svelte-1fgpek"&&(f.innerHTML=Hl),Tl=t(l),p(v.$$.fragment,l),wl=t(l),_=j(l,"P",{"data-svelte-h":!0}),y(_)!=="svelte-1387zj3"&&(_.innerHTML=$l),il=t(l),Z=j(l,"P",{"data-svelte-h":!0}),y(Z)!=="svelte-14ed5ah"&&(Z.textContent=Pl),Cl=t(l),B=j(l,"P",{"data-svelte-h":!0}),y(B)!=="svelte-ze2ab1"&&(B.innerHTML=Kl),Al=t(l),p(G.$$.fragment,l),cl=t(l),k=j(l,"P",{"data-svelte-h":!0}),y(k)!=="svelte-117r6ko"&&(k.innerHTML=Dl),ml=t(l),N=j(l,"P",{"data-svelte-h":!0}),y(N)!=="svelte-11a3y6o"&&(N.innerHTML=Ol),Il=t(l),g=j(l,"UL",{"data-svelte-h":!0}),y(g)!=="svelte-143qr66"&&(g.innerHTML=ls),rl=t(l),E=j(l,"P",{"data-svelte-h":!0}),y(E)!=="svelte-18f7si8"&&(E.textContent=ss),ul=t(l),p(W.$$.fragment,l),bl=t(l),S=j(l,"UL",{"data-svelte-h":!0}),y(S)!=="svelte-1hjv8jo"&&(S.innerHTML=Ms),hl=t(l),p(Y.$$.fragment,l),dl=t(l),X=j(l,"UL",{"data-svelte-h":!0}),y(X)!=="svelte-118z7tx"&&(X.innerHTML=es),fl=t(l),V=j(l,"P",{"data-svelte-h":!0}),y(V)!=="svelte-751o44"&&(V.textContent=as),vl=t(l),p(Q.$$.fragment,l),_l=t(l),z=j(l,"P",{"data-svelte-h":!0}),y(z)!=="svelte-yyn6ov"&&(z.innerHTML=ts),Zl=t(l),p(q.$$.fragment,l),Bl=t(l),x=j(l,"P",{"data-svelte-h":!0}),y(x)!=="svelte-4gn3eb"&&(x.innerHTML=ns),Gl=t(l),R=j(l,"P",{"data-svelte-h":!0}),y(R)!=="svelte-bw746n"&&(R.innerHTML=js),kl=t(l),F=j(l,"P",{"data-svelte-h":!0}),y(F)!=="svelte-13ktzb7"&&(F.innerHTML=ys),Nl=t(l),p(L.$$.fragment,l),gl=t(l),H=j(l,"P",{"data-svelte-h":!0}),y(H)!=="svelte-1khl54i"&&(H.textContent=Us),El=t(l),$=j(l,"P",{"data-svelte-h":!0}),y($)!=="svelte-1s6hwk"&&($.textContent=ps),Wl=t(l),P=j(l,"P",{"data-svelte-h":!0}),y(P)!=="svelte-osxebq"&&(P.textContent=os),Sl=t(l),p(K.$$.fragment,l),Yl=t(l),ll=j(l,"P",{}),Js(ll).forEach(M),this.h()},h(){Ts(i,"name","hf:doc:metadata"),Ts(i,"content",ds)},m(l,s){rs(document.head,i),e(l,sl,s),e(l,O,s),e(l,Ml,s),o(C,l,s),e(l,el,s),o(A,l,s),e(l,al,s),e(l,c,s),e(l,tl,s),e(l,m,s),e(l,nl,s),e(l,I,s),e(l,jl,s),e(l,r,s),e(l,yl,s),o(u,l,s),e(l,Ul,s),e(l,b,s),e(l,pl,s),e(l,h,s),e(l,ol,s),e(l,d,s),e(l,Jl,s),e(l,f,s),e(l,Tl,s),o(v,l,s),e(l,wl,s),e(l,_,s),e(l,il,s),e(l,Z,s),e(l,Cl,s),e(l,B,s),e(l,Al,s),o(G,l,s),e(l,cl,s),e(l,k,s),e(l,ml,s),e(l,N,s),e(l,Il,s),e(l,g,s),e(l,rl,s),e(l,E,s),e(l,ul,s),o(W,l,s),e(l,bl,s),e(l,S,s),e(l,hl,s),o(Y,l,s),e(l,dl,s),e(l,X,s),e(l,fl,s),e(l,V,s),e(l,vl,s),o(Q,l,s),e(l,_l,s),e(l,z,s),e(l,Zl,s),o(q,l,s),e(l,Bl,s),e(l,x,s),e(l,Gl,s),e(l,R,s),e(l,kl,s),e(l,F,s),e(l,Nl,s),o(L,l,s),e(l,gl,s),e(l,H,s),e(l,El,s),e(l,$,s),e(l,Wl,s),e(l,P,s),e(l,Sl,s),o(K,l,s),e(l,Yl,s),e(l,ll,s),Xl=!0},p:Cs,i(l){Xl||(J(C.$$.fragment,l),J(A.$$.fragment,l),J(u.$$.fragment,l),J(v.$$.fragment,l),J(G.$$.fragment,l),J(W.$$.fragment,l),J(Y.$$.fragment,l),J(Q.$$.fragment,l),J(q.$$.fragment,l),J(L.$$.fragment,l),J(K.$$.fragment,l),Xl=!0)},o(l){T(C.$$.fragment,l),T(A.$$.fragment,l),T(u.$$.fragment,l),T(v.$$.fragment,l),T(G.$$.fragment,l),T(W.$$.fragment,l),T(Y.$$.fragment,l),T(Q.$$.fragment,l),T(q.$$.fragment,l),T(L.$$.fragment,l),T(K.$$.fragment,l),Xl=!1},d(l){l&&(M(sl),M(O),M(Ml),M(el),M(al),M(c),M(tl),M(m),M(nl),M(I),M(jl),M(r),M(yl),M(Ul),M(b),M(pl),M(h),M(ol),M(d),M(Jl),M(f),M(Tl),M(wl),M(_),M(il),M(Z),M(Cl),M(B),M(Al),M(cl),M(k),M(ml),M(N),M(Il),M(g),M(rl),M(E),M(ul),M(bl),M(S),M(hl),M(dl),M(X),M(fl),M(V),M(vl),M(_l),M(z),M(Zl),M(Bl),M(x),M(Gl),M(R),M(kl),M(F),M(Nl),M(gl),M(H),M(El),M($),M(Wl),M(P),M(Sl),M(Yl),M(ll)),M(i),w(C,l),w(A,l),w(u,l),w(v,l),w(G,l),w(W,l),w(Y,l),w(Q,l),w(q,l),w(L,l),w(K,l)}}}const ds='{"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 fs(Vl){return As(()=>{new URLSearchParams(window.location.search).get("fw")}),[]}class ks extends cs{constructor(i){super(),ms(this,i,fs,hs,is,{})}}export{ks as component};
