Spaces:
Running
Running
Update main.py
Browse files
main.py
CHANGED
|
@@ -182,14 +182,17 @@ async def select_and_activate_new_agent():
|
|
| 182 |
|
| 183 |
async def check_for_new_battle():
|
| 184 |
"""Checks if the active agent has started a battle with a valid tag."""
|
| 185 |
-
global
|
|
|
|
|
|
|
| 186 |
|
| 187 |
if active_agent_instance:
|
| 188 |
battle = get_active_battle(active_agent_instance)
|
| 189 |
# Check if battle exists AND has a valid battle_tag
|
| 190 |
if battle and battle.battle_tag:
|
| 191 |
-
|
| 192 |
current_battle_instance = battle
|
|
|
|
| 193 |
|
| 194 |
# Stop the agent from listening for more challenges once a battle starts
|
| 195 |
if active_agent_task and not active_agent_task.done():
|
|
@@ -203,7 +206,6 @@ async def check_for_new_battle():
|
|
| 203 |
# else:
|
| 204 |
# print(f"DEBUG: get_active_battle returned None or battle without tag.")
|
| 205 |
|
| 206 |
-
|
| 207 |
async def deactivate_current_agent(reason: str = "cycle"):
|
| 208 |
"""Cleans up the currently active agent and resets state."""
|
| 209 |
global active_agent_name, active_agent_instance, active_agent_task, current_battle_instance
|
|
@@ -279,10 +281,11 @@ async def deactivate_current_agent(reason: str = "cycle"):
|
|
| 279 |
await asyncio.sleep(2) # Reduced from 3, adjust as needed
|
| 280 |
print(f"Lifecycle: Agent '{agent_name_to_deactivate}' deactivation complete.")
|
| 281 |
|
| 282 |
-
# --- Main Background Task ---
|
| 283 |
async def manage_agent_lifecycle():
|
| 284 |
"""Runs the main loop selecting, running, and cleaning up agents sequentially."""
|
| 285 |
-
global
|
|
|
|
|
|
|
| 286 |
|
| 287 |
print("Background lifecycle manager started.")
|
| 288 |
REFRESH_INTERVAL_SECONDS = 3 # How often to check state when idle/in battle
|
|
@@ -301,6 +304,7 @@ async def manage_agent_lifecycle():
|
|
| 301 |
# ==================================
|
| 302 |
# State 1: No agent active
|
| 303 |
# ==================================
|
|
|
|
| 304 |
if active_agent_instance is None:
|
| 305 |
print(f"[{loop_counter}] State 1: No active agent. Selecting...")
|
| 306 |
activated = await select_and_activate_new_agent()
|
|
@@ -308,6 +312,7 @@ async def manage_agent_lifecycle():
|
|
| 308 |
print(f"[{loop_counter}] State 1: Activation failed. Waiting {ERROR_RETRY_DELAY_SECONDS}s before retry.")
|
| 309 |
await asyncio.sleep(ERROR_RETRY_DELAY_SECONDS)
|
| 310 |
else:
|
|
|
|
| 311 |
print(f"[{loop_counter}] State 1: Agent '{active_agent_name}' activated successfully.")
|
| 312 |
# No sleep here, proceed to next check immediately if needed
|
| 313 |
|
|
@@ -315,14 +320,17 @@ async def manage_agent_lifecycle():
|
|
| 315 |
# State 2: Agent is active
|
| 316 |
# ==================================
|
| 317 |
else:
|
|
|
|
| 318 |
agent_name = active_agent_name # Cache for logging
|
| 319 |
print(f"[{loop_counter}] State 2: Agent '{agent_name}' is active.")
|
| 320 |
|
| 321 |
# --- Sub-state: Check for new battle if none is tracked ---
|
|
|
|
| 322 |
if current_battle_instance is None:
|
| 323 |
print(f"[{loop_counter}] State 2a: Checking for new battle for '{agent_name}'...")
|
| 324 |
-
await check_for_new_battle() # This updates current_battle_instance if found
|
| 325 |
|
|
|
|
| 326 |
if current_battle_instance:
|
| 327 |
battle_tag = current_battle_instance.battle_tag
|
| 328 |
print(f"[{loop_counter}] State 2a: *** NEW BATTLE DETECTED: {battle_tag} for '{agent_name}' ***")
|
|
@@ -336,6 +344,7 @@ async def manage_agent_lifecycle():
|
|
| 336 |
print(f"[{loop_counter}] Detected potentially non-public battle format ({battle_tag}). Forfeiting.")
|
| 337 |
# Don't update display yet, do it before deactivation
|
| 338 |
try:
|
|
|
|
| 339 |
if active_agent_instance: # Ensure agent still exists
|
| 340 |
await active_agent_instance.forfeit(battle_tag)
|
| 341 |
# await active_agent_instance.send_message("/forfeit", battle_tag) # Alternative
|
|
@@ -364,11 +373,13 @@ async def manage_agent_lifecycle():
|
|
| 364 |
|
| 365 |
|
| 366 |
# --- Sub-state: Monitor ongoing battle ---
|
|
|
|
| 367 |
if current_battle_instance is not None:
|
| 368 |
battle_tag = current_battle_instance.battle_tag
|
| 369 |
print(f"[{loop_counter}] State 2b: Monitoring battle {battle_tag} for '{agent_name}'")
|
| 370 |
|
| 371 |
# Ensure agent instance still exists before accessing its battles
|
|
|
|
| 372 |
if not active_agent_instance:
|
| 373 |
print(f"[{loop_counter}] WARNING: Agent instance for '{agent_name}' disappeared while monitoring battle {battle_tag}! Deactivating.")
|
| 374 |
await deactivate_current_agent(reason="agent_disappeared_mid_battle")
|
|
@@ -376,6 +387,7 @@ async def manage_agent_lifecycle():
|
|
| 376 |
|
| 377 |
# Get potentially updated battle object directly from agent's state
|
| 378 |
# Use .get() for safety
|
|
|
|
| 379 |
battle_obj = active_agent_instance._battles.get(battle_tag)
|
| 380 |
|
| 381 |
if battle_obj and battle_obj.finished:
|
|
@@ -405,7 +417,9 @@ async def manage_agent_lifecycle():
|
|
| 405 |
except Exception as e:
|
| 406 |
print(f"!!! ERROR in main lifecycle loop #{loop_counter}: {e} !!!")
|
| 407 |
traceback.print_exc()
|
|
|
|
| 408 |
current_agent_name = active_agent_name # Cache name before deactivation attempts
|
|
|
|
| 409 |
if active_agent_instance:
|
| 410 |
print(f"Attempting to deactivate agent '{current_agent_name}' due to loop error...")
|
| 411 |
try:
|
|
@@ -433,7 +447,6 @@ async def manage_agent_lifecycle():
|
|
| 433 |
if elapsed_time < LOOP_COOLDOWN_SECONDS:
|
| 434 |
await asyncio.sleep(LOOP_COOLDOWN_SECONDS - elapsed_time)
|
| 435 |
|
| 436 |
-
|
| 437 |
def log_task_exception(task: asyncio.Task):
|
| 438 |
"""Callback to log exceptions from background tasks (like accept_challenges)."""
|
| 439 |
try:
|
|
|
|
| 182 |
|
| 183 |
async def check_for_new_battle():
|
| 184 |
"""Checks if the active agent has started a battle with a valid tag."""
|
| 185 |
+
# --- FIX: Declare intention to use/modify global variables ---
|
| 186 |
+
global active_agent_instance, current_battle_instance, active_agent_name, active_agent_task
|
| 187 |
+
# -------------------------------------------------------------
|
| 188 |
|
| 189 |
if active_agent_instance:
|
| 190 |
battle = get_active_battle(active_agent_instance)
|
| 191 |
# Check if battle exists AND has a valid battle_tag
|
| 192 |
if battle and battle.battle_tag:
|
| 193 |
+
# This line MODIFIES the global variable
|
| 194 |
current_battle_instance = battle
|
| 195 |
+
print(f"Lifecycle: Agent '{active_agent_name}' started battle: {battle.battle_tag}")
|
| 196 |
|
| 197 |
# Stop the agent from listening for more challenges once a battle starts
|
| 198 |
if active_agent_task and not active_agent_task.done():
|
|
|
|
| 206 |
# else:
|
| 207 |
# print(f"DEBUG: get_active_battle returned None or battle without tag.")
|
| 208 |
|
|
|
|
| 209 |
async def deactivate_current_agent(reason: str = "cycle"):
|
| 210 |
"""Cleans up the currently active agent and resets state."""
|
| 211 |
global active_agent_name, active_agent_instance, active_agent_task, current_battle_instance
|
|
|
|
| 281 |
await asyncio.sleep(2) # Reduced from 3, adjust as needed
|
| 282 |
print(f"Lifecycle: Agent '{agent_name_to_deactivate}' deactivation complete.")
|
| 283 |
|
|
|
|
| 284 |
async def manage_agent_lifecycle():
|
| 285 |
"""Runs the main loop selecting, running, and cleaning up agents sequentially."""
|
| 286 |
+
# --- FIX: Declare intention to use global variables ---
|
| 287 |
+
global active_agent_name, active_agent_instance, active_agent_task, current_battle_instance
|
| 288 |
+
# ------------------------------------------------------
|
| 289 |
|
| 290 |
print("Background lifecycle manager started.")
|
| 291 |
REFRESH_INTERVAL_SECONDS = 3 # How often to check state when idle/in battle
|
|
|
|
| 304 |
# ==================================
|
| 305 |
# State 1: No agent active
|
| 306 |
# ==================================
|
| 307 |
+
# Now Python knows active_agent_instance refers to the global one
|
| 308 |
if active_agent_instance is None:
|
| 309 |
print(f"[{loop_counter}] State 1: No active agent. Selecting...")
|
| 310 |
activated = await select_and_activate_new_agent()
|
|
|
|
| 312 |
print(f"[{loop_counter}] State 1: Activation failed. Waiting {ERROR_RETRY_DELAY_SECONDS}s before retry.")
|
| 313 |
await asyncio.sleep(ERROR_RETRY_DELAY_SECONDS)
|
| 314 |
else:
|
| 315 |
+
# Now Python knows active_agent_name refers to the global one set by select_and_activate_new_agent
|
| 316 |
print(f"[{loop_counter}] State 1: Agent '{active_agent_name}' activated successfully.")
|
| 317 |
# No sleep here, proceed to next check immediately if needed
|
| 318 |
|
|
|
|
| 320 |
# State 2: Agent is active
|
| 321 |
# ==================================
|
| 322 |
else:
|
| 323 |
+
# Now Python knows active_agent_name refers to the global one
|
| 324 |
agent_name = active_agent_name # Cache for logging
|
| 325 |
print(f"[{loop_counter}] State 2: Agent '{agent_name}' is active.")
|
| 326 |
|
| 327 |
# --- Sub-state: Check for new battle if none is tracked ---
|
| 328 |
+
# Now Python knows current_battle_instance refers to the global one
|
| 329 |
if current_battle_instance is None:
|
| 330 |
print(f"[{loop_counter}] State 2a: Checking for new battle for '{agent_name}'...")
|
| 331 |
+
await check_for_new_battle() # This updates global current_battle_instance if found
|
| 332 |
|
| 333 |
+
# Now Python knows current_battle_instance refers to the global one
|
| 334 |
if current_battle_instance:
|
| 335 |
battle_tag = current_battle_instance.battle_tag
|
| 336 |
print(f"[{loop_counter}] State 2a: *** NEW BATTLE DETECTED: {battle_tag} for '{agent_name}' ***")
|
|
|
|
| 344 |
print(f"[{loop_counter}] Detected potentially non-public battle format ({battle_tag}). Forfeiting.")
|
| 345 |
# Don't update display yet, do it before deactivation
|
| 346 |
try:
|
| 347 |
+
# Now Python knows active_agent_instance refers to the global one
|
| 348 |
if active_agent_instance: # Ensure agent still exists
|
| 349 |
await active_agent_instance.forfeit(battle_tag)
|
| 350 |
# await active_agent_instance.send_message("/forfeit", battle_tag) # Alternative
|
|
|
|
| 373 |
|
| 374 |
|
| 375 |
# --- Sub-state: Monitor ongoing battle ---
|
| 376 |
+
# Now Python knows current_battle_instance refers to the global one
|
| 377 |
if current_battle_instance is not None:
|
| 378 |
battle_tag = current_battle_instance.battle_tag
|
| 379 |
print(f"[{loop_counter}] State 2b: Monitoring battle {battle_tag} for '{agent_name}'")
|
| 380 |
|
| 381 |
# Ensure agent instance still exists before accessing its battles
|
| 382 |
+
# Now Python knows active_agent_instance refers to the global one
|
| 383 |
if not active_agent_instance:
|
| 384 |
print(f"[{loop_counter}] WARNING: Agent instance for '{agent_name}' disappeared while monitoring battle {battle_tag}! Deactivating.")
|
| 385 |
await deactivate_current_agent(reason="agent_disappeared_mid_battle")
|
|
|
|
| 387 |
|
| 388 |
# Get potentially updated battle object directly from agent's state
|
| 389 |
# Use .get() for safety
|
| 390 |
+
# Now Python knows active_agent_instance refers to the global one
|
| 391 |
battle_obj = active_agent_instance._battles.get(battle_tag)
|
| 392 |
|
| 393 |
if battle_obj and battle_obj.finished:
|
|
|
|
| 417 |
except Exception as e:
|
| 418 |
print(f"!!! ERROR in main lifecycle loop #{loop_counter}: {e} !!!")
|
| 419 |
traceback.print_exc()
|
| 420 |
+
# Now Python knows active_agent_name refers to the global one
|
| 421 |
current_agent_name = active_agent_name # Cache name before deactivation attempts
|
| 422 |
+
# Now Python knows active_agent_instance refers to the global one
|
| 423 |
if active_agent_instance:
|
| 424 |
print(f"Attempting to deactivate agent '{current_agent_name}' due to loop error...")
|
| 425 |
try:
|
|
|
|
| 447 |
if elapsed_time < LOOP_COOLDOWN_SECONDS:
|
| 448 |
await asyncio.sleep(LOOP_COOLDOWN_SECONDS - elapsed_time)
|
| 449 |
|
|
|
|
| 450 |
def log_task_exception(task: asyncio.Task):
|
| 451 |
"""Callback to log exceptions from background tasks (like accept_challenges)."""
|
| 452 |
try:
|