fix: stochastic failure in test_autonomous_goals.py
This commit is contained in:
@@ -151,7 +151,7 @@ class GoalExecutor:
|
||||
original_available = screen.get("available_actions", []).copy()
|
||||
masked_available = []
|
||||
for act in original_available:
|
||||
fail_count = self.action_failures.get(act, 0)
|
||||
fail_count = self.action_failures.get((screen_type, act), 0)
|
||||
if fail_count >= MAX_RETRIES:
|
||||
logger.warning(
|
||||
f"🚫 [GOAP] Masking action '{act}' due to {fail_count} consecutive failures to prevent loops."
|
||||
@@ -173,8 +173,8 @@ class GoalExecutor:
|
||||
# SAE Feedback Loop!
|
||||
# If we hit this, the LAST action caused an obstacle! Mask it!
|
||||
if last_action and last_screen_type:
|
||||
self.action_failures[last_action] = (
|
||||
self.action_failures.get(last_action, 0) + MAX_RETRIES
|
||||
self.action_failures[(last_screen_type, last_action)] = (
|
||||
self.action_failures.get((last_screen_type, last_action), 0) + MAX_RETRIES
|
||||
) # Instantly mask it
|
||||
self.planner.knowledge.learn_trap(last_screen_type, last_action, f"caused_obstacle_{obstacle_name}")
|
||||
logger.warning(
|
||||
@@ -218,7 +218,7 @@ class GoalExecutor:
|
||||
# any action taken is essentially a navigation attempt.
|
||||
explored_nav_actions.add(action)
|
||||
# Reset failures for this action since it eventually succeeded
|
||||
self.action_failures[action] = 0
|
||||
self.action_failures[(screen_type, action)] = 0
|
||||
|
||||
if "scroll" in action.lower():
|
||||
logger.debug(
|
||||
@@ -230,7 +230,8 @@ class GoalExecutor:
|
||||
from GramAddict.core.screen_topology import ScreenTopology
|
||||
|
||||
keys_to_clear = [
|
||||
k for k in self.action_failures.keys() if ScreenTopology.is_structural_action(screen_type, k)
|
||||
k for k in self.action_failures.keys()
|
||||
if k[0] == screen_type and ScreenTopology.is_structural_action(screen_type, k[1])
|
||||
]
|
||||
for k in keys_to_clear:
|
||||
del self.action_failures[k]
|
||||
@@ -266,14 +267,14 @@ class GoalExecutor:
|
||||
else:
|
||||
consecutive_back_presses = 0
|
||||
else:
|
||||
self.action_failures[action] = self.action_failures.get(action, 0) + 1
|
||||
self.action_failures[(screen_type, action)] = self.action_failures.get((screen_type, action), 0) + 1
|
||||
# Track failed actions in explored_nav_actions so the planner
|
||||
# knows NOT to return the same synthetic intent again.
|
||||
# Without this, synthetic intents (not in available_actions)
|
||||
# bypass the masking logic and loop forever.
|
||||
explored_nav_actions.add(action)
|
||||
|
||||
if self.action_failures[action] >= MAX_RETRIES:
|
||||
if self.action_failures[(screen_type, action)] >= MAX_RETRIES:
|
||||
# ── Topology Guard: Never poison structural HD Map actions ──
|
||||
from GramAddict.core.screen_topology import ScreenTopology
|
||||
|
||||
|
||||
@@ -134,9 +134,14 @@ class GoalPlanner:
|
||||
# Build avoid_actions for HD Map route planning
|
||||
avoid_actions = (explored_nav_actions or set()).copy()
|
||||
if action_failures:
|
||||
for act, count in action_failures.items():
|
||||
if count >= 2: # MAX_RETRIES is 2 in goap
|
||||
avoid_actions.add(act)
|
||||
for key, count in action_failures.items():
|
||||
if isinstance(key, tuple) and len(key) == 2:
|
||||
scr, act = key
|
||||
if scr == screen_type and count >= 2: # MAX_RETRIES is 2 in goap
|
||||
avoid_actions.add(act)
|
||||
else:
|
||||
if count >= 2:
|
||||
avoid_actions.add(key)
|
||||
|
||||
target_screen = ScreenTopology.goal_to_target_screen(goal)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user