feat: implement smart unfollow with resonance evaluation and close friends guard

This commit is contained in:
2026-04-21 02:45:05 +02:00
parent 0a02e901b6
commit ee3022e95d
3 changed files with 167 additions and 32 deletions

View File

@@ -56,38 +56,70 @@ def _run_zero_latency_unfollow_loop(device, zero_engine, nav_graph, configs, ses
try:
xml_dump = device.dump_hierarchy()
# Use Telepathic Engine to explicitly locate existing "Following" buttons in lists
nodes = telepathic._extract_semantic_nodes(xml_dump, "find 'Following' buttons next to usernames", threshold=0.7)
# Smart Unfollow Phase 1: Find user rows instead of just clicking "Following"
nodes = telepathic._extract_semantic_nodes(xml_dump, "find user profile rows in list", threshold=0.7)
action_taken = False
for node in nodes:
# Basic validation it's an interactive button
if node.get("skip") or not node.get("bounds"):
continue
# Tap the first valid following button we see
# 1. Tap the profile row to navigate to their page
_humanized_click(device, node["x"], node["y"])
action_taken = True
logger.debug(f"👆 Tapped following button at ({node['x']}, {node['y']})")
logger.debug(f"👆 Tapped profile row at ({node['x']}, {node['y']})")
# Check for confirmation dialog ("Unfollow @username?")
random_sleep(1.0, 2.0)
confirm_xml = device.dump_hierarchy()
confirm_nodes = telepathic._extract_semantic_nodes(confirm_xml, "find 'Unfollow' confirmation button", threshold=0.8)
# Wait for profile to load
random_sleep(1.5, 2.5)
profile_xml = device.dump_hierarchy()
if confirm_nodes and not confirm_nodes[0].get("skip"):
c_node = confirm_nodes[0]
_humanized_click(device, c_node["x"], c_node["y"])
# 2. Close Friend Guard
profile_text = profile_xml.lower()
if "enge freunde" in profile_text or "close friend" in profile_text:
logger.info("💚 [Anti-Friend] Profile is a Close Friend. Skipping unfollow.", extra={"color": Fore.GREEN})
device.back()
random_sleep(0.8, 1.5)
break # Go next in loop
logger.info("✅ [Unfollow Engine] Unfollowed a user in list.", extra={"color": Fore.GREEN})
session_state.totalUnfollowed += 1
total_unfollowed_this_session += 1
failed_scrolls = 0
# Unfollow cost logic
dopamine.boredom += random.uniform(1.0, 3.0)
random_sleep(1.5, 3.0)
# 3. Resonance Evaluation
resonance = cognitive_stack.get("resonance")
res_score = 0.5
if resonance:
# Parse the description from the XML (rough pass, ResonanceEngine handles noise)
res_score = resonance.calculate_resonance({"description": profile_xml})
# 4. Decision: If < 0.4, Unfollow. Else Keep.
if res_score < 0.4:
logger.info(f"🗑️ [Smart Cleanup] Resonance is low ({res_score:.2f}). Unfollowing.", extra={"color": Fore.YELLOW})
# Find 'Following' button on their profile
following_nodes = telepathic._extract_semantic_nodes(profile_xml, "find 'Following' button", threshold=0.7)
if following_nodes and not following_nodes[0].get("skip"):
f_node = following_nodes[0]
_humanized_click(device, f_node["x"], f_node["y"])
random_sleep(1.0, 2.0)
# Find 'Unfollow' confirm
confirm_xml = device.dump_hierarchy()
confirm_nodes = telepathic._extract_semantic_nodes(confirm_xml, "find 'Unfollow' confirmation button", threshold=0.8)
if confirm_nodes and not confirm_nodes[0].get("skip"):
c_node = confirm_nodes[0]
_humanized_click(device, c_node["x"], c_node["y"])
random_sleep(0.8, 1.5)
logger.info("✅ [Unfollow Engine] Unfollowed a user.", extra={"color": Fore.GREEN})
session_state.totalUnfollowed += 1
total_unfollowed_this_session += 1
failed_scrolls = 0
dopamine.boredom += random.uniform(1.0, 3.0)
else:
logger.info(f"✨ [Smart Cleanup] Resonance is high ({res_score:.2f}). Keeping subscription.", extra={"color": Fore.MAGENTA})
failed_scrolls = 0
# 5. Always return to the Following list
device.back()
random_sleep(1.0, 2.0)
break
if not action_taken: