Skip to content

Stop the voice test tripping answering-machine detection - #48

Merged
dimavrem22 merged 1 commit into
mainfrom
fix/voice-test-amd-and-fail-fast
Jul 28, 2026
Merged

Stop the voice test tripping answering-machine detection#48
dimavrem22 merged 1 commit into
mainfrom
fix/voice-test-amd-and-fail-fast

Conversation

@dimavrem22

Copy link
Copy Markdown
Contributor

Summary

The live voice suite goes red intermittently with two-way call transcript: nothing within 220s. It is not the transport, and the 220s is a symptom rather than the cause.

Answering-machine detection scores whoever answers the call. The driver answered with a ~3s pause followed by ~7s of uninterrupted speech:

"Hi, this is a quick test call. Please reply out loud with one short sentence, then say goodbye."

The carrier's threshold for a human greeting is greeting_duration_millis = 3500ms. We were 2× over it, so the driver was classified machine and the call hung up about ten seconds in — before the agent said a word. It is intermittent rather than broken because the scoring is probabilistic near that boundary; the same commit passes on a re-run with no change.

Confirmed against a real incident (opencode-plugin, 2026-07-28):

16:21:58.836  call placed
16:22:01.517  call.answered
16:22:03.838  agent connected
16:22:08.620  AMD premium detection ended  result=machine
16:22:08.620  "Voicemail detected, hanging up"
16:22:09.645  hangup

hangup_reason=voicemail, duration=10.160s, session_failed=false, 0 transcript rows. Not quota or concurrency — 2 calls and 66 voice-seconds in the window against limits of 300 calls / 300 minutes per 24h.

Two changes

1. The driver answers like a person. One short word immediately, then silence, with the prompt held until the detection window has closed. A human says "Hello?" and stops; a voicemail greeting runs on. VOICE_DRIVER_GREETING overrides it.

2. The test stops polling a dead call. The terminal-status check only covered canceled and failed. A detection hangup ends the call completed with hangup_reason=voicemail, so the loop kept asking for a transcript that could never arrive and reported the timeout instead of the reason — which was sitting in the call record ten seconds in. It now stops shortly after the call ends, with the hangup reason already in the failure message.

The grace period (LIVE_VOICE_ENDED_GRACE, 15s) exists because transcript rows can still land while the call tears down.

Scope

Test harness only. No plugin runtime, no gateway, no API change. No version bump.

Not fixed here

The real fix is server-side: answering_machine_detection="premium" is hardcoded at all three dial sites in servers, with no per-call opt-out. AMD is meaningless when calling a known synthetic peer — and the same tax applies to any customer placing agent-to-agent calls. That is written up separately for the servers repo; this change makes CI honest in the meantime.

The live voice suite goes red intermittently with "two-way call
transcript: nothing within 220s". The cause is not the transport: the
carrier's answering-machine detection scores whoever answers, and the
driver answered with ~7s of uninterrupted speech after a 3s pause. The
threshold for a human greeting is 3.5s, so the call was classified as
voicemail and hung up about ten seconds in, before the agent said
anything. It is intermittent because the scoring is probabilistic near
that boundary.

The driver now answers the way a person does -- one short word, then
silence -- and holds the prompt until the detection window has closed.

The test also polled a dead call. Its terminal-status check covers only
canceled and failed, and a detection hangup ends the call `completed`
with hangup_reason=voicemail, so the loop kept asking for a transcript
that could never arrive and reported the timeout instead of the reason.
It now stops shortly after the call ends, with the hangup reason already
in the failure message, which was available ten seconds in rather than
at 220.

The grace period exists because transcript rows can still land while the
call tears down.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dimavrem22
dimavrem22 marked this pull request as ready for review July 28, 2026 21:00
@dimavrem22
dimavrem22 merged commit b602962 into main Jul 28, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant