feat. Finishing sound & agent loop fixes
CI / test (push) Failing after 33s

This commit is contained in:
2026-06-04 15:16:31 +02:00
parent 97641b354e
commit 643320a9de
6 changed files with 271 additions and 42 deletions
+122
View File
@@ -495,6 +495,128 @@ def test_observation_loop_blocks_repeated_broad_reobservation(tmp_path: Path, mo
assert blocked["window_summary"] == "Save as [#32770]"
def test_observation_loop_counts_sleep_as_non_progress(tmp_path: Path, monkeypatch) -> None:
agent = _build_agent(tmp_path, monkeypatch)
agent.step_history = [
{
"step": 40,
"tool_names": ["click"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": False,
"contains_action": True,
},
{
"step": 41,
"tool_names": ["see_screen"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": True,
"contains_action": False,
},
{
"step": 42,
"tool_names": ["sleep"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": False,
"contains_action": False,
},
{
"step": 43,
"tool_names": ["get_active_window"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": False,
"contains_action": False,
},
{
"step": 44,
"tool_names": ["sleep"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": False,
"contains_action": False,
},
{
"step": 45,
"tool_names": ["see_screen"],
"window_signature": "123|#32770|Save as",
"window_summary": "Save as [#32770]",
"had_visual": True,
"contains_action": False,
},
]
blocked = agent._dispatch_tool("see_screen", {})
assert blocked["ok"] is False
assert blocked["blocked"] is True
assert blocked["blocked_reason"] == "observation_loop"
assert blocked["repeated_steps"] == 3
def test_observation_loop_treats_focus_window_as_action_progress(tmp_path: Path, monkeypatch) -> None:
agent = _build_agent(tmp_path, monkeypatch)
agent._record_step_history(["focus_window"], {"hwnd": 123, "class_name": "#32770", "title": "Save as"})
entry = agent.step_history[-1]
assert entry["contains_action"] is True
def test_observation_loop_requires_non_empty_window_signature(tmp_path: Path, monkeypatch) -> None:
agent = _build_agent(tmp_path, monkeypatch)
agent.step_history = [
{
"step": 50,
"tool_names": ["see_screen"],
"window_signature": "",
"window_summary": "",
"had_visual": True,
"contains_action": False,
},
{
"step": 51,
"tool_names": ["get_active_window"],
"window_signature": "",
"window_summary": "",
"had_visual": False,
"contains_action": False,
},
{
"step": 52,
"tool_names": ["see_screen"],
"window_signature": "",
"window_summary": "",
"had_visual": True,
"contains_action": False,
},
]
assert agent._stable_observation_loop() is None
def test_record_step_history_reuses_last_observed_window_for_visual_only_steps(tmp_path: Path, monkeypatch) -> None:
agent = _build_agent(tmp_path, monkeypatch)
agent.last_observed_window = {
"available": True,
"hwnd": 321,
"class_name": "ApplicationFrameWindow",
"title": "Settings",
}
agent._record_step_history(["see_screen"], None, "sig-a")
agent._record_step_history(["get_active_window"], None)
agent._record_step_history(["detect_dialog"], None)
stable = agent._stable_observation_loop()
assert stable is not None
assert stable["window_summary"] == "Settings [ApplicationFrameWindow]"
assert stable["repeated_steps"] == 3
def test_repeated_ambiguous_action_requires_verification_and_then_blocks(tmp_path: Path, monkeypatch) -> None:
agent = _build_agent(tmp_path, monkeypatch)
type_args = {"text": "repeat me"}