chore: add .hypothesis to .gitignore and commit remaining modified files

This commit is contained in:
2026-04-27 11:01:29 +02:00
parent 9ad49500f9
commit 3c4dd84a61
9 changed files with 24 additions and 12 deletions

1
.gitignore vendored
View File

@@ -37,3 +37,4 @@ traceback.log
htmlcov/
.coverage
coverage.xml
.hypothesis/

View File

@@ -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"})

View File

@@ -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)

View File

@@ -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))

View File

@@ -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

View File

@@ -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(

View File

@@ -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()

View File

@@ -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)