Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .fern/metadata.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"cliVersion": "5.44.6",
"cliVersion": "5.95.1",
"generatorName": "fernapi/fern-java-sdk",
"generatorVersion": "4.16.0",
"generatorVersion": "4.18.0",
"generatorConfig": {
"package-prefix": "com.deepgram",
"base-api-exception-class-name": "DeepgramHttpException",
Expand All @@ -12,8 +12,8 @@
"enable-wire-tests": true,
"runtime-version": true
},
"originGitCommit": "03f06776bbb692c49f8d76c4230bca7f4bc4bca7",
"originGitCommit": "068de888501fcc3b792086aab45de975587b89e1",
"originGitCommitIsDirty": true,
"invokedBy": "manual",
"sdkVersion": "0.8.0"
"sdkVersion": "0.8.1"
}
23 changes: 23 additions & 0 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,34 @@ src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java
src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java
src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java

# Back-compat patch for the speak v2 connect `speed` retype. Generator 4.18.0 changed this param
# from Double to the SpeakV2Speed string-literal enum — breaking for every caller that passed a
# number in 0.8.0, and a closed 7-value enum cannot express a valid in-range value it omits. The
# spec contradicts itself: the sibling mid-stream SpeakV2Configure.speed is still Double, and the
# server parses the numeric form and range-checks it (SPEED_OUT_OF_RANGE / SPEED_INCREMENT_INVALID).
# Restored to Double; guarded by SpeakV2ConnectWireTest. Unfreeze once the spec types the connect
# `speed` as a number. The generated SpeakV2Speed type is left in place, unused, as documentation
# of the accepted values.
src/main/java/com/deepgram/resources/speak/v2/websocket/V2ConnectOptions.java

# Restores the FLUX_RENEE_EN constant that generator 4.18.0 dropped. The voice is live:
# POST /v2/speak?model=flux-renee-en returns 200 with valid audio, and the name resolves in the
# server's model registry (an invented flux-* name is rejected with INVALID_QUERY_PARAMETER), so the
# removal is a spec regression, not a retirement. Dropping the constant would break 0.8.0 callers
# for no reason. Remove the patch and unfreeze once the spec lists the voice again.
#
# WARNING: unlike the other temporarily frozen files, this one receives frequent *additive* spec
# changes -- 4.18.0 alone added 25 constants. On the next regen do NOT restore the .bak wholesale:
# diff it against the newly generated file, carry forward every new voice, and re-apply only the
# FLUX_RENEE_EN touchpoints (constant, Value enum, visit() case, valueOf() case, Visitor method).
src/main/java/com/deepgram/types/DeepgramModel.java

# Manual equals/hashCode contract fix: Fern generates equals() (all instances equal) but no
# hashCode() for fields-less message types, violating the Object contract. We add a consistent
# hashCode() to each. Unfreeze and drop these patches once the generator emits a matching
# equals/hashCode pair for fields-less types (tracked as an upstream Fern request).
src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java
src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java
src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java
src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java
src/main/java/com/deepgram/resources/agent/v1/types/AgentV1ListenUpdated.java
Expand Down
19 changes: 15 additions & 4 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,13 @@ How to identify:

Current temporarily frozen files:

