Skip to content

feat(regen): add Speak V2 streaming, agent update-listen, and Flux EOT tuning#742

Open
GregHolmes wants to merge 8 commits into
mainfrom
gh/sdk-gen-2026-07-08
Open

feat(regen): add Speak V2 streaming, agent update-listen, and Flux EOT tuning#742
GregHolmes wants to merge 8 commits into
mainfrom
gh/sdk-gen-2026-07-08

Conversation

@GregHolmes

@GregHolmes GregHolmes commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Fern SDK regeneration (2026-07-08). Pulls in new generator output, re-applies the hand-maintained patches, extends the socket-client convention to the new client, and adds test + example coverage for the new surface.

New public surface (Fern-generated this regen)

  • Speak V2 — Flux TTS WebSocket (client.speak.v2.connect(...)): new speak/v2/ package (client, socket client, request/response types) plus top-level SpeakV2Encoding/MipOptOut/Model/SampleRate/Tag.
  • Agent mid-session listen reconfigure: send_update_listen(...) with AgentV1UpdateListen/AgentV1UpdateListenListen, and the AgentV1ListenUpdated server acknowledgement.
  • Flux end-of-turn tuning fields on the listen providers: eot_threshold, eager_eot_threshold, eot_timeout_ms.

Manual-patch reconciliation

The generator caught up on none of the existing back-compat concerns, so all 25 frozen patches were re-applied (nothing dropped from .fernignore), preserving the new generator additions:

  • Legacy alias re-exports merged back into the package __init__.py files (kept alongside the new SpeakV2* / AgentV1* entries).
  • language_hintlanguage_hints migration shim re-added to the three listen-provider models (kept alongside the new eot_* fields).
  • Agent socket client: _sanitize_numeric_types, broad except Exception, optional send_keep_alive (kept the new send_update_listen).
  • listen/v1, listen/v2, speak/v1 socket clients, query_encoder bool coercion, agent_v1settings* back-compat, create-key alias + wire test — all restored.

Judgment call — listen/v2 send_configure shim: kept

The generator now emits complete ListenV2Configure/ListenV2ConfigureSuccess models, but adopting them changes the public signature (raw dict → model, typed responses) — a breaking change. The typing.Any shim is kept for this maintenance regen; typed-model adoption is deferred to a future major/minor.

New: Speak V2 socket-client patch

The newly generated speak/v2/socket_client.py was made consistent with the other four socket clients and frozen:

  • Broad except Exception (preserves the custom-transport error contract — a transport can raise arbitrary types; the narrow generated catch would leak them past the message loop).
  • Optional send_flush() / send_close() for no-payload control messages (parity with speak/v1).

Test & example coverage

  • tests/custom/test_speak_v2_socket.py — send serialization, response-type parsing, broad-except error emission, and forward compatibility: an unknown/future message type passes through untouched on all four receive paths (sync + async recv() and the start_listening loop), so a newer server never breaks an older client.
  • tests/custom/test_speak_v2_connect_wire.pyconnect request wire shape (sync + async): targets the /v2/speak path and serializes query params, incl. mip_opt_out=True"true"; doubles as the wire-level guard on the frozen query_encoder bool coercion. Frozen in .fernignore since Fern never generates websocket-connect wire tests.
  • tests/custom/test_eot_thresholds_feature.pyeot_* fields serialize on all three listen providers.
  • tests/custom/test_agent_update_listen.pysend_update_listen serialization + AgentV1ListenUpdated resolution.
  • tests/manual/speak/v2/connect/ — standalone scripts (main / async / with_auth_token / with_raw_response), parity with speak/v1; now accept a DEEPGRAM_BASE_URL override for non-prod (staging) targeting.
  • examples/25-text-to-speech-streaming-v2.py (+ examples/README.md entry).
  • reference.md — new "Speak V2 Connect" section and send_update_listen added to the Agent V1 send methods.

Verification

  • mypy src/ — clean (844 files)
  • mypy tests/typecheck — clean
  • pytest — 318 passed, 1 skipped (pre-review baseline; the review follow-up tests below add 6 more and pass)
  • pytest tests/custom — 205 passed, 1 skipped (includes the new forward-compat + connect-wire tests)
  • ruff check / mypy on the review follow-up files — clean

Release telemetry — version drift fix

