File size: 4,954 Bytes
d36ce3c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# P3 Bug Report: Advanced Mode Missing Termination Guarantee
## Status
- **Date:** 2025-11-29
- **Priority:** P3 (Edge case, but confusing UX)
- **Component:** `src/orchestrator_magentic.py`
- **Resolution:** Fixed (Guarantee termination event)
---
## Symptoms
In **Advanced (Magentic) mode** with OpenAI API key:
1. Workflow runs for many iterations (up to 10 rounds)
2. Agents search, judge, hypothesize repeatedly
3. Eventually... **nothing happens**
- No "complete" event
- No error message
- UI just stops updating
**User perception:** "Did it finish? Did it crash? What happened?"
### Observed Behavior
When workflow hits `max_round_count=10`:
- `workflow.run_stream(task)` iterator ends
- NO `MagenticFinalResultEvent` is emitted by agent-framework
- Our code yields nothing after the loop
- User is left hanging
---
## Root Cause Analysis
### Code Path (`src/orchestrator_magentic.py:170-186`)
```python
iteration = 0
try:
async for event in workflow.run_stream(task):
agent_event = self._process_event(event, iteration)
if agent_event:
if isinstance(event, MagenticAgentMessageEvent):
iteration += 1
yield agent_event
# BUG: NO FALLBACK HERE!
# If loop ends without FinalResultEvent, user sees nothing
except Exception as e:
logger.error("Magentic workflow failed", error=str(e))
yield AgentEvent(
type="error",
message=f"Workflow error: {e!s}",
iteration=iteration,
)
# BUG: NO FINALLY BLOCK TO GUARANTEE TERMINATION EVENT
```
### Workflow Configuration (`src/orchestrator_magentic.py:110-116`)
```python
.with_standard_manager(
chat_client=manager_client,
max_round_count=self._max_rounds, # 10 - can hit this limit
max_stall_count=3, # If agents repeat 3x
max_reset_count=2, # Workflow reset limit
)
```
### Failure Modes
| Scenario | What Happens | User Sees |
|----------|--------------|-----------|
| `MagenticFinalResultEvent` emitted | `_process_event` yields "complete" | Final report |
| Max rounds (10) reached, no final event | Loop ends silently | **Nothing** |
| `max_stall_count` triggered | Workflow ends | **Nothing** |
| `max_reset_count` triggered | Workflow ends | **Nothing** |
| OpenAI API error | Exception caught | Error message |
---
## The Fix
Add guaranteed termination event after the loop:
```python
iteration = 0
final_event_received = False
try:
async for event in workflow.run_stream(task):
agent_event = self._process_event(event, iteration)
if agent_event:
if isinstance(event, MagenticAgentMessageEvent):
iteration += 1
if agent_event.type == "complete":
final_event_received = True
yield agent_event
except Exception as e:
logger.error("Magentic workflow failed", error=str(e))
yield AgentEvent(
type="error",
message=f"Workflow error: {e!s}",
iteration=iteration,
)
final_event_received = True # Error is a form of termination
finally:
# GUARANTEE: Always emit termination event
if not final_event_received:
logger.warning(
"Workflow ended without final event",
iterations=iteration,
)
yield AgentEvent(
type="complete",
message=(
f"Research completed after {iteration} agent rounds. "
"Max iterations reached - results may be partial. "
"Try a more specific query for better results."
),
data={"iterations": iteration, "reason": "max_rounds_reached"},
iteration=iteration,
)
```
---
## Alternative: Increase Max Rounds
The default `max_rounds=10` might be too low for complex queries.
In `src/orchestrator_factory.py:52-53`:
```python
return orchestrator_cls(
max_rounds=config.max_iterations if config else 10, # Could increase to 15-20
api_key=api_key,
)
```
**Trade-off:** More rounds = more API cost, but better chance of complete results.
---
## Test Plan
- [ ] Add fallback yield after async for loop
- [ ] Add `final_event_received` flag tracking
- [ ] Log warning when fallback is used
- [ ] Test with `max_rounds=2` to force hitting limit
- [ ] Verify user always sees termination event
- [ ] `make check` passes
---
## Related Files
- `src/orchestrator_magentic.py` - Main fix location
- `src/orchestrator_factory.py` - Max rounds configuration
- `src/utils/models.py` - AgentEvent types
- `docs/bugs/P2_MAGENTIC_THINKING_STATE.md` - Related UX issue (implemented)
---
## Priority Justification
**P3** because:
- Advanced mode is working for most queries
- Only hits edge case when max rounds reached without synthesis
- User CAN retry with different query
- Not blocking hackathon demo (free tier Simple mode works)
Would be P2 if:
- This happened frequently
- No workaround existed
|