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:
|