You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -181,12 +188,21 @@ are worth understanding if you fork this connector.
181
188
### Real-time streaming bridge
182
189
183
190
`GECXStreamingSession`runs a background thread per conversation that holds one
184
-
CES `BidiRunSession` open. WxCC caller audio is pushed onto an inbound queue and
185
-
forwarded to CES; CES server messages (STT, agent text, TTS audio,
186
-
interruption, and end-of-session) are mapped to BYOVA responses on an outbound
187
-
queue. After the gateway emits `END_OF_INPUT`, it consumes that queue
188
-
incrementally instead of materializing the complete turn. The first CES audio
189
-
frame can therefore reach WxCC before CES emits `turn_completed`.
191
+
CES `BidiRunSession` open. Before speech, it retains only bounded pre-roll. At
192
+
`START_OF_INPUT`, it queues that pre-roll immediately; while speech is active,
193
+
it forwards normalized caller audio as frames arrive while retaining only a
194
+
small `input_holdback_ms` tail. `END_OF_INPUT` never requeues the complete
195
+
utterance: it adds the unsent tail and codec-correct endpointing silence. CES
196
+
server messages (recognition, agent text, TTS audio, interruption, and
197
+
end-of-session) are mapped to BYOVA responses on an outbound queue.
198
+
199
+
The CES input queue is bounded by `input_queue_max_chunks`, and each audio item
200
+
is at most `input_stream_chunk_ms`. A full queue applies the configured short
201
+
put timeout and then terminates explicitly; it does not grow memory, silently
202
+
drop audio, or accumulate unbounded latency. CES may recognize caller audio
203
+
before gateway VAD commits `END_OF_INPUT`, but caller-owned output remains
204
+
queued until that boundary so WxCC response ordering is preserved. The first
205
+
CES response-audio frame can then reach WxCC before CES emits `turn_completed`.
190
206
191
207
CES can also produce an autonomous no-input prompt after the preceding
192
208
caller-owned response has already reached `FINAL`. The connector publishes
@@ -198,7 +214,7 @@ validated end to end. When enabled, WxCC continues forwarding caller audio
198
214
while CES waits for an interruption or a reply.
199
215
200
216
When gateway VAD emits `START_OF_INPUT`, the connector opens an isolated caller
201
-
turn and waits for CES to acknowledge the committed audio with a recognition
217
+
turn and waits for CES to acknowledge the streaming audio with a recognition
202
218
result. An interruption signal does not open the gate because CES can complete
203
219
the interrupted no-input turn immediately afterward. CES output produced before
204
220
recognition belongs to that overlapping autonomous turn and is suppressed. The
@@ -235,10 +251,12 @@ caller-audio frame is ingested while CES responses are being produced.
235
251
At an apparent speech end, the gateway holds `END_OF_INPUT` for
236
252
`speech_end_grace_ms` (default: `1000`, maximum: `2000`). With the default
237
253
`end_silence_ms`value, this creates a bounded two-second natural-pause window.
238
-
If speech resumes in that window, GECX removes the endpoint-triggering pause,
239
-
merges up to `input_pause_preroll_ms` of the resumed onset, and keeps one CES
240
-
input turn. Otherwise it commits the boundary normally. Configure the observer
241
-
under the top-level `voice_activity_detection` block in `config/config.yaml`.
254
+
If speech resumes in that window, GECX discards only its unsent tail, forwards
255
+
up to `input_pause_preroll_ms` of resumed onset, and keeps one CES input turn
256
+
without emitting a duplicate endpoint. Audio already streamed to CES is never
257
+
retracted. Otherwise it commits the boundary by forwarding the held tail and
258
+
configured endpointing silence. Configure the observer under the top-level
259
+
`voice_activity_detection`block in `config/config.yaml`.
242
260
243
261
### Output audio: raw 8 kHz mu-law BYOVA chunks
244
262
@@ -400,9 +418,13 @@ window for an `EndSession` that follows the final TTS frames.
400
418
| `output_speech_preroll_ms` | No | Audio retained immediately before detected speech (default: `100`) |
401
419
| `force_input_format` | No | `wxcc` forces 8 kHz MULAW when input metadata is unavailable |
402
420
| `turn_response_timeout_seconds` | No | Maximum wait after gateway speech end for CES to complete the agent turn (default: `30`) |
403
-
| `endpointing_silence_ms` | No | Codec-correct silence appended to each buffered caller turn for CES endpoint detection (default: `2000`; one second may leave a turn open until more audio arrives) |
421
+
| `endpointing_silence_ms` | No | Codec-correct silence appended after the progressively streamed caller tail for CES endpoint detection (default: `2000`; one second may leave a turn open until more audio arrives) |
404
422
| `input_preroll_ms` | No | Bounded caller audio retained before gateway speech start to avoid clipping (default: `500`) |
423
+
| `input_holdback_ms` | No | Small unsent active-audio tail used for pause/resume and committed endpointing (default: `250`, maximum: `500`) |
405
424
| `input_pause_preroll_ms` | No | Maximum onset audio retained while a possible speech end is held, then merged if the caller resumes (default: `250`) |
425
+
| `input_stream_chunk_ms` | No | Maximum duration of each queued CES caller-audio item (default: `100`, range: `20`-`100`) |
426
+
| `input_queue_max_chunks` | No | Maximum pending CES input items before explicit backpressure failure (default: `20`, range: `1`-`200`) |
427
+
| `input_queue_put_timeout_ms` | No | Maximum wait for CES input queue capacity before terminating the session (default: `50`, maximum: `1000`) |
406
428
| `terminal_response_grace_seconds` | No | Wait for delayed `EndSession` after a terminal-sounding TTS turn (default: `3`) |
407
429
| `transfer_metadata_keys` | No | EndSession metadata keys that, when truthy, trigger a human transfer (see [Escalation](#escalation-to-a-human-agent)) |
408
430
| `transfer_reason_keywords` | No | Substrings that, if found in a reason/type metadata value, trigger a transfer |
@@ -433,11 +455,12 @@ create the JSON cache.
433
455
| Stream fails on start | `roles/ces.client`, API enabled, correct `location` |
434
456
| `404` / `UNIMPLEMENTED` on BidiRunSession | Wrong endpoint — must be regional `ces.<location>.rep.googleapis.com` (auto-derived from `location`) |
435
457
| `429 Resource exhausted` | CES per-app session quota; retry/backoff or request more quota |
436
-
| No audio to caller (silence) | Confirm `gecx_first_audio_chunk` appears, the next response is a BYOVA `CHUNK`, and output remains `MULAW` / `8000`. See [Output audio](#output-audio-raw-8-khz-mu-law-byova-chunks). |
458
+
| No audio to caller (silence) | Confirm `gecx_first_response_audio` appears, the next response is a BYOVA `CHUNK`, and output remains `MULAW` / `8000`. See [Output audio](#output-audio-raw-8-khz-mu-law-byova-chunks). |
437
459
| Long static/noise before a prompt | Look for `gecx_long_leading_audio_detected` followed by `gecx_leading_audio_suppressed`; tune the guarded output settings only with captured CES evidence. |
438
460
| Garbled speech | Confirm the gateway logs the declared WxCC encoding/sample rate; use `force_input_format: "wxcc"` only when the client omits metadata |
439
-
| Agent recognizes the caller but its reply is not audible | Confirm `gecx_pre_input_output_suppressed` is followed by `gecx_caller_input_acknowledged`, `gecx_first_audio_chunk`, and `gecx_streamed_turn_complete` for the same conversation. |
440
-
| CES logs a no-input prompt but the caller does not hear it | Confirm `gecx_first_audio_chunk` reports `delivery_mode=async`; its `barge_in_enabled` value should match connector configuration. Verify the active WxCC stream did not cancel before that timestamp. |
461
+
| Agent recognizes the caller but its reply is not audible | Confirm `gecx_pre_input_output_suppressed` is followed by `gecx_caller_input_acknowledged`, `gecx_first_response_audio`, and `gecx_streamed_turn_complete` for the same conversation. |
462
+
| CES logs a no-input prompt but the caller does not hear it | Confirm `gecx_first_response_audio` reports `delivery_mode=async`; its `barge_in_enabled` value should match connector configuration. Verify the active WxCC stream did not cancel before that timestamp. |
463
+
| Session ends with input backpressure | Correlate `gecx_input_queue_backpressure` with CES/network health. Increase `input_queue_max_chunks` only after measuring frame cadence and acceptable latency; do not mask a stalled CES stream with an unbounded queue. |
441
464
| No response after `END_OF_INPUT` | Check for `turn_completed` or a turn-completion timeout in `[GECX]` logs; increase `turn_response_timeout_seconds` if the agent regularly needs more than 30 seconds |
442
465
| `GoAway` from CES | The connector intentionally emits one `SESSION_END` and half-closes CES; it does not reconnect in the current implementation |
0 commit comments