feat(conductor): Add retry loop for Tech Lead JSON parsing

This commit is contained in:
2026-03-06 12:30:23 -05:00
parent a16ed4b1ae
commit 880ef5f370
3 changed files with 91 additions and 85 deletions

View File

@@ -3,13 +3,13 @@
> **TEST DEBT FIX:** Due to ongoing test architecture instability (documented in `test_architecture_integrity_audit_20260304`), do NOT write new `live_gui` integration tests for this track. Rely strictly on in-process `unittest.mock` for the `ai_client` to verify the retry logic.
## Phase 1: Implementation of Retry Logic
- [ ] Task: Initialize MMA Environment `activate_skill mma-orchestrator`
- [ ] Task: Implement Retry Loop in `generate_tickets`
- [x] Task: Initialize MMA Environment `activate_skill mma-orchestrator`
- [x] Task: Implement Retry Loop in `generate_tickets`
- [ ] WHERE: `conductor_tech_lead.py:generate_tickets`
- [ ] WHAT: Wrap the `send` and `json.loads` calls in a `for _ in range(max_retries)` loop.
- [ ] HOW: If `JSONDecodeError` is caught, append an error message to the context and loop. If it succeeds, `break` and return.
- [ ] SAFETY: Ensure token limits aren't massively breached by appending huge error states. Truncate raw output if necessary.
- [ ] Task: Conductor - User Manual Verification 'Phase 1: Implementation' (Protocol in workflow.md)
- [x] Task: Conductor - User Manual Verification 'Phase 1: Implementation' (Protocol in workflow.md)
## Phase 2: Unit Testing
- [ ] Task: Write Simulation Tests for JSON Parsing

View File

@@ -21,6 +21,9 @@ def generate_tickets(track_brief: str, module_skeletons: str) -> list[dict[str,
old_system_prompt = ai_client._custom_system_prompt
ai_client.set_custom_system_prompt(system_prompt or "")
ai_client.current_tier = "Tier 2"
last_error = None
try:
for _ in range(3):
try:
# 3. Call Tier 2 Model
response = ai_client.send(
@@ -41,9 +44,12 @@ def generate_tickets(track_brief: str, module_skeletons: str) -> list[dict[str,
json_match = match.group(0)
tickets: list[dict[str, Any]] = json.loads(json_match)
return tickets
except Exception as e:
print(f"Error parsing Tier 2 response: {e}")
return []
except json.JSONDecodeError as e:
last_error = e
correction = f"\n\nYour previous output failed to parse as JSON: {e}. Here was your raw output:\n{json_match[:500]}\n\nPlease fix the formatting and output ONLY valid JSON array."
user_message += correction
print(f"JSON parsing error, retrying... ({_ + 1}/3)")
raise RuntimeError(f"Failed to generate valid JSON tickets after 3 attempts. Last error: {last_error}")
finally:
# Restore old system prompt and clear tier tag
ai_client.set_custom_system_prompt(old_system_prompt or "")

View File

@@ -7,9 +7,9 @@ class TestConductorTechLead(unittest.TestCase):
def test_generate_tickets_parse_error(self) -> None:
with patch('src.ai_client.send') as mock_send:
mock_send.return_value = "invalid json"
# conductor_tech_lead.generate_tickets returns [] on error, doesn't raise
tickets = conductor_tech_lead.generate_tickets("brief", "skeletons")
self.assertEqual(tickets, [])
# conductor_tech_lead.generate_tickets now raises RuntimeError on error
with pytest.raises(RuntimeError):
conductor_tech_lead.generate_tickets("brief", "skeletons")
def test_generate_tickets_success(self) -> None:
with patch('src.ai_client.send') as mock_send: