feat(perception): VLM-driven Meta AI comment generation integration
This commit is contained in:
@@ -329,7 +329,7 @@ class GoalExecutor:
|
||||
|
||||
return False
|
||||
|
||||
def _execute_action(self, action: str, goal: str = None) -> bool:
|
||||
def _execute_action(self, action: str, goal: str = None, **kwargs) -> bool:
|
||||
"""Execute a single natural-language action using the TelepathicEngine."""
|
||||
|
||||
if action == "press back":
|
||||
@@ -349,6 +349,9 @@ class GoalExecutor:
|
||||
random_sleep(2.0, 3.5)
|
||||
return True
|
||||
|
||||
if action == "type and post comment":
|
||||
return self._execute_type_and_post_comment(kwargs.get("text", ""))
|
||||
|
||||
# Use TelepathicEngine for any semantic click
|
||||
from GramAddict.core.telepathic_engine import TelepathicEngine
|
||||
|
||||
@@ -555,6 +558,83 @@ class GoalExecutor:
|
||||
achieved = self.planner.plan_next_step(goal, screen) is None
|
||||
return achieved
|
||||
|
||||
def _execute_type_and_post_comment(self, fallback_text: str) -> bool:
|
||||
"""Handles the specific typing interaction, prioritizing Meta AI chips if available."""
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from GramAddict.core.telepathic_engine import TelepathicEngine
|
||||
|
||||
logger.info("💬 [GOAP] Executing 'type and post comment'...")
|
||||
engine = TelepathicEngine.get_instance()
|
||||
|
||||
# 1. Tap the comment input field to open the keyboard
|
||||
xml_dump = self.device.dump_hierarchy()
|
||||
if "com.google.android.inputmethod.latin" not in xml_dump:
|
||||
logger.info("⌨️ [GOAP] Tapping comment composer to open keyboard...")
|
||||
best_node = engine.find_best_node(
|
||||
xml_dump, "tap comment input field", min_confidence=0.7, device=self.device
|
||||
)
|
||||
if best_node:
|
||||
self.device.click(obj=best_node)
|
||||
random_sleep(1.5, 2.5)
|
||||
xml_dump = self.device.dump_hierarchy()
|
||||
else:
|
||||
logger.warning("⚠️ [GOAP] Could not find comment input field.")
|
||||
return False
|
||||
|
||||
# 2. Check for Meta AI chips (Supportive, Funny, etc.)
|
||||
meta_ai_chips = []
|
||||
try:
|
||||
root = ET.fromstring(xml_dump.encode("utf-8"))
|
||||
for node in root.iter("node"):
|
||||
node_text = node.attrib.get("text", "")
|
||||
if node_text in ["Supportive", "Rewrite", "Absurd", "Casual", "Funny", "Heartfelt", "Professional"]:
|
||||
meta_ai_chips.append(node_text)
|
||||
except Exception as e:
|
||||
logger.debug(f"XML parse error for Meta AI chips: {e}")
|
||||
|
||||
if meta_ai_chips:
|
||||
logger.info(f"✨ [Meta AI] Detected Meta AI chips: {meta_ai_chips}")
|
||||
logger.info("🧠 [Meta AI] Asking VLM to select the best tone...")
|
||||
|
||||
# Use Telepathic Engine to pick the best chip via VLM
|
||||
chip_node = engine.find_best_node(
|
||||
xml_dump,
|
||||
"tap the best Meta AI tone chip to generate a comment (e.g. Supportive, Funny, Casual)",
|
||||
min_confidence=0.6,
|
||||
device=self.device,
|
||||
)
|
||||
|
||||
if chip_node:
|
||||
logger.info(f"✨ [Meta AI] VLM selected chip: '{chip_node.get('text', 'Unknown')}'")
|
||||
self.device.click(obj=chip_node)
|
||||
random_sleep(3.0, 4.5) # Wait for Meta AI to generate the text
|
||||
else:
|
||||
logger.warning("⚠️ [Meta AI] VLM failed to pick a chip, falling back to manual typing.")
|
||||
from GramAddict.core.stealth_typing import ghost_type
|
||||
|
||||
ghost_type(self.device, fallback_text)
|
||||
random_sleep(1.0, 2.0)
|
||||
else:
|
||||
# 3. Fallback: Type the text provided by our own VLM writer
|
||||
logger.info(f"⌨️ [GOAP] Typing comment manually: {fallback_text}")
|
||||
from GramAddict.core.stealth_typing import ghost_type
|
||||
|
||||
ghost_type(self.device, fallback_text)
|
||||
random_sleep(1.0, 2.0)
|
||||
|
||||
# 4. Click the Post button
|
||||
xml_dump = self.device.dump_hierarchy()
|
||||
post_btn = engine.find_best_node(xml_dump, "tap post comment button", min_confidence=0.7, device=self.device)
|
||||
if post_btn:
|
||||
self.device.click(obj=post_btn)
|
||||
random_sleep(1.5, 2.5)
|
||||
logger.info("✅ [GOAP] Comment posted successfully.")
|
||||
return True
|
||||
else:
|
||||
logger.warning("⚠️ [GOAP] Could not find post button after typing.")
|
||||
return False
|
||||
|
||||
# ── Convenience methods (backward compatibility with navigate_to) ──
|
||||
|
||||
def navigate_to_screen(self, target: str) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user