From c769a0ed18501e6a3301b0626e7283653d2c67ff Mon Sep 17 00:00:00 2001 From: Ed_ Date: Thu, 14 May 2026 23:13:17 -0400 Subject: [PATCH] fix(phase3): Resolve remaining test failures and stabilize GUI - Fixed ullcontext NameError in gui_2.py. - Corrected TestMMAApprovalIndicators to call real rendering methods on mock app. - Updated est_history_manager.py to provide required context_files argument to UISnapshot. - Stabilized est_z_negative_flows.py with robust polling for terminal response status and corrected field names. - Cleaned up debug logging in ag_engine.py and pp_controller.py. --- src/gui_2.py | 4 +-- src/rag_engine.py | 5 ++- tests/test_history_manager.py | 2 ++ tests/test_mma_approval_indicators.py | 15 +++++++++ tests/test_z_negative_flows.py | 46 +++++++++++++++++++-------- 5 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/gui_2.py b/src/gui_2.py index d938010..5c8f0e2 100644 --- a/src/gui_2.py +++ b/src/gui_2.py @@ -17,7 +17,7 @@ import threading import time import tomli_w import typing -# from contextlib import ExitStack, nullcontext +from contextlib import ExitStack, nullcontext from defer import defer from imgui_bundle import imgui, hello_imgui, immapp, imgui_node_editor as ed, imgui_color_text_edit as ced from pathlib import Path @@ -771,7 +771,7 @@ class App: try: self._render_main_interface() except Exception as e: - print(f"ERROR in _gui_func: {e}") + sys.stderr.write(f"ERROR in _gui_func: {e}\n") traceback.print_exc() if pushed_prior_tint: diff --git a/src/rag_engine.py b/src/rag_engine.py index 6a6a9a2..7ca05f7 100644 --- a/src/rag_engine.py +++ b/src/rag_engine.py @@ -18,7 +18,7 @@ def _get_sentence_transformers(): from sentence_transformers import SentenceTransformer _SENTENCE_TRANSFORMERS = SentenceTransformer except Exception as e: - sys.stderr.write(f"[DEBUG RAG] FAILED to import sentence_transformers: {e}\n") + sys.stderr.write(f"FAILED to import sentence_transformers: {e}\n") sys.stderr.flush() raise e return _SENTENCE_TRANSFORMERS @@ -51,7 +51,7 @@ class LocalEmbeddingProvider(BaseEmbeddingProvider): if ST: self.model = ST(model_name) except Exception as e: - sys.stderr.write(f"[DEBUG RAG] LocalEmbeddingProvider failed to load model {model_name}: {e}. Using dummy embeddings.\n") + sys.stderr.write(f"LocalEmbeddingProvider failed to load model {model_name}: {e}. Using dummy embeddings.\n") sys.stderr.flush() def embed(self, texts: List[str]) -> List[List[float]]: @@ -108,7 +108,6 @@ class RAGEngine: def _init_vector_store(self): vs_config = self.config.vector_store if vs_config.provider == 'chroma': - # Use absolute path to avoid confusion during directory cleanup/change db_path = os.path.abspath(os.path.join(self.base_dir, ".slop_cache", "rag_chroma")) os.makedirs(db_path, exist_ok=True) chroma_module = _get_chromadb() diff --git a/tests/test_history_manager.py b/tests/test_history_manager.py index 6bbdbcf..e9f903a 100644 --- a/tests/test_history_manager.py +++ b/tests/test_history_manager.py @@ -70,6 +70,7 @@ class TestHistoryManager: auto_add_history=True, disc_entries=[{"role": "user", "content": "hello"}], files=[{"path": "a.txt"}], + context_files=[], screenshots=["screenshot.png"], ) d = snap.to_dict() @@ -85,6 +86,7 @@ class TestHistoryManager: assert restored.auto_add_history == snap.auto_add_history assert restored.disc_entries == snap.disc_entries assert restored.files == snap.files + assert restored.context_files == snap.context_files assert restored.screenshots == snap.screenshots def test_push_clears_redo_stack(self): diff --git a/tests/test_mma_approval_indicators.py b/tests/test_mma_approval_indicators.py index 1ce30d7..b80867e 100644 --- a/tests/test_mma_approval_indicators.py +++ b/tests/test_mma_approval_indicators.py @@ -61,6 +61,21 @@ def _make_app(**kwargs): mock_controller = MagicMock() mock_controller.engine = mock_engine app.controller = mock_controller + + # Ensure real methods are called for the dashboard rendering components + app._render_mma_dashboard = lambda: App._render_mma_dashboard(app) + app._render_mma_focus_selector = lambda: App._render_mma_focus_selector(app) + app._render_mma_track_summary = lambda: App._render_mma_track_summary(app) + app._render_mma_epic_planner = lambda: App._render_mma_epic_planner(app) + app._render_mma_conductor_setup = lambda: App._render_mma_conductor_setup(app) + app._render_mma_track_browser = lambda: App._render_mma_track_browser(app) + app._render_mma_global_controls = lambda: App._render_mma_global_controls(app) + app._render_mma_usage_section = lambda: App._render_mma_usage_section(app) + app._render_ticket_queue = lambda: App._render_ticket_queue(app) + app._render_window_if_open = lambda name, func, condition=True: func() if condition else None + app._render_mma_ticket_editor = lambda: App._render_mma_ticket_editor(app) + app._render_mma_agent_streams = lambda: App._render_mma_agent_streams(app) + return app def _make_imgui_mock(): diff --git a/tests/test_z_negative_flows.py b/tests/test_z_negative_flows.py index bb0df9b..19f2942 100644 --- a/tests/test_z_negative_flows.py +++ b/tests/test_z_negative_flows.py @@ -25,12 +25,19 @@ def test_mock_malformed_json(live_gui) -> None: try: # Trigger generation - client.set_value("system_prompt_input", "Trigger malformed") + client.set_value("ai_input", "Trigger malformed") client.click("btn_gen_send") - # Wait for response - event = client.wait_for_event("response", timeout=15) - assert event is not None, "Did not receive response event" + # Wait for terminal response + event = None + start = time.time() + while time.time() - start < 30: + ev = client.wait_for_event("response", timeout=5) + if ev and ev.get("payload", {}).get("status") != "streaming...": + event = ev + break + + assert event is not None, "Did not receive terminal response event" assert event["payload"]["status"] == "error" assert "JSONDecodeError" in event["payload"]["text"] or "json" in event["payload"]["text"].lower() finally: @@ -60,12 +67,19 @@ def test_mock_error_result(live_gui) -> None: try: # Trigger generation - client.set_value("system_prompt_input", "Trigger error") + client.set_value("ai_input", "Trigger error") client.click("btn_gen_send") - # Wait for response - event = client.wait_for_event("response", timeout=15) - assert event is not None, "Did not receive response event" + # Wait for terminal response + event = None + start = time.time() + while time.time() - start < 30: + ev = client.wait_for_event("response", timeout=5) + if ev and ev.get("payload", {}).get("status") != "streaming...": + event = ev + break + + assert event is not None, "Did not receive terminal response event" assert event["payload"]["status"] == "error" assert "Mock simulated error" in event["payload"]["text"] finally: @@ -95,13 +109,19 @@ def test_mock_timeout(live_gui) -> None: try: # Trigger generation - client.set_value("system_prompt_input", "Trigger timeout") + client.set_value("ai_input", "Trigger timeout") client.click("btn_gen_send") - # Wait for response. Note: gemini_cli_adapter has a 60s timeout, - # but the mock might not actually hang for 60s if we adjust it or we wait for 65s here. - event = client.wait_for_event("response", timeout=70) - assert event is not None, "Did not receive response event" + # Wait for terminal response + event = None + start = time.time() + while time.time() - start < 80: + ev = client.wait_for_event("response", timeout=5) + if ev and ev.get("payload", {}).get("status") != "streaming...": + event = ev + break + + assert event is not None, "Did not receive terminal response event" assert event["payload"]["status"] == "error" assert "timeout" in event["payload"]["text"].lower() finally: