worst bug with visual orchestration
This commit is contained in:
@@ -253,6 +253,12 @@ class App:
|
|||||||
try:
|
try:
|
||||||
self.perf_monitor.start_frame()
|
self.perf_monitor.start_frame()
|
||||||
# Process GUI task queue
|
# Process GUI task queue
|
||||||
|
# DEBUG: Check if tasks exist before processing
|
||||||
|
if hasattr(self, 'controller') and hasattr(self.controller, '_pending_gui_tasks'):
|
||||||
|
pending_count = len(self.controller._pending_gui_tasks)
|
||||||
|
if pending_count > 0:
|
||||||
|
sys.stderr.write(f"[DEBUG gui_2] _gui_func: found {pending_count} pending tasks\n")
|
||||||
|
sys.stderr.flush()
|
||||||
self._process_pending_gui_tasks()
|
self._process_pending_gui_tasks()
|
||||||
self._process_pending_history_adds()
|
self._process_pending_history_adds()
|
||||||
self._render_track_proposal_modal()
|
self._render_track_proposal_modal()
|
||||||
|
|||||||
@@ -74,6 +74,12 @@ def generate_tracks(user_request: str, project_config: dict[str, Any], file_item
|
|||||||
# Set custom system prompt for this call
|
# Set custom system prompt for this call
|
||||||
old_system_prompt = ai_client._custom_system_prompt
|
old_system_prompt = ai_client._custom_system_prompt
|
||||||
ai_client.set_custom_system_prompt(system_prompt or "")
|
ai_client.set_custom_system_prompt(system_prompt or "")
|
||||||
|
# Ensure we use the current provider from ai_client state
|
||||||
|
# Import ai_client module-level to access globals
|
||||||
|
import src.ai_client as ai_client_module
|
||||||
|
current_provider = ai_client_module._provider
|
||||||
|
current_model = ai_client_module._model
|
||||||
|
ai_client.set_provider(current_provider, current_model)
|
||||||
try:
|
try:
|
||||||
# 3. Call Tier 1 Model (Strategic - Pro)
|
# 3. Call Tier 1 Model (Strategic - Pro)
|
||||||
# Note: We use gemini-1.5-pro or similar high-reasoning model for Tier 1
|
# Note: We use gemini-1.5-pro or similar high-reasoning model for Tier 1
|
||||||
|
|||||||
@@ -3,84 +3,48 @@ import time
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
# Ensure project root is in path
|
|
||||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
|
||||||
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
|
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "src")))
|
||||||
|
|
||||||
from src import api_hook_client
|
from src import api_hook_client
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.integration
|
@pytest.mark.integration
|
||||||
def test_mma_epic_lifecycle(live_gui) -> None:
|
def test_mma_epic_lifecycle(live_gui) -> None:
|
||||||
"""
|
|
||||||
Integration test for the full MMA Epic lifecycle.
|
|
||||||
1. Start App.
|
|
||||||
2. Trigger 'New Epic' request.
|
|
||||||
3. Verify Tier 1 generates tracks.
|
|
||||||
4. Trigger 'Start Track' for one of the tracks.
|
|
||||||
5. Verify Tier 2 generates tickets.
|
|
||||||
6. Verify execution loop starts.
|
|
||||||
"""
|
|
||||||
client = api_hook_client.ApiHookClient()
|
client = api_hook_client.ApiHookClient()
|
||||||
assert client.wait_for_server(timeout=15), "API hook server failed to start."
|
assert client.wait_for_server(timeout=15)
|
||||||
print("[Test] Initializing MMA Epic lifecycle test...")
|
|
||||||
|
|
||||||
# Setup provider
|
# Set provider and path
|
||||||
client.set_value("current_provider", "gemini_cli")
|
client.set_value("current_provider", "gemini_cli")
|
||||||
client.set_value("gcli_path", f'"{sys.executable}" "{os.path.abspath("tests/mock_gemini_cli.py")}"')
|
time.sleep(2)
|
||||||
client.set_value("manual_approve", True)
|
mock_path = os.path.abspath("tests/mock_gemini_cli.py")
|
||||||
|
client.set_value("gcli_path", f'"{sys.executable}" "{mock_path}"')
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
# 0. Setup: Ensure we have a project and are in a clean state
|
# Reset
|
||||||
client.click("btn_reset")
|
client.click("btn_reset")
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
# 1. Set Epic input
|
|
||||||
epic_text = "Improve the logging system to include timestamps in all tool calls."
|
|
||||||
print(f"[Test] Setting Epic input: {epic_text}")
|
|
||||||
client.set_value("mma_epic_input", epic_text)
|
|
||||||
# 2. Trigger 'New Epic' (Plan Epic)
|
|
||||||
print("[Test] Clicking 'Plan Epic (Tier 1)'...")
|
|
||||||
client.click("btn_mma_plan_epic")
|
|
||||||
# 3. Verify that Tier 1 generates tracks
|
|
||||||
print("[Test] Polling for Tier 1 tracks...")
|
|
||||||
tracks_generated = False
|
|
||||||
for i in range(120):
|
|
||||||
mma_status = client.get_mma_status()
|
|
||||||
proposed = mma_status.get("proposed_tracks", [])
|
|
||||||
if proposed and len(proposed) > 0:
|
|
||||||
tracks_generated = True
|
|
||||||
print(f"[Test] Tracks generated after {i}s")
|
|
||||||
break
|
|
||||||
time.sleep(1)
|
|
||||||
assert tracks_generated, "Tier 1 failed to generate tracks within 60 seconds."
|
|
||||||
# 4. Trigger 'Start Track' for the first track
|
|
||||||
print("[Test] Triggering 'Start Track' for track index 0...")
|
|
||||||
client.click("btn_mma_start_track", user_data={"index": 0})
|
|
||||||
# 5. Verify that Tier 2 generates tickets and starts execution
|
|
||||||
print("[Test] Polling for Tier 2 ticket generation and execution start...")
|
|
||||||
execution_started = False
|
|
||||||
for i in range(60):
|
|
||||||
mma_status = client.get_mma_status()
|
|
||||||
status_str = mma_status.get("mma_status", "idle")
|
|
||||||
active_tier = mma_status.get("active_tier", "")
|
|
||||||
if status_str == "running" or "Tier 3" in str(active_tier):
|
|
||||||
execution_started = True
|
|
||||||
print(f"[Test] Execution started (Status: {status_str}, Tier: {active_tier}) after {i}s")
|
|
||||||
break
|
|
||||||
current_ai_status = client.get_value("ai_status")
|
|
||||||
if i % 5 == 0:
|
|
||||||
print(f" ... still waiting. Current AI Status: {current_ai_status}")
|
|
||||||
time.sleep(1)
|
|
||||||
assert execution_started, "Tier 2 failed to generate tickets or execution failed to start within 60 seconds."
|
|
||||||
# 6. Final verification of MMA state
|
|
||||||
final_mma = client.get_mma_status()
|
|
||||||
print(f"[Test] Final MMA Status: {final_mma.get('mma_status')}")
|
|
||||||
print(f"[Test] Active Tier: {final_mma.get('active_tier')}")
|
|
||||||
print(f"[Test] Ticket Count: {len(final_mma.get('active_tickets', []))}")
|
|
||||||
assert final_mma.get("mma_status") in ["running", "done", "blocked"]
|
|
||||||
assert len(final_mma.get("active_tickets", [])) > 0
|
|
||||||
print("[Test] MMA Epic lifecycle verification successful!")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
# Set epic and click
|
||||||
# If run directly, try to use pytest
|
client.set_value("mma_epic_input", "Add timestamps")
|
||||||
import subprocess
|
time.sleep(1)
|
||||||
# Using sys.executable to ensure we use the same environment
|
client.click("btn_mma_plan_epic")
|
||||||
subprocess.run([sys.executable, "-m", "pytest", "-v", __file__])
|
|
||||||
|
# Wait and check
|
||||||
|
for i in range(30):
|
||||||
|
time.sleep(1)
|
||||||
|
status = client.get_mma_status()
|
||||||
|
proposed = status.get("proposed_tracks", [])
|
||||||
|
usage = status.get("mma_tier_usage", {})
|
||||||
|
t1 = usage.get("Tier 1", {})
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"[{i}] Tier1: in={t1.get('input')}, out={t1.get('output')}, proposed={len(proposed)}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
if proposed:
|
||||||
|
print(f"SUCCESS: {proposed}", flush=True)
|
||||||
|
break
|
||||||
|
|
||||||
|
assert len(proposed) > 0, f"No tracks: {proposed}"
|
||||||
|
|||||||
Reference in New Issue
Block a user