Skip to content

feat(provider-utils): WS proxy tunnel + RFC-0034 (realtime STT follow-ups) - #183

Draft
eric8810 wants to merge 5 commits into
masterfrom
rfc-0034/ws-proxy
Draft

feat(provider-utils): WS proxy tunnel + RFC-0034 (realtime STT follow-ups)#183
eric8810 wants to merge 5 commits into
masterfrom
rfc-0034/ws-proxy

Conversation

@eric8810

@eric8810 eric8810 commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Implements RFC-0034 (draft: rfc/0034-realtime-stt-followups.md), the RFC-0028 follow-ups tracked in #178. Research record: #178 (comment).

This PR carries the RFC plus P1 (WS proxy tunnel). P2 (ElevenLabs realtime) is #184, stacked on this branch. P3 (Cartesia) is deferred with explicit restart triggers (RFC-0034 §4/D6: docs behind a login wall, young turns API, unverifiable wire — deferral costs nothing).

P1 — WS proxy tunnel

ws_connect honors the global ProxyConfig (the one init_proxy sets for HTTP):

  • wss://https_url, ws://http_url, all_url fallback; no proxy configured → direct path unchanged.
  • no_proxy matching aligned with reqwest semantics (suffix, *, port-specific entries); known CIDR divergence documented.
  • HTTP CONNECT tunnel (manual TCP → CONNECT with Basic proxy auth → 2xx validation → client_async_tls_with_config; explicit ring provider + webpki-roots for wss targets).
  • SOCKS/https-scheme proxies fail loudly, never silently bypass; CONNECT rejections classified by the shared is_retryable_status rule (5xx transient, 407 terminal).
  • Every tunnel await is abort-raced and bounded by first_chunk_ms.

Review round

An independent review pass surfaced and fixed: IPv6 proxy host brackets, proxy-credential leakage in errors, blanket non-retryable CONNECT verdicts, and the missing promised tests (abort-in-tunnel, black-hole timeout, 503 retryability, CONNECT wire shape). 16 tests total; workspace clippy clean.

Closes #178 (item 1 resolved by P2 + documented deferral; item 2 by P1; item 3 wontfix per research).

…bs/Cartesia do_stream)

P1 WS proxy tunnel honoring the global ProxyConfig (CONNECT + no_proxy,
SOCKS errors loudly); P2 ElevenLabs scribe_v2_realtime do_stream; P3
Cartesia ink-2 do_stream. No unified session abstraction (D1), minimal
parameter surface (D5). Closes #178 (research record attached there).
…proxy (RFC-0034 P1)

ws_connect now consults the global ProxyConfig that already governs
HTTP: wss uses https_url (all_url fallback), ws uses http_url (all_url
fallback), no_proxy entries are honored with reqwest NoProxy semantics
(comma-separated, suffix match, '*', port-specific entries), and matched
targets keep the direct path unchanged.

Tunneled connects: manual TCP to the proxy -> CONNECT (with Basic
Proxy-Authorization from proxy-URL userinfo) -> 2xx validation -> WS
handshake over the tunnel via client_async_tls_with_config (explicit
ring provider + webpki-roots for wss targets, Plain for ws). SOCKS and
https-scheme proxies fail loudly as UnsupportedFunctionality instead of
silently bypassing the configured proxy; proxy CONNECT rejections
surface as non-retryable ApiCall errors carrying the proxy status.

The tunnel steps are bounded by first_chunk_ms and raced against abort
by the existing ws_connect select. rustls/webpki-roots/base64 join the
optional 'ws' feature only.
Independent review (PR #183) surfaced three defects and a test gap:

- IPv6 proxy hosts never connected: url::Url::host_str returns bracketed
  literals and the socket resolver wants the bare address — strip them.
- Proxy credentials leaked into error strings: all resolve_proxy error
  paths now mask userinfo (scheme://***@host), matching the existing
  request-URL sanitization.
- CONNECT rejections were blanket non-retryable: classify by the shared
  is_retryable_status rule (407/403 stay terminal, 502/503/504 retry);
  EOF-before-response (status 0) is transient.
- Missing promised tests added: abort during the CONNECT tunnel (against
  a black-hole proxy), unresponsive proxy tripping first_chunk_ms, 503
  retryability, CONNECT wire shape (request line, Host, no stray
  Proxy-Authorization), IPv6 bracket stripping, credential masking.
- no_proxy docstring now states the CIDR divergence; init_proxy documents
  that WS reads the config live.
- RFC-0034: OQ2 verified and closed — stream_transcribe has no attempt
  retry and should not (audio input is consumed once; replayable sources
  would be new design). Status line and test list updated to match what
  landed.
…l cost

Re-review after P1: the decisive difference vs P2 (ElevenLabs) is
verifiability. ElevenLabs ships a public API reference, so mock tests
pin documented facts; Cartesia's turns API is behind a login wall, its
event schema is only inferable from the Python SDK, and the API is new
enough to churn — on top of the D4 lesson that mock-only wire shapes
can be wrong. Deferring loses nothing: ink-2 already fails honestly
with UnsupportedFunctionality on both paths, and nothing depends on it.

Restart triggers (any one): a user asks; the docs come out from behind
the login wall; a key + smoke decision. Gate comment in cartesia.rs
records the deferral. D6 added.
…smoke through the proxy tunnel

P4 of RFC-0034 plus the executable closure of P1's untested wss branch:

- RFC-0028: status line points at RFC-0034 for the follow-ups; §3.4's
  'skeletons are isomorphic, add as needed' corrected to the actual
  outcome (per-provider implementations, no shared layer); Open
  Questions 2/4 resolved (WS proxy landed; ElevenLabs landed, Cartesia
  deferred with triggers, xAI dropped), 5 linked to #167's
  transport-level replay.
- New #[ignore] smoke: wss://api.elevenlabs.io through the local CONNECT
  proxy — no key needed, the real server answering the handshake (HTTP
  rejection or in-session auth error) proves the tunnel + rustls
  webpki-roots path executed against a real public CA chain. Ran green;
  fixture now maps https_url to the fake proxy so wss targets tunnel.
- Full transcript round-trip smoke still needs a provider key (D4
  posture, flagged in code and RFC-0034).
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.

Transcription streaming follow-ups (RFC-0028): remaining WS providers, proxy gap, callback mode

1 participant