feat(regen)!: speak v2 interrupt/configure, listen v2 redact; retype provider + google version - #92
Conversation
dg-coreylweathers
left a comment
There was a problem hiding this comment.
Content approved — holding merge until the spec branch lands. Three fixes are needed first, and none of them depend on the gate.
The regen itself is clean, and I verified it mechanically rather than from the body: removed public members vs released 0.7.1 come to exactly three, and they are exactly the three declared. Zero deleted types, zero renames, zero narrowed enums. All 17 hand patches survive, the additionalProperties escape hatch reaches the wire on all four WS clients, and compileJava compileExamples unitTest spotlessCheck is BUILD SUCCESSFUL locally in Docker. The apparent deletions against main — diarize types, ListenV2TurnInfo.trigger, channel-word speaker_confidence — are all unreleased #89 additions, so non-breaking against the released baseline.
The new barge-in README section and example are the strongest developer-facing work here. Every API call checks out against the tree (including the easy-to-get-wrong bit: getTextSpoken()/getTextRemaining() are on the event, not nested in metadata), and every behavioral claim traces to spec.
Blocking
[B1] Merge gate — regenerated from an unmerged spec branch. originGitCommit 03f0677 is not on deepgram-docs main; git branch -r --contains returns only origin/jherlihy/flux-tts-ga. breaks_applied — declared breaking change #3 — has 0 occurrences on merged main and 2 on the branch, as do ConfigureFailure and expressivity. Maven releases are immutable, and this PR declares a 0.8.0 release plan. Python #758 and JS #532 both name the branch in their first sentence and are both drafts. Please mark this draft, name the branch in the body, and add a Blocked-on line for the branch's docs PR and deepgram-docs#1094.
[B3] Migration guide's retry-tuning snippet doesn't produce a DeepgramClient. docs/Migrating-v0.7-to-v0.8.md:57-64. Compiled it: error: incompatible types: DeepgramApiClient cannot be converted to DeepgramClient. The three knobs live only on the base DeepgramApiClientBuilder; DeepgramClientBuilder narrows ten inherited setters but not these three, so the chain degrades and build() returns the wrong client. As printed (no assignment) it compiles and silently builds a DeepgramApiClient. Fix by restoring the three covariant overrides on both DeepgramClientBuilder and AsyncDeepgramClientBuilder — verified that makes the snippet compile unchanged:
@Override
public DeepgramClientBuilder initialRetryDelayMillis(long initialRetryDelayMillis) {
super.initialRetryDelayMillis(initialRetryDelayMillis);
return this;
}
@Override
public DeepgramClientBuilder maxRetryDelayMillis(long maxRetryDelayMillis) {
super.maxRetryDelayMillis(maxRetryDelayMillis);
return this;
}
@Override
public DeepgramClientBuilder retryJitterFactor(double retryJitterFactor) {
super.retryJitterFactor(retryJitterFactor);
return this;
}[B4] Both Google snippets omit the required model() stage. docs/Migrating-v0.7-to-v0.8.md:138-141,151-155. Google.builder() returns ModelStage; version(...) is on _FinalStage. Compiled: cannot find symbol: method version(GoogleThinkProviderVersion), location: interface ModelStage. True of the "before" snippet too — builder() returned ModelStage in 0.7.1 as well. Insert .model(GoogleThinkProviderModel.GEMINI25FLASH) in both (constants are GEMINI25FLASH / GEMINI20FLASH / GEMINI20FLASH_LITE, not GEMINI_2_5_FLASH). Same applies to the provider-union snippets at :102/:119, where DeepgramListenProviderV2.builder() also needs .model("flux-general-en").
[B5] 71cbe4e and 2cfc3d5 hand-edit generated files that aren't frozen. src/main/java/com/deepgram/types/Deepgram.java and src/main/java/com/deepgram/resources/speak/v2/audio/requests/SpeakV2Request.java — twelve javadoc edits, and neither path is in .fernignore or AGENTS.md, so the next regen reverts all twelve silently with no test to catch it. Deepgram.java used to be frozen; this PR's own .fernignore diff removes the type-rename block that listed it. Since both edits pre-apply copy from the unmerged deepgram-docs#1094 — and the strings come from spec description fields — the cleanest fix is to drop both commits and let the copy arrive by regeneration once #1094 merges. If it has to ship now, freeze both paths properly with a matching AGENTS.md entry and an unfreeze condition.
[B6] The 0.8.0 changelog will advertise the reverted #89 features. 5b6323a ("feat(regen): add diarize_info, Flux force-end-turn, update-listen, word speaker confidence") is still in release-please's range since the v0.7.1 tag, and release-please can't pair a revert with the commit it reverts. So 0.8.0's notes will list diarize_info and force-end-turn under Features — re-asserting in the release notes exactly what c55725f correctly removed from the migration guide. Needs a human edit of the generated release PR's changelog before merging it; worth adding as an explicit Follow-ups step.
Should-fix
[S1] pom.xml:169 — dropping addDefaultImplementationEntries strips Implementation-Title/Implementation-Version from the published jar. The Gradle half of the revert is right (nothing reads getSdkVersion() any more), but the Maven half only removes artifact metadata and can't cause the drift it guards against. Suggest restoring just the pom.xml hunk.
[S2] No wire test for speed, expressivity, sendInterrupt, or sendConfigure — the four symbols sourced from the unmerged branch, so the highest-churn surface here. SpeakV2ConnectWireTest has only the two tag cases. Mirror the two redact cases you added on the listen side, and add a send-frame test including an Interrupt with a playback_offset.
[S3] examples/speak/StreamingTtsV2.java:41,162 — BYTES_PER_SECOND = 32000 is correct only for the LINEAR16 @ 16 kHz set 100 lines away, and the comment above that builder invites changing it. The offset is load-bearing server-side (it drives the text_spoken/text_remaining split and must advance monotonically), so derive it from a shared sample-rate constant.
Nits
.fern/metadata.json:18—sdkVersionis0.7.2while all five other markers and the latest release say0.7.1..fern/metadata.json:2—cliVersiongoes backwards 5.89.0 → 5.44.6 while the body says "latest Fern generator". Accurate forgeneratorVersion, but worth naming the CLI pin so the next reviewer doesn't chase it as I did..fern/metadata.json:13—runtime-version: trueremains aftergetSdkVersion()was stripped, so every regen re-emits a helper someone must remove by hand.examples/speak/StreamingTtsV2.java:147-160— the barge-in rewrite dropped the multi-chunk send loop, but the class javadoc still says "Sends text chunks". Splitting the long utterance across two or threesendSpeakcalls restores it and keeps the barge-in demo intact.
Worth noting
The README is clean across two review passes because ReadmeSnippetsCompileTest extracts and compiles every ```java fence at test time. docs/*.md has no equivalent gate, and B3/B4 have now survived two passes as a direct result. Pointing the same machinery at `docs/Migrating-*.md` would have caught both and will catch the next guide's — I built that harness to find these, so it's a small change.
#91) Reverts the listen v2 regen (`5b6323a`, originally #89: Flux force-end-turn, listen v1 diarize metadata + arch, word speaker confidence, `AgentV1UpdateListen` provider retype, `ListenV2Redact`) off `main`. Mirrors the equivalent revert on deepgram-python-sdk: deepgram/deepgram-python-sdk#757 ## Why This work isn't ready to ship yet, and other priorities need to release from `main` without it. Since the regen is already on `main`, any release cut from `main` (including the pending release-please 0.7.2, #90) would publish it. Reverting removes it from the release line cleanly, without rewriting history. ## Redoing the regen The regen commit `5b6323a` stays reachable in history (and on the #89 branch), and the next regen branch `gh/sdk-gen-2026-08-11` (#92) is stacked on this revert. **Caveat:** re-landing is a fresh 4.16.0 regen, not a replay of #89's hand-patches — see "Forfeited by this revert" below. ## Also reverted (not spec features) Beyond the five spec features, this 184-file revert also rolls back: - **Fern toolchain downgrade** (`.fern/metadata.json`): `cliVersion` 5.89.0 → 5.44.6, `generatorVersion` 4.16.0 → 4.10.1, `runtime-version` dropped. This is what makes most of the rest follow. - **Restores** the `ClientOptions.java` `.fernignore` freeze block + its release-please `generic` extra-file entry (both dropped by #89) — this is what keeps `X-Fern-SDK-Version` release-please-bumpable (no wire-version drift). - **Removes** the three 4.16.0-era stopgap freeze blocks (type-rename, return-type shim, union default-variant) and the `ListenV2ForceEndTurn` `hashCode()` entry from `.fernignore` and `AGENTS.md`. - **`README.md`**: removes the 4.16.0 retry-knob docs (retry-behavior prose that remains accurate has been restored — see the diff). ## Forfeited by this revert (tracked in #93) The revert also drops patches #89 carried that are **not** preserved on `gh/sdk-gen-2026-08-11` and **not** among #92's 17 reconciled patches (verified: all three unions read `defaultImpl = _UnknownValue.class` on #92, both tests absent): - **Union default-variant fix** (`defaultImpl = V2Value`) on `AgentV1UpdateListenListenProvider`, `AgentV1SettingsAgentListenProvider`, `AgentV1SettingsAgentContextListenProvider`. The two Settings unions carry this bug in **released 0.7.1** (pre-existing, not a regression), so the revert restores released behavior — it forfeits an *unreleased* fix. - **`AgentV1UpdateListenListen.getProvider()` additive return-type shim.** - **Regression guards** `AgentV1UpdateListenShimTest.java`, `AgentSettingsProviderDefaultTest.java`. Whether to re-apply the `defaultImpl` fix on #92 is a deliberate decision tracked in #93. ## Verification - `./gradlew compileJava compileExamples unitTest` — build successful, all unit tests pass. - The revert is a clean inverse of the single regen commit (184 files): `git diff 5b6323a^ HEAD` over the pre-README-fix tree is empty (byte-identical to the 0.7.1 release commit `8b3c605`). Restores pre-regen `.fern/metadata.json` (sdkVersion 0.7.1, generator 4.10.1), the `.fernignore` freeze blocks, and the `release-please-config.json` `ClientOptions.java` generic entry. - Escape-hatch (`additionalProperties`), forward-compat no-op, and fields-less `hashCode()` patches from 0.7.1 all survive.
…/example/pom/wire-test fixes - B3: add covariant initialRetryDelayMillis/maxRetryDelayMillis/retryJitterFactor overrides to DeepgramClientBuilder + AsyncDeepgramClientBuilder so the fluent chain returns DeepgramClient. - B4: fix migration-guide snippets — add required .model(...) to the Google and provider-union builders. - S1: restore addDefaultImplementationEntries in pom.xml maven-jar-plugin. - S2: add SpeakV2 wire coverage — speed/expressivity connect params + sendInterrupt/sendConfigure frames. - S3+nit: derive the example's bytes/sec from a shared SpeakV2SampleRate; restore the multi-chunk send loop. - nit: .fern/metadata.json sdkVersion 0.7.2 -> 0.7.1 to match the other markers.
…, streaming query-param patches)
…union, google version enum)
…ads aren't dropped
Fern points the union @JsonTypeInfo defaultImpl at the empty-bodied _UnknownValue, so a
provider payload omitting the optional "version" discriminator (what 0.7.x emits)
deserialized to null and re-serialized as {"provider":null}, silently dropping the
provider. Patch defaultImpl = V2Value on the three agent listen-provider unions, freeze them
in .fernignore, and guard with AgentSettingsProviderDefaultTest. Re-applies the fix the #89
revert forfeited (issue #93).
…fidence (not in this regen)
… (matches deepgram-docs#1094)
…ches deepgram-docs#1094 intent)
…/example/pom/wire-test fixes - B3: add covariant initialRetryDelayMillis/maxRetryDelayMillis/retryJitterFactor overrides to DeepgramClientBuilder + AsyncDeepgramClientBuilder so the fluent chain returns DeepgramClient. - B4: fix migration-guide snippets — add required .model(...) to the Google and provider-union builders. - S1: restore addDefaultImplementationEntries in pom.xml maven-jar-plugin. - S2: add SpeakV2 wire coverage — speed/expressivity connect params + sendInterrupt/sendConfigure frames. - S3+nit: derive the example's bytes/sec from a shared SpeakV2SampleRate; restore the multi-chunk send loop. - nit: .fern/metadata.json sdkVersion 0.7.2 -> 0.7.1 to match the other markers.
3402070 to
21db050
Compare
Transcribed from the approved deepgram-docs#1090 spec (4170ce53), which defers both inline controls at GA. Two descriptions were not merely stale but inverted: SpeakV2Request said batch "rejects the whole request with a 400" (the server now strips the control instead), and SpeakV2Speak said a malformed control is fatal via DATA-0002 (nothing is fatal). Warning codes are now described as reserved and not currently emitted, and the controls-applied counts as always 0 at launch. Also corrects the v0.7-to-v0.8 guide: breaksApplied is always 0 until pause controls ship, and the builder example no longer shows an impossible non-zero value. These docstrings are a bridge, not a patch to preserve — once #1090 is on main a regen reproduces them from the spec and should overwrite freely, so no .fernignore entries were added. Do not regen before #1090 lands or the old wording returns.
SPEED_OUT_OF_RANGE and SPEED_INCREMENT_INVALID are members of SpeakV2ConfigureFailureCode, a WebSocket ConfigureFailure message. The REST batch path returns err_code "Bad Request" instead, so naming them on SpeakV2Request was wrong on that path. The spec agrees: parameters.speak.v2.yml (deepgram-docs#1090 @ 4170ce53) describes the REST speed query param without error codes, while the asyncapi SpeakV2Speed schema carries them. Description now matches the REST spec text verbatim. README.md:340 already attributes the codes to the WebSocket and is left alone.
dg-coreylweathers
left a comment
There was a problem hiding this comment.
Content approved — hold merge until the spec branch lands.
Re-reviewed at cc219b9. The two items actioned this round are correct, and I verified both are verbatim the branch-tip spec text rather than paraphrases:
- B8 — speed error codes now scoped to the WebSocket path; the REST javadoc matches the tip's openapi wording exactly, across all four occurrences.
- B5 premise — spot-checked every hand-applied javadoc string against
deepgram-docs@4170ce5: 9 of 11 prose blocks are verbatim matches.SpeakV2Warningwas synced to the branch tip, not to #1094. Freeze question settled on that basis.
f354ef6 went further than asked, propagating the "not applied at launch / always 0" reality into seven generated types including the reserved-warning-codes paragraph. That's the honest launch surface and the strongest work in this pass.
Build gate: compileJava compileExamples unitTest spotlessCheck BUILD SUCCESSFUL locally in Docker.
Before merge (not blocking this approval):
- Blocked-on line needs both gates.
deepgram-docs#1090and#1096— the latter carries the agent speak-provider copy and the full 39-voice enum, perca6c569. - Paste the drift note into this body under
## Known follow-up. It is currently in none of the three SDK PR bodies, and it is the entire basis of the document-the-drift approach. Per-repo cost, verified against each recordedsdkVersion: java0.9.0absorbs it; python needs8.0.0, js needs6.0.0. - Revert
b647486.ca6c569deliberately revertedspeak-providers/deepgram.ymltomain, so the tip still marks Flux TTS "Early Access" in four places. As it stands the SDK javadoc asserts GA against its own spec, and the next regen silently reverts the edit anyway. - Expressivity needs the spec's Beta sentence on
SpeakV2Request(:146,:322,:484,:494) — hallucination risk and theEXPRESSIVITY_*400 codes, both confirmed against the live API. - 0.8.0 changelog still needs a hand-edit at release time:
5b6323ais in release-please's range sincev0.7.1, so the generated notes will re-list the reverted #89 features.
Full detail in the review notes.
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.jsonoriginGitCommit03f0677lives only onorigin/jherlihy/flux-tts-ga, not ondeepgram-docsmain. The launch surface here (breaks_applied,ConfigureFailure,expressivity,speed,redact) exists only on that branch. Kept as a draft until it lands.deepgram-docs#1094(Flux TTS copy) + thejherlihy/flux-tts-gaspec branch merging todeepgram-docsmain.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.AgentV1UpdateListenListen.providerretypedDeepgramListenProviderV2→AgentV1UpdateListenListenProvider(V1/V2 union). Wrap withAgentV1UpdateListenListenProvider.v2(...); read viagetV2().Google.versionretypedOptional<String>→Optional<GoogleThinkProviderVersion>. Use the enum constants (V1BETA,AI_STUDIO_V1BETA,GEMINI_ENTERPRISE_AGENT_V1).SpeakV2SpeechMetadataControlsAppliedgains a requiredbreaksAppliedfield (new builder step; newgetBreaksApplied()). 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
.bakpatches against the freshly generated originals — all 17 still needed, none dropped..fernignorerestored to its pre-prep state; all.bakfiles deleted.hashCode()types,ReconnectingWebSocketListener(override hook /connectionTimeoutMs/maxRetries(0)semantics), and thelisten/v1+speak/v1websocket clients (query-param repeats +additionalProperties).listen/v2+speak/v2websocket clients): re-appliedQueryStringMapperarray-param serialization, theadditionalPropertiesescape hatch, and the forward-compat unknown-message no-op, while keeping the generator's new features (speak/v2sendInterrupt/sendConfigure+onSpeechInterrupted/onConfigureSuccess/onConfigureFailure; listen/v2redact).ClientOptions: kept the new retry-tuning options +ResponseDecompressionInterceptor; re-applied only the two// x-release-please-versionheader lines (colon SDK-name form), removed the generator'sgetSdkVersion()helper (build does not stamp the JAR manifest, so it would drift).Additive highlights
Speak V2 interrupt/configure, Listen V2
redact, Speak V2speed/expressivity, new Deepgram Flux TTS voices, client retry tuning, automatic response decompression.Tests added
ListenV2ConnectWireTest: newredactconnect param (present as wirenumbers, omitted when absent).RegenTypesTest→ "2026-08-11 regen type shapes": the three breaking shapes (provider union v2 factory/getV2/serialization,Google.versionenum wire value,ListenV2Redactwire 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)manageexamples: 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)
defaultImpl = V2ValueonAgentV1UpdateListenListenProvider,AgentV1SettingsAgentListenProvider,AgentV1SettingsAgentContextListenProvider, so a provider payload omitting the optionalversiondiscriminator (what 0.7.x emits) deserializes as V2 instead of dropping to{"provider":null}. Frozen in.fernignore+AGENTS.md, guarded by the re-addedAgentSettingsProviderDefaultTest. ThegetProvider()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:
ResponseDecompressionInterceptor): gzip/deflate-encoded HTTP responses are transparently decoded. No API change; transparent to callers.ClientOptions.Builder:initialRetryDelayMillis,maxRetryDelayMillis,retryJitterFactor. All defaulted — existing behavior is unchanged unless set.Follow-ups
feat!).5b6323a(feat(regen): add diarize_info, Flux force-end-turn, update-listen, word speaker confidence #89feat(regen)) is still in release-please's range sincev0.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 feat(regen): add diarize_info, Flux force-end-turn, update-listen, word speaker confidence #89 features (diarize_info, force-end-turn) under Features. Hand-edit the release PR'sCHANGELOG.mdto drop them before merging it.BREAKING CHANGE:
AgentV1UpdateListenListen.provideris nowAgentV1UpdateListenListenProvider(V1/V2 union);Google.versionis nowOptional<GoogleThinkProviderVersion>;SpeakV2SpeechMetadataControlsAppliedhas a new requiredbreaksAppliedfield. See docs/Migrating-v0.7-to-v0.8.md.