Correct the AI turn detection params - #676
Merged
Merged
Conversation
`enable_turn_detection` was documented as a boolean that watches partial transcripts for sentence-ending punctuation. It takes a string enum — `off` / `both` / `punct_only` / `acoustic_only`, defaulting to `both` — and the punctuation-only behavior the page described is one of the four modes, not the whole param. Verified against mod_openai and mod_deepgram at origin/main: - Enum values, the `turn_detection` alias, and the legacy boolean mapping (`false`->off, `true`->both): app_config.c:1737-1756. - Default `both`: `ai_globals.default_turn_detection = 1` (api_commands.c:1334), read by app_config.c:1551. - "No effect when off" for both tuning knobs: the `!= TURN_DETECTION_OFF` guard at speech_detect.c:1486. Also fixes three pre-existing errors on `turn_detection_timeout`, and adds the undocumented `turn_detection_min_length`: - The default is not 250. That value is only mod_deepgram's struct initializer (mod_deepgram.c:7895), live when turn detection is off. With it on, mod_deepgram.c:9548 sets the wait to `silence_ms`, which mod_openai always populates from `end_of_speech_timeout` (speech_detect.c:1347), so the effective default is 700. - `0` does not finalize immediately. mod_openai only sends the knob when `> 0` (speech_detect.c:1502), so `0` means "use the default". - Lowering it does not improve responsiveness. The mod_deepgram comment records eos->push as hedge-independent across 250-1000 and homophone garble below 500, so the page now states the floor instead of inviting readers under it. - `turn_detection_min_length` is characters of transcript, not milliseconds of speech: mod_deepgram_fusion.h:209 declares it "min text length" and mod_deepgram_fusion.c:2774 tests `slen >= in->min_length` over `strlen(in->text)`. It is also bypassed once the acoustic signal clears the gate, so it filters the punctuation path alone. Regenerated openapi.yaml and SWMLObject.json via yarn build:specs. Fixes signalwire/cloud-product#20939
Contributor
hey-august
reviewed
Sep 11, 2026
hey-august
left a comment
Collaborator
There was a problem hiding this comment.
Summary
The branch is accurate and the generated output is in sync. One sentence overstates which modes the two tuning parameters affect, and the acoustic_only mode ignores both. Fix that before merging. The rest is optional.
Verified
- The mode enum, the
turn_detectionalias, the boolean mapping, and thebothdefault all match the platform's behavior. - The
turn_detection_timeoutdefault ofend_of_speech_timeout, the meaning of0, and the sub-500 accuracy warning all match. - The
turn_detection_min_lengthparameter counts transcript characters, and the acoustic signal bypasses it when it reads the caller as finished. - A fresh
yarn build:specsproduces no diff against the committed output.yarn fern-md-checkpasses on all 2831 files.
Blocking
- The
acoustic_onlymode ignores both tuning parameters. An acoustic-only end of turn finalizes with no wait and skips the length check, so "Every mode exceptoffis tuned byturn_detection_timeoutandturn_detection_min_length" is wrong for that mode. The sentence appears in themdxpage at line 113 and in the.tspdoc at line 161, and from there in both generated files. Suggested wording: "Thebothandpunct_onlymodes honorturn_detection_timeoutandturn_detection_min_length. Theacoustic_onlymode uses neither."
Suggested
- The
turn_detection_min_lengthtext assumes the acoustic override exists in every mode. Inpunct_onlythere is no acoustic signal, so a value of 4 does block "Yes.". Add "inbothmode" to the sentence that begins "The acoustic signal overrides this". - The
enable_turn_detectionParamField is typedstringbut also accepts a boolean. The page writes unions astype="boolean | integer", sotype="string | boolean"matches. Line 105 of themdxpage. - Consider a changelog entry. Documentation work gets none, but this publishes two capabilities customers could not discover before, the mode enum and
turn_detection_min_length, plus a default change from punctuation-only detection toboth. That is the exception the changelog guidance allows. Date it when the change reached customers, if that date can be established. - Em-dash density. The
turn_detection_min_lengthparagraphs carry three across two short paragraphs and theenable_turn_detectionblock has four. The "Uh-huh." appositive earns its pair. The tail "a caller who has finished usually commits well inside it" reads the same as its own sentence.
`acoustic_only` finalizes with no wait and skips the length check, so it honors neither `turn_detection_timeout` nor `turn_detection_min_length`. Scope the acoustic override on `turn_detection_min_length` to `both`, since `punct_only` has no acoustic signal to override it. Also type `enable_turn_detection` as `string | boolean` to match the boolean aliases, and split an em-dash tail into its own sentence.
hey-august
approved these changes
Sep 14, 2026
hey-august
left a comment
Collaborator
There was a problem hiding this comment.
Approving. The follow-up commit addresses the review notes, and the branch is ready to merge.
Verified after the update
- The
acoustic_onlymode is now excluded from both tuning parameters in the mdx page, the.tspsource, and both generated files. Each parameter carries a matching "no effect whenofforacoustic_only" line. - The acoustic override on
turn_detection_min_lengthis scoped tobothmode. - The
enable_turn_detectionfield is typedstring | boolean, matching the page's union convention. - The
bothbullet's two acoustic claims, holding a turn open when the caller sounds mid-sentence and ending one that trails off without punctuation, both match the platform's decision logic. That answers the open question from the linked issue. - A fresh
yarn build:specsproduces no diff against the committed output.yarn fern-md-checkpasses. - The merge from main touched none of these four files beyond this branch's own changes.
Follow-up, not blocking
A changelog entry is still worth considering. This publishes the mode enum and turn_detection_min_length, which customers could not discover before, and a default change from punctuation-only detection to both. It can ship separately once the production date is known.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes signalwire/cloud-product#20939.
ai.params.enable_turn_detectionwas documented as a boolean that monitors partialtranscripts for sentence-ending punctuation. It actually takes a string enum —
off/both/punct_only/acoustic_only, defaulting toboth— and the punctuationbehavior the page described is one of the four modes, not the parameter itself.
Chasing that turned up three more errors on
turn_detection_timeout, all pre-existing,plus a sibling parameter that was never documented.
What changed
enable_turn_detectionboolean, defaulttrueoff/both/punct_only/acoustic_only, defaultboth; booleans are still accepted (false→off,true→both), andturn_detectionis an accepted aliasturn_detection_timeout250;0finalizes immediately; lower is more responsiveend_of_speech_timeout(700 ms);0means "use the default"; lowering it doesn't improve responsiveness, and values under 500 ms hurt transcription accuracyturn_detection_min_lengthDetail
enable_turn_detection— the page now documents all four modes and what each onelistens to, notes that booleans still work for backward compatibility, and records
turn_detectionas an alias. Both tuning parameters below are documented as having noeffect when the mode is
off.turn_detection_timeout— the previous default of 250 ms was never the effectivedefault with turn detection enabled; the value falls back to
end_of_speech_timeout,which is 700 ms unless you set it.
0doesn't finalize the turn immediately — it leavesthe default in place. Reducing the timeout below 500 ms does not make responses arrive
sooner and does introduce transcription errors on similar-sounding words, so the page now
states a 500 ms practical floor instead of framing lower values as a responsiveness win.
turn_detection_min_length— sets the minimum length of transcript, in characters,before the punctuation path will treat a turn as complete. Range 0–1000. It's bypassed
when the acoustic signal alone is a confident end-of-turn, so short complete replies like
"Yes." still fire normally; the parameter only gates the punctuation-based path.
Checks
yarn build:specs— regeneratedfern/apis/signalwire-rest/openapi.yamlandSWMLObject.json. The large REST diff is expected for a SWML-only.tspchange.yarn fern-md-check— 2831 files valid.#params…anchors verified by hand against the convention in the page's ownlink definitions; all targets exist.
Behavior for all four parameters was confirmed against the current engine implementation
rather than taken from the existing docs.