fix(mma): Unblock visual simulation - event routing, loop passing, adapter preservation

Three independent root causes fixed:
- gui_2.py: Route mma_spawn_approval/mma_step_approval events in _process_event_queue
- multi_agent_conductor.py: Pass asyncio loop from ConductorEngine.run() through to
  thread-pool workers for thread-safe event queue access; add _queue_put helper
- ai_client.py: Preserve GeminiCliAdapter in reset_session() instead of nulling it

Test: visual_sim_mma_v2::test_mma_complete_lifecycle passes in ~8s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 08:32:31 -05:00
parent db32a874fd
commit da21ed543d
11 changed files with 144 additions and 122 deletions

View File

@@ -23,6 +23,10 @@ def test_mma_complete_lifecycle(live_gui) -> None:
# Point the CLI adapter to our mock script
mock_cli_path = f'{sys.executable} {os.path.abspath("tests/mock_gemini_cli.py")}'
client.set_value('gcli_path', mock_cli_path)
# Prevent polluting the real project directory with test tracks
client.set_value('files_base_dir', 'tests/temp_workspace')
client.click('btn_project_save')
time.sleep(1)
except Exception as e:
pytest.fail(f"Failed to set up mock provider: {e}")
@@ -36,10 +40,13 @@ def test_mma_complete_lifecycle(live_gui) -> None:
status = client.get_mma_status()
print(f"Polling status: {status}")
print(f"Polling ai_status: {status.get('ai_status', 'N/A')}")
if status and status.get('pending_spawn') is True:
if status and status.get('pending_mma_spawn_approval') is True:
print('[SIM] Worker spawn required. Clicking btn_approve_spawn...')
client.click('btn_approve_spawn')
elif status and status.get('pending_approval') is True:
elif status and status.get('pending_mma_step_approval') is True:
print('[SIM] MMA step approval required. Clicking btn_approve_mma_step...')
client.click('btn_approve_mma_step')
elif status and status.get('pending_tool_approval') is True:
print('[SIM] Tool approval required. Clicking btn_approve_tool...')
client.click('btn_approve_tool')
if status and status.get('proposed_tracks') and len(status['proposed_tracks']) > 0:
@@ -56,9 +63,11 @@ def test_mma_complete_lifecycle(live_gui) -> None:
tracks_populated = False
for _ in range(30): # Poll for up to 30 seconds
status = client.get_mma_status()
if status and status.get('pending_spawn') is True:
if status and status.get('pending_mma_spawn_approval') is True:
client.click('btn_approve_spawn')
elif status and status.get('pending_approval') is True:
elif status and status.get('pending_mma_step_approval') is True:
client.click('btn_approve_mma_step')
elif status and status.get('pending_tool_approval') is True:
client.click('btn_approve_tool')
tracks = status.get('tracks', [])
@@ -90,10 +99,13 @@ def test_mma_complete_lifecycle(live_gui) -> None:
for _ in range(60): # Poll for up to 60 seconds
status = client.get_mma_status()
print(f"Polling load status: {status}")
if status and status.get('pending_spawn') is True:
if status and status.get('pending_mma_spawn_approval') is True:
print('[SIM] Worker spawn required. Clicking btn_approve_spawn...')
client.click('btn_approve_spawn')
elif status and status.get('pending_approval') is True:
elif status and status.get('pending_mma_step_approval') is True:
print('[SIM] MMA step approval required. Clicking btn_approve_mma_step...')
client.click('btn_approve_mma_step')
elif status and status.get('pending_tool_approval') is True:
print('[SIM] Tool approval required. Clicking btn_approve_tool...')
client.click('btn_approve_tool')
@@ -108,20 +120,20 @@ def test_mma_complete_lifecycle(live_gui) -> None:
print(f"Successfully loaded and verified track ID: {track_id_to_load} with active tickets.")
# 7. Start the MMA track and poll for its status.
print(f"Starting track {track_id_to_load}...")
client.click('btn_mma_start_track', user_data=track_id_to_load)
# 7. Poll for MMA status 'running' or 'done' (already started by Accept Tracks).
mma_running = False
for _ in range(120): # Poll for up to 120 seconds
status = client.get_mma_status()
print(f"Polling MMA status for 'running': {status.get('mma_status')}")
# Handle pending states during the run
if status and status.get('pending_spawn') is True:
if status and status.get('pending_mma_spawn_approval') is True:
print('[SIM] Worker spawn required. Clicking btn_approve_spawn...')
client.click('btn_approve_spawn')
elif status and status.get('pending_approval') is True:
elif status and status.get('pending_mma_step_approval') is True:
print('[SIM] MMA step approval required. Clicking btn_approve_mma_step...')
client.click('btn_approve_mma_step')
elif status and status.get('pending_tool_approval') is True:
print('[SIM] Tool approval required. Clicking btn_approve_tool...')
client.click('btn_approve_tool')
@@ -136,17 +148,19 @@ def test_mma_complete_lifecycle(live_gui) -> None:
assert mma_running or (status and status.get('mma_status') == 'done'), f"Timed out waiting for MMA status to become 'running' for track {track_id_to_load}."
print(f"MMA status is: {status.get('mma_status')}")
# 8. Verify 'active_tier' change and output in 'mma_streams'.
streams_found = False
for _ in range(60): # Give it more time for the worker to spawn and respond
status = client.get_mma_status()
# Handle approvals if they pop up during worker execution
if status and status.get('pending_spawn') is True:
if status and status.get('pending_mma_spawn_approval') is True:
print('[SIM] Worker spawn required. Clicking btn_approve_spawn...')
client.click('btn_approve_spawn')
elif status and status.get('pending_approval') is True:
elif status and status.get('pending_mma_step_approval') is True:
print('[SIM] MMA step approval required. Clicking btn_approve_mma_step...')
client.click('btn_approve_mma_step')
elif status and status.get('pending_tool_approval') is True:
print('[SIM] Tool approval required. Clicking btn_approve_tool...')
client.click('btn_approve_tool')