- `src/main/java/com/deepgram/core/ClientOptions.java` - preserves release-please version markers and correct SDK header constants that Fern currently overwrites; use the standard `.bak` swap/restore workflow during regen review
- `src/main/java/com/deepgram/core/ClientOptions.java` - preserves release-please version markers and correct SDK header constants that Fern currently overwrites; use the standard `.bak` swap/restore workflow during regen review. Since generator 4.18.0 Fern emits a `getSdkVersion()` helper reading `Package.getImplementationVersion()` instead of a literal. That *does* resolve in the published artifact (CI publishes via `mvn deploy -P release`, and `pom.xml`'s maven-jar-plugin sets `addDefaultImplementationEntries=true`, so the JAR manifest carries `Implementation-Version`), but it resolves to `null` under Gradle and in tests, where it silently falls back to a hardcoded literal the generator does not keep current. We keep the explicit literals because they are correct in every context and because `.github/release-please-config.json` already lists this file in `extra-files`, so release-please bumps it alongside `pom.xml`, `build.gradle`, and `.fern/metadata.json`. Fern also emits `User-Agent` with a `com.deepgram.` prefix while leaving `X-Fern-SDK-Name` on the `com.deepgram:` Maven-coordinate form; we keep both on the colon form.
- `src/main/java/com/deepgram/core/ReconnectingWebSocketListener.java` - carries bug fixes for `maxRetries(0)` semantics ("connect once, don't retry") and a configurable `connectionTimeoutMs` field (was hardcoded 4000ms), plus an `applyOptionsOverride(...)` hook used by `TransportWebSocketFactory` to apply per-transport reconnect policy; pull this back out once the fixes are upstreamed into the Fern generator. Use the standard `.bak` swap/restore workflow during regen review.
- `src/main/java/com/deepgram/resources/speak/v2/websocket/V2WebSocketClient.java` and `src/main/java/com/deepgram/resources/listen/v2/websocket/V2WebSocketClient.java` - forward-compat patch (both clients). Fern's generated `handleIncomingMessage` dispatcher routes any unrecognized message type to `onError` with "Update your SDK version...", which makes a benign new server control frame look fatal to a deployed client. Patched so the unrecognized-type branch is a no-op — the raw frame is already delivered via `onMessage(String)` earlier in the method, so consumers still see it. Mirrors the JS/Python SDKs' forward-compat behavior and is regression-guarded by `src/test/java/com/deepgram/SpeakV2ForwardCompatTest.java` and `src/test/java/com/deepgram/ListenV2ForwardCompatTest.java`. These two clients also carry the streaming query-param patches described in the next entry. Use the standard `.bak` swap/restore workflow during regen review; re-apply the no-op to both after regen, and unfreeze once the generator stops treating unknown frames as errors.
- `src/main/java/com/deepgram/resources/listen/v1/websocket/V1WebSocketClient.java` and `src/main/java/com/deepgram/resources/speak/v1/websocket/V1WebSocketClient.java` (and the v2 clients above) - streaming query-param patches on the generated `connect()` builders. Two fixes: (1) multi-value serialization — array-valued params (listen: `keyterm`, `keywords`, `replace`, `search`, `tag`, `extra`, `language_hint`; speak: `tag`) were serialized with `String.valueOf(union.get())`, collapsing a `List` into one param (`keyterm=[a, b]`) instead of repeats (`keyterm=a&keyterm=b`); (2) an `additionalProperties` escape hatch — the builder exposes `additionalProperty(key, value)` for unmodeled params (e.g. `no_delay`) but `connect()` never emitted them to the URL. Both patched to route through `QueryStringMapper(arraysAsRepeats=true)`, matching the REST path. Use the standard `.bak` swap/restore workflow during regen review; re-apply after regen and unfreeze once the generator emits array params as repeats and serializes `additionalProperties` on the WS `connect()` path (tracked as an upstream Fern request).
- Fields-less message types carrying a manual `hashCode()` patch (Fern generates `equals()` but no `hashCode()` for these, violating the Object contract): `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java`, and the `AgentV1*` event types `src/main/java/com/deepgram/resources/agent/v1/types/{AgentV1ListenUpdated,AgentV1SpeakUpdated,AgentV1AgentAudioDone,AgentV1SettingsApplied,AgentV1UserStartedSpeaking,AgentV1KeepAlive,AgentV1ThinkUpdated,AgentV1PromptUpdated}.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze all of them once the generator emits a matching equals/hashCode pair for fields-less types (tracked as an upstream Fern request).
- Fields-less message types carrying a manual `hashCode()` patch (Fern generates `equals()` but no `hashCode()` for these, violating the Object contract): `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2CloseStream.java`, `src/main/java/com/deepgram/resources/listen/v2/types/ListenV2ForceEndTurn.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Close.java`, `src/main/java/com/deepgram/resources/speak/v2/types/SpeakV2Flush.java`, and the `AgentV1*` event types `src/main/java/com/deepgram/resources/agent/v1/types/{AgentV1ListenUpdated,AgentV1SpeakUpdated,AgentV1AgentAudioDone,AgentV1SettingsApplied,AgentV1UserStartedSpeaking,AgentV1KeepAlive,AgentV1ThinkUpdated,AgentV1PromptUpdated}.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze all of them once the generator emits a matching equals/hashCode pair for fields-less types (tracked as an upstream Fern request).
- `src/main/java/com/deepgram/resources/speak/v2/websocket/V2ConnectOptions.java` - back-compat patch for the speak v2 connect `speed` retype. Generator 4.18.0 changed the param from `Optional<Double>` to the `SpeakV2Speed` string-literal enum, which breaks every caller that passed a number in 0.8.0 and, being a closed 7-value enum, cannot express a valid in-range value the enum omits. The spec contradicts itself here: the sibling mid-stream `SpeakV2Configure.speed` is still `Optional<Double>`, and the server parses the numeric form and range-checks it (`SPEED_OUT_OF_RANGE`, `SPEED_INCREMENT_INVALID`). Restored to `Optional<Double>`; guarded by `src/test/java/com/deepgram/SpeakV2ConnectWireTest.java`. The generated `SpeakV2Speed` type is left in place, unused, as documentation of the accepted values. Use the standard `.bak` swap/restore workflow during regen review; unfreeze once the spec types the connect `speed` as a number (tracked as an upstream Fern request).
- `src/main/java/com/deepgram/types/DeepgramModel.java` - restores the `FLUX_RENEE_EN` constant that generator 4.18.0 dropped. The voice is live: `POST /v2/speak?model=flux-renee-en` returns 200 with valid audio, and the name resolves in the server's model registry (an invented `flux-*` name is rejected with `INVALID_QUERY_PARAMETER`), so the removal is a spec regression rather than a retirement, and dropping the constant would break 0.8.0 callers for nothing. Five touchpoints: the constant, the `Value` enum entry, the `visit()` case, the `valueOf()` case, and the `Visitor` method. **This file is unlike the other temporarily frozen ones — it receives frequent additive spec changes (4.18.0 alone added 25 constants), so on the next regen do NOT restore the `.bak` wholesale.** Diff the `.bak` against the newly generated file, carry forward every new voice, and re-apply only the `FLUX_RENEE_EN` touchpoints. Drop the patch and unfreeze once the spec lists the voice again (tracked as an upstream spec request).
- Union default-variant fix on the agent listen-provider unions: `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1UpdateListenListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentListenProvider.java`, `src/main/java/com/deepgram/resources/agent/v1/types/AgentV1SettingsAgentContextListenProvider.java`. `version` is an optional discriminator, so a provider payload without it is valid (and is what 0.7.x emits), but Fern points `@JsonTypeInfo` `defaultImpl` at the empty-bodied `_UnknownValue`, so such a payload deserializes to an unknown variant carrying `null` — `getProvider()` returns `null` and re-serialization emits `{"provider":null}`, silently dropping the provider on the wire. Patched to `defaultImpl = V2Value` on each; guarded by `src/test/java/com/deepgram/AgentSettingsProviderDefaultTest.java`. Use the standard `.bak` swap/restore workflow during regen review; drop the patches and unfreeze once the generator stops defaulting unions to the empty `_UnknownValue` (tracked as an upstream Fern request).

### Prepare repo for regeneration
Expand All @@ -75,5 +77,14 @@ The `.bak` files are our manually patched versions protected by `.fernignore`. T
3. In `.fernignore`, replace each `.bak` path back to the original path for files that still need patches.
4. Remove `.fernignore` entries entirely for any files where the generator now produces correct output.
5. Delete all `.bak` files once review is complete.
6. Run checks (`./gradlew test compileExamples`) to verify. `test` covers unit/wire tests including the README snippet compilation; `compileExamples` separately compiles the hand-maintained `examples/` directory and catches stale API call sites that `test` alone would miss.
7. Commit as `chore: re-apply manual patches after regen` and push.
6. Sweep for **newly generated** files that need an existing patch class. Diffing `.bak` files only catches regressions in files we already froze — a brand-new generated type has no `.bak` and will slip through. At minimum, re-run the fields-less `hashCode()` sweep:

```sh
for f in $(grep -rl 'instanceof' src/main/java/com/deepgram --include='*.java'); do
grep -q 'public boolean equals' "$f" && ! grep -q 'public int hashCode' "$f" && echo "$f"
done
```

Ignore `core/Nullable.java` and `core/NullableNonemptyFilter.java` (Jackson utility classes, not message types). Anything else in the list needs the `hashCode()` patch, a `.fernignore` entry, an entry in the list above, and a `RegenTypesTest.FieldsLessMessageContract` assertion. `ListenV2ForceEndTurn` reached `main` unpatched this way.
7. Run checks (`./gradlew spotlessCheck test compileExamples`) to verify. `test` covers unit/wire tests including the README snippet compilation; `compileExamples` separately compiles the hand-maintained `examples/` directory and catches stale API call sites that `test` alone would miss. **`spotlessCheck` is required** — CI runs it as a separate job, so `test compileExamples` alone can pass locally while CI fails. Re-applying patches by hand almost always trips it: inserted comments and renamed types change line lengths, which changes how the formatter wraps chained calls. Run `./gradlew spotlessApply` to fix, then re-check.
8. Commit as `chore: re-apply manual patches after regen` and push.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ You can learn more about the Deepgram API at [developers.deepgram.com](https://d

### Migrating Between Versions

- [v0.7 to v0.8](./docs/Migrating-v0.7-to-v0.8.md) (current)
- [v0.8 to v0.9](./docs/Migrating-v0.8-to-v0.9.md) (current)
- [v0.7 to v0.8](./docs/Migrating-v0.7-to-v0.8.md)
- [v0.6 to v0.7](./docs/Migrating-v0.6-to-v0.7.md)
- [v0.5 to v0.6](./docs/Migrating-v0.5-to-v0.6.md)
- [v0.3 to v0.4](./docs/Migrating-v0.3-to-v0.4.md)
Expand Down
Loading
Loading