Spaces:
Running
Running
Update agents.py
Browse files
agents.py
CHANGED
@@ -1,32 +1,37 @@
|
|
|
|
1 |
import os
|
2 |
import json
|
3 |
import asyncio
|
4 |
import random
|
5 |
from openai import AsyncOpenAI # Use AsyncOpenAI for async compatibility with poke-env
|
6 |
|
|
|
7 |
from poke_env.player import Player
|
8 |
from poke_env.environment.battle import Battle
|
9 |
from poke_env.environment.move import Move
|
10 |
from poke_env.environment.pokemon import Pokemon
|
11 |
-
from poke_env.player import
|
12 |
-
|
13 |
|
14 |
|
15 |
class OpenAIAgent(Player):
|
16 |
"""
|
17 |
An AI agent for Pokemon Showdown that uses OpenAI's API
|
18 |
with function calling to decide its moves.
|
|
|
19 |
"""
|
20 |
def __init__(self, *args, **kwargs):
|
|
|
21 |
super().__init__(*args, **kwargs)
|
22 |
|
23 |
# Initialize OpenAI client
|
|
|
24 |
api_key = os.environ["OPENAI_API_KEY"]
|
25 |
if not api_key:
|
26 |
-
raise ValueError("OPENAI_API_KEY environment variable not set.")
|
|
|
27 |
# Use AsyncOpenAI for compatibility with poke-env's async nature
|
28 |
self.openai_client = AsyncOpenAI(api_key=api_key)
|
29 |
-
self.model = "gpt-4o" # Or "gpt-
|
30 |
|
31 |
# Define the functions OpenAI can "call"
|
32 |
self.functions = [
|
@@ -59,10 +64,10 @@ class OpenAIAgent(Player):
|
|
59 |
},
|
60 |
},
|
61 |
]
|
|
|
62 |
|
63 |
def _format_battle_state(self, battle: Battle) -> str:
|
64 |
"""Formats the current battle state into a string for the LLM."""
|
65 |
-
|
66 |
# Own active Pokemon details
|
67 |
active_pkmn = battle.active_pokemon
|
68 |
active_pkmn_info = f"Your active Pokemon: {active_pkmn.species} " \
|
@@ -176,8 +181,8 @@ class OpenAIAgent(Player):
|
|
176 |
"""
|
177 |
# 1. Format battle state
|
178 |
battle_state_str = self._format_battle_state(battle)
|
179 |
-
# print(f"\n--- Turn {battle.turn} ---")
|
180 |
-
# print(battle_state_str) #
|
181 |
|
182 |
# 2. Get decision from OpenAI
|
183 |
decision = await self._get_openai_decision(battle_state_str)
|
@@ -217,7 +222,8 @@ class OpenAIAgent(Player):
|
|
217 |
# Ensure options exist before choosing randomly
|
218 |
available_options = battle.available_moves + battle.available_switches
|
219 |
if available_options:
|
|
|
220 |
return self.choose_random_move(battle)
|
221 |
else:
|
222 |
# Should only happen if forced to Struggle
|
223 |
-
return self.choose_default_move(battle)
|
|
|
1 |
+
# agent.py
|
2 |
import os
|
3 |
import json
|
4 |
import asyncio
|
5 |
import random
|
6 |
from openai import AsyncOpenAI # Use AsyncOpenAI for async compatibility with poke-env
|
7 |
|
8 |
+
# Import necessary poke-env components for type hinting and functionality
|
9 |
from poke_env.player import Player
|
10 |
from poke_env.environment.battle import Battle
|
11 |
from poke_env.environment.move import Move
|
12 |
from poke_env.environment.pokemon import Pokemon
|
13 |
+
from poke_env.player import Observation # Observation might not be directly used here, but good to keep if extending
|
|
|
14 |
|
15 |
|
16 |
class OpenAIAgent(Player):
|
17 |
"""
|
18 |
An AI agent for Pokemon Showdown that uses OpenAI's API
|
19 |
with function calling to decide its moves.
|
20 |
+
Requires OPENAI_API_KEY environment variable to be set.
|
21 |
"""
|
22 |
def __init__(self, *args, **kwargs):
|
23 |
+
# Pass account_configuration and other Player args/kwargs to the parent
|
24 |
super().__init__(*args, **kwargs)
|
25 |
|
26 |
# Initialize OpenAI client
|
27 |
+
# It's slightly better practice to get the key here rather than relying solely on the global env scope
|
28 |
api_key = os.environ["OPENAI_API_KEY"]
|
29 |
if not api_key:
|
30 |
+
raise ValueError("OPENAI_API_KEY environment variable not set or loaded.")
|
31 |
+
|
32 |
# Use AsyncOpenAI for compatibility with poke-env's async nature
|
33 |
self.openai_client = AsyncOpenAI(api_key=api_key)
|
34 |
+
self.model = "gpt-4o" # Or "gpt-3.5-turbo", "gpt-4-turbo-preview", etc.
|
35 |
|
36 |
# Define the functions OpenAI can "call"
|
37 |
self.functions = [
|
|
|
64 |
},
|
65 |
},
|
66 |
]
|
67 |
+
self.battle_history = [] # Optional: To potentially add context later
|
68 |
|
69 |
def _format_battle_state(self, battle: Battle) -> str:
|
70 |
"""Formats the current battle state into a string for the LLM."""
|
|
|
71 |
# Own active Pokemon details
|
72 |
active_pkmn = battle.active_pokemon
|
73 |
active_pkmn_info = f"Your active Pokemon: {active_pkmn.species} " \
|
|
|
181 |
"""
|
182 |
# 1. Format battle state
|
183 |
battle_state_str = self._format_battle_state(battle)
|
184 |
+
# print(f"\n--- Turn {battle.turn} ---") # Debugging
|
185 |
+
# print(battle_state_str) # Debugging
|
186 |
|
187 |
# 2. Get decision from OpenAI
|
188 |
decision = await self._get_openai_decision(battle_state_str)
|
|
|
222 |
# Ensure options exist before choosing randomly
|
223 |
available_options = battle.available_moves + battle.available_switches
|
224 |
if available_options:
|
225 |
+
# Use the built-in random choice method from Player for fallback
|
226 |
return self.choose_random_move(battle)
|
227 |
else:
|
228 |
# Should only happen if forced to Struggle
|
229 |
+
return self.choose_default_move(battle)
|