From 3c4dd84a61b29417289adca513d7192e23ecf6fb Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Mon, 27 Apr 2026 11:01:29 +0200 Subject: [PATCH] chore: add .hypothesis to .gitignore and commit remaining modified files --- .gitignore | 1 + .../unicode_data/14.0.0/codec-utf-8.json.gz | Bin 60 -> 60 bytes GramAddict/core/behaviors/obstacle_guard.py | 2 +- GramAddict/core/behaviors/resonance_evaluator.py | 3 ++- GramAddict/core/stealth_typing.py | 6 +++++- test_config.yml | 2 +- tests/integration/test_dm_loop.py | 2 +- tests/unit/behaviors/test_obstacle_guard.py | 11 +++++++---- tests/unit/behaviors/test_resonance_evaluator.py | 9 ++++++--- 9 files changed, 24 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index a5f491f..cdbfc4f 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,4 @@ traceback.log htmlcov/ .coverage coverage.xml +.hypothesis/ diff --git a/.hypothesis/unicode_data/14.0.0/codec-utf-8.json.gz b/.hypothesis/unicode_data/14.0.0/codec-utf-8.json.gz index 20bc62159b8a70ef5f0120791b8056989ef30691..47e7f9380423a9458ee58eda66a6ed06224f8ae7 100644 GIT binary patch delta 27 icmcDq5tZ-e;9z86U|{-Rl3S3MW{_8&Y*s!|R2=|U?gwE2 delta 27 icmcDq5tZ-e;9z86U|{-Rl3QS&mQz_`oK-eaR2=|U&= 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"}) diff --git a/GramAddict/core/behaviors/resonance_evaluator.py b/GramAddict/core/behaviors/resonance_evaluator.py index cb8f8be..2677876 100644 --- a/GramAddict/core/behaviors/resonance_evaluator.py +++ b/GramAddict/core/behaviors/resonance_evaluator.py @@ -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) diff --git a/GramAddict/core/stealth_typing.py b/GramAddict/core/stealth_typing.py index 49ed81a..dc541d5 100644 --- a/GramAddict/core/stealth_typing.py +++ b/GramAddict/core/stealth_typing.py @@ -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)) diff --git a/test_config.yml b/test_config.yml index 6d01cd9..e87b005 100644 --- a/test_config.yml +++ b/test_config.yml @@ -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 diff --git a/tests/integration/test_dm_loop.py b/tests/integration/test_dm_loop.py index f10d7f4..ae56d7c 100644 --- a/tests/integration/test_dm_loop.py +++ b/tests/integration/test_dm_loop.py @@ -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( diff --git a/tests/unit/behaviors/test_obstacle_guard.py b/tests/unit/behaviors/test_obstacle_guard.py index ff282e4..894a7f3 100644 --- a/tests/unit/behaviors/test_obstacle_guard.py +++ b/tests/unit/behaviors/test_obstacle_guard.py @@ -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 = "dummy" + xml_content = "dummy" + 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() diff --git a/tests/unit/behaviors/test_resonance_evaluator.py b/tests/unit/behaviors/test_resonance_evaluator.py index 8594475..3daaeff 100644 --- a/tests/unit/behaviors/test_resonance_evaluator.py +++ b/tests/unit/behaviors/test_resonance_evaluator.py @@ -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)