chore: add .hypothesis to .gitignore and commit remaining modified files
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -37,3 +37,4 @@ traceback.log
|
||||
htmlcov/
|
||||
.coverage
|
||||
coverage.xml
|
||||
.hypothesis/
|
||||
|
||||
Binary file not shown.
@@ -46,7 +46,7 @@ class ObstacleGuardPlugin(BehaviorPlugin):
|
||||
if situation == SituationType.OBSTACLE_MODAL:
|
||||
if misses >= 2:
|
||||
logger.error("🛑 [ObstacleGuard] Failed to recover from OBSTACLE_MODAL after multiple attempts.")
|
||||
sae.unlearn_current_state()
|
||||
sae.unlearn_current_state(xml)
|
||||
dump_ui_state(ctx.device, f"fatal_obstacle_{ctx.session_state.job_target}")
|
||||
return BehaviorResult(executed=True, should_skip=True, metadata={"return_code": "CONTEXT_LOST"})
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ class ResonanceEvaluatorPlugin(BehaviorPlugin):
|
||||
tele = ctx.cognitive_stack.get("telepathic")
|
||||
if tele:
|
||||
logger.info("✨ [Resonance] Performing visual vibe check...")
|
||||
vibe = tele.evaluate_post_vibe()
|
||||
persona_interests = getattr(ctx.configs.args, "persona_interests", [])
|
||||
vibe = tele.evaluate_post_vibe(ctx.device, persona_interests)
|
||||
vibe_score = vibe.get("quality_score", 5) / 10.0
|
||||
if vibe.get("matches_niche"):
|
||||
vibe_score = min(1.0, vibe_score + 0.2)
|
||||
|
||||
@@ -5,7 +5,7 @@ from time import sleep
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ghost_type(device, text: str):
|
||||
def ghost_type(device, text: str, speed: str = "normal"):
|
||||
"""
|
||||
Tesla Stealth Ghost Keyboard.
|
||||
Bypasses UIAutomator virtual IME completely and sends raw Native InputEvents.
|
||||
@@ -48,6 +48,10 @@ def ghost_type(device, text: str):
|
||||
else:
|
||||
_adb_inject_text(device, chunk)
|
||||
|
||||
if speed == "fast":
|
||||
sleep(random.uniform(0.01, 0.05))
|
||||
continue
|
||||
|
||||
# Realistic pause between semantic bursts (humans think while typing)
|
||||
if chunk.endswith((" ", ".", ",", "!", "?")):
|
||||
sleep(random.uniform(0.2, 0.5))
|
||||
|
||||
@@ -93,7 +93,7 @@ limits:
|
||||
speed_multiplier: 1.0
|
||||
|
||||
# ── Infrastructure & System ──
|
||||
device: 192.168.1.206:40505
|
||||
device: 192.168.1.206:36369
|
||||
app-id: com.instagram.android
|
||||
debug: true
|
||||
blank_start: true
|
||||
|
||||
@@ -58,7 +58,7 @@ def test_dm_engine_basic_loop(dm_mock_dependencies):
|
||||
with (
|
||||
patch("GramAddict.core.bot_flow.sleep"),
|
||||
patch("GramAddict.core.bot_flow._humanized_click") as mock_click,
|
||||
patch("GramAddict.core.stealth_typing.ghost_type") as mock_ghost_type,
|
||||
patch("GramAddict.core.stealth_typing.ghost_type", autospec=True) as mock_ghost_type,
|
||||
patch("GramAddict.core.llm_provider.query_llm", return_value={"response": "I am good, thanks!"}),
|
||||
):
|
||||
res = _run_zero_latency_dm_loop(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import MagicMock, create_autospec, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -102,11 +102,14 @@ class TestObstacleGuardPlugin:
|
||||
@patch("GramAddict.core.behaviors.obstacle_guard.dump_ui_state")
|
||||
@patch("GramAddict.core.behaviors.obstacle_guard.SituationalAwarenessEngine")
|
||||
def test_execute_obstacle_miss_3_abort(self, mock_sae, mock_dump, obstacle_guard, mock_context):
|
||||
mock_instance = MagicMock()
|
||||
from GramAddict.core.situational_awareness import SituationalAwarenessEngine
|
||||
|
||||
mock_instance = create_autospec(SituationalAwarenessEngine, instance=True)
|
||||
mock_instance.perceive.return_value = SituationType.OBSTACLE_MODAL
|
||||
mock_sae.get_instance.return_value = mock_instance
|
||||
|
||||
mock_context.device.dump_hierarchy.return_value = "<xml>dummy</xml>"
|
||||
xml_content = "<xml>dummy</xml>"
|
||||
mock_context.device.dump_hierarchy.return_value = xml_content
|
||||
mock_context.device.get_info.return_value = {"displayWidth": 1080, "displayHeight": 2400}
|
||||
mock_context.shared_state["consecutive_marker_misses"] = 2
|
||||
mock_context.session_state.job_target = "Feed"
|
||||
@@ -115,5 +118,5 @@ class TestObstacleGuardPlugin:
|
||||
|
||||
assert result.executed is True
|
||||
assert result.metadata.get("return_code") == "CONTEXT_LOST"
|
||||
mock_instance.unlearn_current_state.assert_called_once()
|
||||
mock_instance.unlearn_current_state.assert_called_once_with(xml_content)
|
||||
mock_dump.assert_called_once()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest import mock
|
||||
from unittest.mock import MagicMock, create_autospec, patch
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -63,10 +64,12 @@ class TestResonanceEvaluatorPlugin:
|
||||
@patch("GramAddict.core.behaviors.resonance_evaluator.humanized_scroll")
|
||||
@patch("GramAddict.core.behaviors.resonance_evaluator.sleep")
|
||||
def test_execute_visual_vibe_check(self, mock_sleep, mock_scroll, resonance_evaluator, mock_context):
|
||||
from GramAddict.core.telepathic_engine import TelepathicEngine
|
||||
|
||||
mock_context.configs.args.visual_vibe_check_percentage = 100
|
||||
mock_context.cognitive_stack["resonance"].calculate_resonance.return_value = 0.5
|
||||
|
||||
mock_tele = MagicMock()
|
||||
mock_tele = create_autospec(TelepathicEngine, instance=True)
|
||||
mock_tele.evaluate_post_vibe.return_value = {"quality_score": 10, "matches_niche": True}
|
||||
mock_context.cognitive_stack["telepathic"] = mock_tele
|
||||
|
||||
@@ -77,4 +80,4 @@ class TestResonanceEvaluatorPlugin:
|
||||
assert result.should_skip is False
|
||||
# res_score = 0.5 * 0.3 + 1.0 * 0.7 = 0.15 + 0.70 = 0.85
|
||||
assert round(mock_context.shared_state["res_score"], 2) == 0.85
|
||||
mock_tele.evaluate_post_vibe.assert_called_once()
|
||||
mock_tele.evaluate_post_vibe.assert_called_once_with(mock_context.device, mock.ANY)
|
||||
|
||||
Reference in New Issue
Block a user