client_wrapper.py is a generic extra-file in release-please-config.json, but the generic updater only rewrites lines carrying an annotation — and the two version header lines had none, so release-please never bumped the wire telemetry version. It drifts from the published package version (the pre-existing pattern: main shipping 7.4.0 while sending 7.3.2, and this branch would send 7.4.1 against a 7.5.0 release).

  • Added # x-release-please-version to the User-Agent and X-Fern-SDK-Version header lines so they bump in lockstep with the release.
  • Froze client_wrapper.py in .fernignore — it is a live Fern-generated file, so a regen would strip the annotations otherwise — and documented the freeze + re-apply step in AGENTS.md.

Live end-to-end ✅ validated against staging

Prod /v2/speak (Flux) returns HTTP 400 at the handshake until GA, so the manual connect scripts accept a DEEPGRAM_BASE_URL override to point at staging:

DEEPGRAM_BASE_URL=wss://api.staging.deepgram.com DEEPGRAM_API_KEY=<staging-key> \
  poetry run python tests/manual/speak/v2/connect/main.py

Ran against staging (wss://api.staging.deepgram.com), both sync and async: Connect → Speak → Flush → Close completes end to end — Connected (model alexis, v 2026-07-02.2) → SpeechStarted → 20 binary audio frames (~77 KB) → FlushedSpeechMetadataSessionMetadata → clean close. The forward-compat and connect-wire unit tests remain the regression guards; this confirms the real handshake + streaming path.

fern-api Bot and others added 4 commits July 8, 2026 15:19
…nce.md

Apply the socket-client patch convention to the newly generated
speak/v2/socket_client.py so it is consistent with the other four
clients: broad `except Exception` (custom-transport error contract)
and optional `send_flush()`/`send_close()` for no-payload control
messages. Freeze it in .fernignore and add regression coverage.

Document the new Speak V2 WebSocket in reference.md and add
send_update_listen to the Agent V1 send-methods section.
…fields

Cover the functionality introduced by the 2026-07-08 regen that shipped
with only indirect coverage:

- tests/custom/test_speak_v2_socket.py: Speak V2 send serialization,
  response-type parsing, and broad-except error-emit behavior.
- tests/custom/test_eot_thresholds_feature.py: eot_threshold /
  eager_eot_threshold / eot_timeout_ms serialize on the three listen
  providers (mirrors test_language_hints_feature.py).
- tests/custom/test_agent_update_listen.py: send_update_listen
  serialization + AgentV1ListenUpdated response resolution.
- tests/manual/speak/v2/connect/: standalone connect scripts (main,
  async, with_auth_token, with_raw_response), parity with speak/v1.
- examples/25-text-to-speech-streaming-v2.py: Speak V2 streaming example.

Freeze the three new custom tests in .fernignore.
@GregHolmes GregHolmes changed the title chore: SDK regeneration 2026-07-08 feat(regen): Speak V2 TTS websocket, agent update-listen, Flux EOT tuning Jul 9, 2026
…g E2E

Addresses review feedback on the Speak V2 (Flux TTS) update:

- Forward compat: add unknown-message coverage across all four receive
  paths (sync/async recv() and start_listening loop) in
  test_speak_v2_socket.py, pinning that an unrecognized message type
  passes through as a raw dict without raising or dropping the connection.
- Wire shape: add test_speak_v2_connect_wire.py asserting connect targets
  /v2/speak and serializes query params, incl. mip_opt_out=True -> "true"
  (also guards the frozen query_encoder bool-coercion patch). Frozen in
  .fernignore since Fern never generates websocket-connect wire tests.
- Staging E2E: the manual connect scripts hardcoded production; add an
  env-driven DEEPGRAM_BASE_URL override so they can target staging.
client_wrapper.py is a `generic` release-please extra-file, but the generic
updater only rewrites annotated lines. Without annotations the User-Agent and
X-Fern-SDK-Version headers never get bumped, so wire telemetry drifts from the
published package version (main shipping 7.4.0 while sending 7.3.2).

Add `# x-release-please-version` to both header lines so they bump in lockstep
with the release. Freeze client_wrapper.py in .fernignore (it is a live
Fern-generated file that would otherwise be regenerated without the
annotations) and document the freeze in AGENTS.md.
@GregHolmes GregHolmes changed the title feat(regen): Speak V2 TTS websocket, agent update-listen, Flux EOT tuning feat(regen): add Speak V2 TTS websocket, agent update-listen, and Flux EOT tuning Jul 13, 2026
@GregHolmes GregHolmes changed the title feat(regen): add Speak V2 TTS websocket, agent update-listen, and Flux EOT tuning feat(regen): add Speak V2 streaming, agent update-listen, and Flux EOT tuning Jul 13, 2026
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