feat(navigation): complete autonomous integration tests and goal weighting

This commit is contained in:
2026-04-28 19:06:16 +02:00
parent 4ad559e107
commit 0bdfd999d2
10 changed files with 239 additions and 22 deletions

View File

@@ -446,7 +446,10 @@ def start_bot(**kwargs):
while not dopamine.is_app_session_over():
# 1. Ask the Growth Brain for a Strategic Objective
current_goal = growth_brain.get_current_goal(dopamine, getattr(configs.args, "goals", []))
success_rates = getattr(session_state, "successfulInteractions", {})
current_goal = growth_brain.get_current_goal(
dopamine, getattr(configs.args, "goals", []), success_rates=success_rates
)
if current_goal == "ShiftContext":
logger.info("🧠 [Free Will] Boredom critical. Forcing app restart to clear context.")

View File

@@ -215,10 +215,12 @@ def _run_zero_latency_dm_loop(device, zero_engine, nav_graph, configs, session_s
# If keyboard was open, the first back only closed it. Check if still in thread.
check_xml = device.dump_hierarchy()
if (
'resource-id="com.instagram.android:id/direct_thread_header"' in check_xml
or 'resource-id="com.instagram.android:id/row_thread_composer_edittext"' in check_xml
):
from GramAddict.core.perception.screen_identity import ScreenIdentity, ScreenType
check_identity = ScreenIdentity(getattr(configs.args, "username", ""))
check_screen = check_identity.identify(check_xml)
if check_screen["screen_type"] == ScreenType.DM_THREAD:
device.press("back")
sleep(1.0)
@@ -239,10 +241,12 @@ def _run_zero_latency_dm_loop(device, zero_engine, nav_graph, configs, session_s
sleep(1.0)
check_xml = device.dump_hierarchy()
if (
'resource-id="com.instagram.android:id/direct_thread_header"' in check_xml
or 'resource-id="com.instagram.android:id/row_thread_composer_edittext"' in check_xml
):
from GramAddict.core.perception.screen_identity import ScreenIdentity, ScreenType
check_identity = ScreenIdentity(getattr(configs.args, "username", ""))
check_screen = check_identity.identify(check_xml)
if check_screen["screen_type"] == ScreenType.DM_THREAD:
device.press("back")
sleep(1.0)

View File

@@ -94,10 +94,11 @@ class GrowthBrain:
logger.info(f"🧠 [GrowthBrain] Strategy '{self.strategy}' dictated Desire: {selected_desire}")
return selected_desire
def get_current_goal(self, dopamine_engine, available_goals: list[str]) -> str:
def get_current_goal(self, dopamine_engine, available_goals: list[str], success_rates: dict = None) -> str:
"""
Autonomously selects the next strategic goal.
If no goals are configured, falls back to legacy desires.
Weights goals based on session success rates if provided.
"""
import random
@@ -105,13 +106,20 @@ class GrowthBrain:
# Legacy Desire Mapping (Fallback)
return self.get_current_desire(dopamine_engine)
# Basic strategy: For now, randomly select a goal.
# Future: Weight by strategy, previous success, or time of day.
# Use DopamineEngine to influence 'boredom' switching if needed.
if dopamine_engine.boredom > 80:
return "ShiftContext" # High boredom triggers a context shift
return random.choice(available_goals)
if not success_rates:
return random.choice(available_goals)
weights = []
for goal in available_goals:
base_weight = 1.0
success_count = success_rates.get(goal, 0)
weight = base_weight + float(success_count)
weights.append(weight)
return random.choices(available_goals, weights=weights, k=1)[0]
def get_circadian_pacing(self) -> float:
"""

View File

@@ -179,8 +179,9 @@ class ScreenIdentity:
if any(marker in ids for marker in REELS_MARKERS):
return ScreenType.REELS_FEED
# DM thread detection — structural markers present inside DM conversations
if "direct_thread_header" in ids or "row_thread_composer_edittext" in ids:
# DM thread detection — Semantic app-agnostic markers (chat input fields)
chat_input_markers = ["Message...", "Nachricht...", "Type a message", "Nachricht senden", "Send a message"]
if any(marker in texts for marker in chat_input_markers) or "direct_thread_header" in ids:
return ScreenType.DM_THREAD
# Priority 2: Check Qdrant Semantic Cache (Fuzzy/VLM derived)