Realtime error surfacing (Session):
- Add maybe_emit_response_done_error/2 to detect failed status in
response.done payloads and emit ErrorEvent to subscribers
- Handle response.done failures arriving via both websocket_event
and RawServerEvent paths with response_done_error/1 extraction
- Fix tool_choice serialization for {:function, name} to emit
top-level "name" key instead of nested "function" map for
session.update compatibility
Example skip-reason generalization:
- Replace boolean insufficient_quota? field with skip_reason string
across realtime_basic, realtime_handoffs, live_realtime_voice,
and realtime_tools examples
- Add skip_reason_for_error/1 detecting both insufficient_quota and
realtime_model_unavailable (model_not_found / "do not have access")
- Refactor realtime_tools to use main/0 entry point with
{:ok, :error, :skip} return protocol, matching other examples
- Add deterministic function tool_choice to realtime_handoffs demo
for stable CI runs; return {:error, {:handoff_not_observed, _}}
on missed handoff instead of silent :ok
Voice example hardening:
- Refactor voice_pipeline, voice_with_agent, voice_multi_turn to
main/0 entry point with tagged return protocol
- Replace System.halt(1) error paths with tagged error tuples
- Track error_count, session_ended?, and insufficient_quota? in
stats maps instead of bare {bytes, turns} tuples
- Add preflight TTS quota check to voice_multi_turn to fail fast
on quota exhaustion before starting full pipeline
- Add evaluate_stream_result/1 to distinguish quota skip, error,
incomplete, and success outcomes
TTS fail-fast (OpenAITTS):
- Add normalize_stream_start_response/1 to check HTTP status on
initial response and return {:error, {:api_error, status, body}}
for non-2xx statuses instead of entering streaming state
- Raise RuntimeError on stream transport errors and process DOWN
instead of silently halting with {:error, _}
- Raise on 30s stream timeout instead of returning error tuple
Misc fixes:
- Fix live_app_server_approvals: use prompt that exercises approvals
more reliably, increase trailing-message wait from 0ms to 250ms,
add note when no approval requests observed
- Fix live_attachments_and_search: replace PNG base64 payload with
known-good minimal 1x1 PNG to avoid decoder drift
- Add runtime note to tool_bridging_auto_run when transport does
not inject tool outputs
- Update guide 06-realtime-and-voice.md: document model_not_found
skip reason, fix lifecycle event name, note response.done error
surfacing
CHANGELOG:
- Add Unreleased section with Changed and Fixed entries
- Remove duplicate Realtime API surface changelog entries from 0.8.0
section (already shipped in prior commit)
Test additions:
- Add response.done failure tests for both websocket_event and
raw server event paths (ErrorEvent emission with source_event
and response_id fields)
- Add function tool_choice serialization test (top-level name key)
- Add TTS non-success status test (RuntimeError with api_error)
- Add TTS stream transport error test (RuntimeError with reason)