fix: track escalation for legacy AI voice handoff path #9

Merged
arystanbek merged 1 commits from fix/handoff-escalation-tracking into main 2026-08-30 19:08:21 +00:00
Owner

request_handoff() (called by ai_voice_runtime_service for every real call handoff - the only path production calls actually take) reserved an agent from the routing pool but never created an EscalationRow, so the Phase 2 no-answer-retry DialEnd/Hangup listener could never find it and act on it. A failed transfer left the agent stuck in RESERVED forever.

Fix: creates an EscalationRow alongside the reservation, releases the agent + marks it failed on an immediate AMI Redirect error, and lets the existing DialEnd/Hangup handler drive no-answer retry/release exactly like /escalations already does.

Reproduced live on aimaq: call handed off to extension 2002 with nobody registered -> immediate hangup, both pool agents stuck in RESERVED (fixed manually via psql in the meantime).

Tests: tests/test_escalation_retry.py + test_asterisk_bridge_service.py + test_routing_engine.py all green.

request_handoff() (called by ai_voice_runtime_service for every real call handoff - the only path production calls actually take) reserved an agent from the routing pool but never created an EscalationRow, so the Phase 2 no-answer-retry DialEnd/Hangup listener could never find it and act on it. A failed transfer left the agent stuck in RESERVED forever. Fix: creates an EscalationRow alongside the reservation, releases the agent + marks it failed on an immediate AMI Redirect error, and lets the existing DialEnd/Hangup handler drive no-answer retry/release exactly like /escalations already does. Reproduced live on aimaq: call handed off to extension 2002 with nobody registered -> immediate hangup, both pool agents stuck in RESERVED (fixed manually via psql in the meantime). Tests: tests/test_escalation_retry.py + test_asterisk_bridge_service.py + test_routing_engine.py all green.
arystanbek added 1 commit 2026-08-30 19:08:08 +00:00
request_handoff() (called by ai_voice_runtime_service for every real
call handoff, the only handoff path production calls actually use)
reserved an agent from the same routing pool as create_escalation()
but never created an EscalationRow, so the Phase 2 no-answer-retry
listener (DialEnd/Hangup) could never find it. A failed transfer
(no SIP registration, no answer, redirect error) left the agent
stuck in RESERVED forever with no retry to the next agent.

Now creates an EscalationRow (status=ringing) alongside the agent
reservation, releases the agent + marks the escalation failed if the
AMI Redirect itself errors immediately, and lets the existing
DialEnd/Hangup handler drive no-answer retry / release exactly like
the /escalations endpoint already does.

Reproduced live: call handed off to extension 2002 with no SIP
contact registered -> immediate hangup, cause=3, both pool agents
stuck in RESERVED indefinitely (had to release manually via psql).
arystanbek merged commit 3826f5704a into main 2026-08-30 19:08:21 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: digiops/call-center#9