🌿 Fern Regeneration -- November 10, 2025 - #1
Closed
fern-api[bot] wants to merge 2 commits into
Closed
Conversation
GregHolmes
added a commit
that referenced
this pull request
Jul 9, 2026
Finding 6 (ours): applyOptionsOverride rewired five separate volatile fields
while getNextDelay() read three of them, so a concurrent override could yield a
torn (min, growFactor, max) set. Hold the overridable options behind a single
volatile ReconnectOptions reference; readers snapshot it once for a consistent
view. maxEnqueuedMessages stays a separate final field (not overridable).
Finding 5 (generator bug, also flagged upstream): the TimeoutException retry
branch omitted the closing paren ('(retry attempt #1' -> '(retry attempt #1)').
dg-coreylweathers
pushed a commit
that referenced
this pull request
Jul 13, 2026
…T tuning (#73) ## Summary Fern SDK regeneration for 2026-07-09, with manual patches reconciled against the new generator output (`dd2d427 SDK regeneration`), plus a review pass that fixed a generator contract bug in the new output and two reconnect-listener issues, and the follow-ups from the #73 review. ## Regenerated output (Fern-owned, new features) - **Speak v2 WebSocket**: new `resources/speak/v2/websocket/` client (`V2WebSocketClient`, `V2ConnectOptions`) + `SpeakV2*` message types and `SpeakV2Encoding/SampleRate/Tag/MipOptOut`. - **Agent update-listen**: `AgentV1UpdateListen`, `AgentV1ListenUpdated`, `AgentV1UpdateListenListen`, plus `V1WebSocketClient` updates. - `DeepgramListenProviderV2` expanded. ## Manual patches reconciled (existing freezes) All three temporarily-frozen files were reverted to generator defaults by the regen and had their patches **re-applied** (none obsolete); `.fernignore` restored to original paths; `.bak` files deleted: - **`core/ClientOptions.java`** — correct SDK header constants + `// x-release-please-version` markers; kept `0.6.0` (release-please owns versioning), not Fern's `0.6.1`. - **`core/ReconnectingWebSocketListener.java`** — `maxRetries(0)` "connect once, don't retry" semantics, configurable `connectionTimeoutMs`, and the `applyOptionsOverride(...)` hook (required by the frozen `core/transport/TransportWebSocketFactory`). - **`listen/v2/types/ListenV2CloseStream.java`** — `hashCode()` to match generator's `equals()`. ## Review fixes **1. Fields-less `equals()`/`hashCode()` contract bug (generator).** The generator emits `equals()` (all-instances-equal) but no `hashCode()` for fields-less message types. Fixed + froze **all 11** affected types (`hashCode() { return getClass().hashCode(); }`): `ListenV2CloseStream`, `SpeakV2Close`, `SpeakV2Flush`, and the 8 `AgentV1*` event types. Stopgap — durable fix is upstream in Fern. **2. `ReconnectingWebSocketListener` reconnect-options torn read (ours).** `applyOptionsOverride` rewired five separate `volatile` fields while `getNextDelay()` read three; a concurrent override could produce an inconsistent (min, growFactor, max) set. Now held behind a single `volatile ReconnectOptions` reference so reads snapshot a consistent set. **3. `TimeoutException` message unbalanced paren (generator).** The retry branch produced `(retry attempt #1` with no closing paren. Fixed locally; also flagged upstream since the generator emits it. ## Review follow-ups (#73 review) **P0 — Flux model on `/v2/speak`.** The flagship example and the gated integration test used `aura-2-thalia-en`; switched both to `flux-alexis-en` (StreamingTtsV2.java, IntegrationTest.java), matching the JS/Python SDKs. ✅ **Ran against staging** (`DEEPGRAM_SPEAK_V2_WS=1` + `DEEPGRAM_BASE_URL=wss://api.staging.deepgram.com`): `Connected` → `SpeechStarted` → `Flushed` → binary audio → clean close. Running it surfaced a latent test bug — the test closed the socket the instant `Flushed` arrived, but Flux streams audio frames *after* `Flushed`, so audio was truncated to 0 bytes; fixed to wait for an audio frame before Close (and `setUp` now honors `DEEPGRAM_BASE_URL` so the opt-in test can target staging). **P0 — Unknown server messages no longer fatal.** The generated speak v2 dispatcher routed any unrecognized message type to `onError` ("Update your SDK version…"), making benign new server control frames look fatal to deployed voice agents. Downgraded the unknown-type branch to a **no-op** — the raw frame is already delivered via `onMessage(String)` earlier in `handleIncomingMessage`, so consumers still see it. Froze `speak/v2/websocket/V2WebSocketClient.java` (+ AGENTS.md note) so the patch survives regen, and added `SpeakV2ForwardCompatTest` as a regression guard. Mirrors JS/Python. **Note:** the listen v2 client has the identical generated bug — flagged for a follow-up (out of scope for this Speak V2 PR). **P1 — `metadata.json` disclosure corrected + reset.** The prior disclosure (below) called `sdkVersion: 0.6.1` "generator-owned"; it is in fact **release-please-tracked** (`release-please-config.json` `$.sdkVersion`). Reset it to `0.6.0` so main carries no phantom pre-bump; the manifest (`0.6.0`) drives and release-please computes the next version at release. **⚠️ Scope addition beyond the review — listen v2 forward-compat parity (`b9a9bc6`).** While fixing speak v2, `listen/v2/websocket/V2WebSocketClient.java:474` was found to have the identical generated bug (unknown frames → `onError`). Applied the same no-op patch + freeze (+ AGENTS.md) and a `ListenV2ForwardCompatTest` guard, so forward-compat is consistent across speak v2, listen v2, and the JS/Python SDKs. This wasn't in the original review scope — flagged in a PR comment; can be split into its own PR if preferred. ## Known, deferred - `V2WebSocketClient` `timeoutExecutor` dead field — generator artifact in unfrozen generated code; left for the upstream Fern request rather than freezing another file. (P2) - Aggregate fields-less `hashCode` test could be parameterized to name the failing type on failure — noted as polish. (P2) ## Docs - `AGENTS.md`: genericized the regen branch prefix (`<YOUR_INITIALS>/sdk-gen-...`) and completed the temporarily-frozen file list (all `hashCode` freezes + the new `V2WebSocketClient` forward-compat freeze now documented). ## Verification `./gradlew test compileExamples` — **BUILD SUCCESSFUL** (includes the new `SpeakV2ForwardCompatTest`). ## Tests & examples added - **`SpeakV2ForwardCompatTest`** — drives the private speak v2 dispatcher with an unknown `{"type":"FutureMessage"}` frame and asserts it is delivered raw via `onMessage(String)` and **not** routed to `onError`. Regression guard for the forward-compat fix above. - **`RegenTypesTest`** — `FieldsLessMessageContract` case asserts the `equals`/`hashCode` contract for all newly-patched fields-less types, so a future regen dropping a `hashCode()` is caught. - **`examples/speak/StreamingTtsV2.java`** — exercises the new Speak v2 WebSocket client (now on `flux-alexis-en`), mirroring the v1 example; compile-covered via `compileExamples`. - **`IntegrationTest`** — opt-in Speak v2 WebSocket test (`testIntegration_SpeakV2WebSocket`, Tier 2), now on `flux-alexis-en`: connect → sendSpeak/sendFlush/sendClose → streamed audio, asserting a Flushed message and non-zero audio bytes. Gated on `DEEPGRAM_SPEAK_V2_WS` and **skipped by default**; run it against staging before merge. Not added (by design): a torn-read unit test for the reconnect snapshot (timing-dependent/flaky), and an agent update-listen example (nice-to-have, no dependency). --------- Co-authored-by: fern-api[bot] <115122769+fern-api[bot]@users.noreply.github.com>
GregHolmes
added a commit
that referenced
this pull request
Aug 12, 2026
…provider + google version (#92) Regenerates the SDK against the latest Fern generator (`4.10.1` → `4.16.0`) and API spec (`ff8fd2b` → `03f0677`), reconciles the hand-maintained patches, and documents the resulting breaking changes with a migration guide. Supersedes the reverted #89. ## Base Stacked on the revert branch (#91). Until that merges, this PR's diff includes the revert commit; merge #91 first (or it rides along). ## ⛔ Blocked / do not merge yet Regenerated from an **unmerged spec branch**: `.fern/metadata.json` `originGitCommit` `03f0677` lives only on `origin/jherlihy/flux-tts-ga`, not on `deepgram-docs` `main`. The launch surface here (`breaks_applied`, `ConfigureFailure`, `expressivity`, `speed`, `redact`) exists only on that branch. Kept as a **draft** until it lands. - **Blocked-on:** `deepgram-docs#1094` (Flux TTS copy) + the `jherlihy/flux-tts-ga` spec branch merging to `deepgram-docs` `main`. ## Breaking changes (pre-1.0, source/compile-time only) All three follow the API definition; on-the-wire payloads for existing requests are unchanged. Full before/after in [`docs/Migrating-v0.7-to-v0.8.md`](./docs/Migrating-v0.7-to-v0.8.md). 1. **`AgentV1UpdateListenListen.provider`** retyped `DeepgramListenProviderV2` → `AgentV1UpdateListenListenProvider` (V1/V2 union). Wrap with `AgentV1UpdateListenListenProvider.v2(...)`; read via `getV2()`. 2. **`Google.version`** retyped `Optional<String>` → `Optional<GoogleThinkProviderVersion>`. Use the enum constants (`V1BETA`, `AI_STUDIO_V1BETA`, `GEMINI_ENTERPRISE_AGENT_V1`). 3. **`SpeakV2SpeechMetadataControlsApplied`** gains a required `breaksApplied` field (new builder step; new `getBreaksApplied()`). Read paths unaffected. Origin verified: #2 and #3 are new in the latest spec; #1's union shape existed in #89 but was previously hidden behind an in-SDK shim we intentionally did not carry forward. ## Reconciliation (post-regen review) Diffed each of the 17 `.bak` patches against the freshly generated originals — **all 17 still needed**, none dropped. `.fernignore` restored to its pre-prep state; all `.bak` files deleted. - **13 restored verbatim** (generator produced no other changes): the 11 fields-less `hashCode()` types, `ReconnectingWebSocketListener` (override hook / `connectionTimeoutMs` / `maxRetries(0)` semantics), and the `listen/v1` + `speak/v1` websocket clients (query-param repeats + `additionalProperties`). - **2 surgically merged** (`listen/v2` + `speak/v2` websocket clients): re-applied `QueryStringMapper` array-param serialization, the `additionalProperties` escape hatch, and the forward-compat unknown-message no-op, **while keeping the generator's new features** (speak/v2 `sendInterrupt`/`sendConfigure` + `onSpeechInterrupted`/`onConfigureSuccess`/`onConfigureFailure`; listen/v2 `redact`). - **`ClientOptions`**: kept the new retry-tuning options + `ResponseDecompressionInterceptor`; re-applied only the two `// x-release-please-version` header lines (colon SDK-name form), removed the generator's `getSdkVersion()` helper (build does not stamp the JAR manifest, so it would drift). ## Additive highlights Speak V2 interrupt/configure, Listen V2 `redact`, Speak V2 `speed`/`expressivity`, new Deepgram Flux TTS voices, client retry tuning, automatic response decompression. ## Tests added - `ListenV2ConnectWireTest`: new `redact` connect param (present as wire `numbers`, omitted when absent). - `RegenTypesTest` → "2026-08-11 regen type shapes": the three breaking shapes (provider union v2 factory/`getV2`/serialization, `Google.version` enum wire value, `ListenV2Redact` wire values). ## Verification - `./gradlew unitTest` ✅ · `spotlessCheck` ✅ · `compileExamples` ✅ - `./gradlew integrationTest` ✅ (Tier 1 + Tier 2 against a live key); opt-in Speak V2 WS integration ✅ (returned audio over the new v2 WS path) - Ran all non-`manage` examples: 19 pass, 7 long-running streaming/agent examples connected and worked, 4 environmental (proxy / file-arg / callback URL / SageMaker) — no SDK regressions. ## Post-review additions (from #91 review) - **Re-applied the union default-variant fix** the #89 revert forfeited (issue #93): `defaultImpl = V2Value` on `AgentV1UpdateListenListenProvider`, `AgentV1SettingsAgentListenProvider`, `AgentV1SettingsAgentContextListenProvider`, so a provider payload omitting the optional `version` discriminator (what 0.7.x emits) deserializes as V2 instead of dropping to `{"provider":null}`. Frozen in `.fernignore` + `AGENTS.md`, guarded by the re-added `AgentSettingsProviderDefaultTest`. The `getProvider()` return-type shim is intentionally **not** re-applied — that retype is a deliberate breaking change (see the migration guide). ## Core behavior changes (generator 4.10.1 → 4.16.0) Beyond the spec features, the generator upgrade changes core HTTP-client behavior worth calling out in the release notes: - **Automatic response decompression** is now installed by default (`ResponseDecompressionInterceptor`): gzip/deflate-encoded HTTP responses are transparently decoded. No API change; transparent to callers. - **New optional retry tuning** on `ClientOptions.Builder`: `initialRetryDelayMillis`, `maxRetryDelayMillis`, `retryJitterFactor`. All defaulted — existing behavior is unchanged unless set. ## Follow-ups - Once this lands, release-please cuts a fresh release at **0.8.0** (breaking `feat!`). - **Changelog needs a manual edit before releasing.** `5b6323a` (#89 `feat(regen)`) is still in release-please's range since `v0.7.1`, and release-please can't pair a revert with the commit it reverts — so the generated 0.8.0 notes will re-list the reverted #89 features (`diarize_info`, force-end-turn) under Features. Hand-edit the release PR's `CHANGELOG.md` to drop them before merging it. BREAKING CHANGE: `AgentV1UpdateListenListen.provider` is now `AgentV1UpdateListenListenProvider` (V1/V2 union); `Google.version` is now `Optional<GoogleThinkProviderVersion>`; `SpeakV2SpeechMetadataControlsApplied` has a new required `breaksApplied` field. See docs/Migrating-v0.7-to-v0.8.md. --------- Co-authored-by: fern-api[bot] <115122769+fern-api[bot]@users.noreply.github.com>
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.
This PR regenerates code to match the latest API Definition.