Skip to content
Merged
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
7 changes: 4 additions & 3 deletions .fern/metadata.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"cliVersion": "5.44.6",
"generatorName": "fernapi/fern-python-sdk",
"generatorVersion": "5.14.18",
"generatorVersion": "5.23.0",
"generatorConfig": {
"client": {
"class_name": "BaseClient",
Expand All @@ -12,12 +12,13 @@
"use_typeddict_requests": true,
"should_generate_websocket_clients": true,
"enable_wire_tests": true,
"runtime_version": true,
"pydantic_config": {
"skip_validation": true
}
},
"originGitCommit": "ff8fd2b74fdd5c081e9f111d59d3619f7e286dd8",
"originGitCommit": "03f06776bbb692c49f8d76c4230bca7f4bc4bca7",
"originGitCommitIsDirty": true,
"invokedBy": "manual",
"sdkVersion": "7.6.0"
"sdkVersion": "7.6.1"
}
49 changes: 31 additions & 18 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,15 @@ src/deepgram/types/deepgram_listen_provider_v2.py
src/deepgram/agent/v1/types/agent_v1settings_agent_listen_provider.py
src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider.py

# Backward-compat patch for the 2026-07-31 AgentV1UpdateListen provider retype. The
# generated `provider` field is now the required discriminated union
# AgentV1UpdateListenListenProvider (_V1/_V2, discriminant `version`). This generated
# model carries a hand-added model_validator(mode='before') / root_validator(pre=True)
# that coerces a legacy DeepgramListenProviderV1/V2 (or a dict lacking the version
# discriminant) into the new shape so existing callers keep working. Remove and unfreeze
# when the old provider payloads are retired in a future major.
src/deepgram/agent/v1/types/agent_v1update_listen_listen.py

# Hand-written compat shim recreating ListenV2CloseStreamType, which Fern removed in the
# 2026-06-15 regen (docs #946). The original generated type wrongly allowed
# Union[Literal["Finalize","CloseStream","KeepAlive"], Any] — v2 copied v1's control-message
Expand All @@ -101,16 +110,6 @@ src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider.py
# resurrecting the invalid values. Frozen so Fern won't delete it again.
src/deepgram/listen/v2/types/listen_v2close_stream_type.py

# Backward-compat shim for the `stt_latency` removal from AgentV1LatencyReport (the
# 2026-07-20 regen; API change in deepgram-docs #1006). LatencyReport is a
# server-emitted (read-only) message, so re-adding the optional `stt_latency` field
# has no request/wire impact — it keeps `report.stt_latency` resolving (to None, since
# the server no longer emits it) instead of raising AttributeError, so the removal
# stays a minor release rather than a major break. Remove the field and unfreeze when
# it is intentionally retired in a future major release.
src/deepgram/agent/v1/types/agent_v1latency_report.py
src/deepgram/agent/v1/requests/agent_v1latency_report.py

# Package __init__.py files that carry hand-applied legacy alias re-exports for the
# above shims. Fern would otherwise regenerate these and strip the legacy entries on
# every regen. Frozen to preserve the public-import surface for renamed types/params.
Expand All @@ -132,17 +131,23 @@ src/deepgram/listen/v2/types/__init__.py
# Deepgram's websocket query strings. HTTP raw_clients hand params to httpx
# directly and are unaffected; httpx accepts the pre-stringified values fine.
# [temporarily frozen — manual patches listed above]
src/deepgram/core/query_encoder.py
# Credential redaction in the error types. Every websocket `connect()` path raises
# ApiError(headers=dict(headers), ...) with the FULL request headers, and both error
# types stringify their headers dict -- so an unredacted `Authorization` reached
# str(e), tracebacks, log aggregators and error trackers (which serialise attributes
# as well as the message). Both now mask credential values at construction via
# _secure_logging.redact_sensitive_headers, keeping non-sensitive headers
# (dg-request-id) for debugging. Same threat _secure_logging.py already covers for
# the websockets DEBUG handshake logs; this is the other path to it. Unfreeze if the
# generator starts redacting credentials itself.

src/deepgram/core/api_error.py
src/deepgram/core/parse_error.py

# Carries `# x-release-please-version` annotations on the User-Agent and
# X-Fern-SDK-Version header lines so release-please bumps the wire telemetry
# version in lockstep with the published package version (it is a `generic`
# extra-file in .github/release-please-config.json). Fern regenerates this file
# from scratch and would strip the annotations, so it is frozen to protect them.
# [temporarily frozen — manual patches listed above]
src/deepgram/core/client_wrapper.py
src/deepgram/core/query_encoder.py

# Hand-written custom tests
tests/custom/test_api_error_redaction.py
tests/custom/test_agent_history.py
tests/custom/test_agent_update_listen.py
tests/custom/test_compat_aliases.py
Expand All @@ -156,6 +161,7 @@ tests/custom/test_query_encoder.py
tests/custom/test_secure_logging.py
tests/custom/test_socket_client_shims.py
tests/custom/test_speak_v2_connect_wire.py
tests/custom/test_speak_v2_interrupt_configure.py
tests/custom/test_speak_v2_socket.py
tests/custom/test_text_builder.py
tests/custom/test_transport.py
Expand All @@ -164,6 +170,13 @@ tests/typecheck/compat_aliases.py
# Wire test with restored compatibility coverage for legacy create-key request alias
tests/wire/test_manage_v1_projects_keys.py

# Wire test with restored query-parameter coverage for manage.v1.projects.requests.list.
# The 2026-08-11 regen simplified the upstream spec *example* for this endpoint, and Fern
# derives the wire test from the example, so the generated test dropped all ten optional
# query params (including the datetime -> ISO-8601 Z encoding) while the client signature
# still forwards them. Frozen so future regens do not silently drop that check again.
tests/wire/test_manage_v1_projects_requests.py

# Manual standalone tests
tests/manual

Expand Down
4 changes: 0 additions & 4 deletions .github/release-please-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
"path": "pyproject.toml",
"jsonpath": "$.tool.poetry.version"
},
{
"type": "generic",
"path": "src/deepgram/core/client_wrapper.py"
},
{
"type": "json",
"path": ".fern/metadata.json",
Expand Down
17 changes: 14 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Current permanently frozen files:
- `tests/custom/test_compat_aliases.py` — hand-written regression test for backward-compatible alias imports after regen renames
- `tests/custom/test_query_encoder.py` — hand-written regression test that `core/query_encoder.py` coerces Python bools to lowercase `"true"`/`"false"` before `urlencode` so websocket query strings stay wire-correct
- `tests/custom/test_secure_logging.py` — hand-written regression test that the `websockets` Authorization-header DEBUG logs are redacted (API key never logged in clear text)
- `tests/custom/test_speak_v2_interrupt_configure.py` — hand-written coverage for the Speak V2 barge-in / mid-stream reconfigure surface (`send_interrupt`, `send_configure`, `SpeechInterrupted`, `ConfigureSuccess`/`ConfigureFailure`, and the `speed`/`expressivity` connect params)
- `tests/custom/test_text_builder.py`, `tests/custom/test_transport.py` — hand-written tests
- `tests/typecheck/compat_aliases.py` — hand-written mypy `assert_type` coverage for backward-compatible alias TypedDicts
- `tests/manual/` — manual standalone tests
Expand All @@ -53,17 +54,27 @@ How to identify:

Current temporarily frozen files:
- `src/deepgram/speak/v1/socket_client.py` — optional message param defaults, broad exception catch
- `src/deepgram/speak/v2/socket_client.py` — same (optional `send_flush`/`send_close` defaults, broad exception catch); new websocket TTS client added in the 2026-07-08 regen
- `src/deepgram/speak/v2/socket_client.py` — same (optional `send_flush`/`send_close`/`send_interrupt` defaults, broad exception catch); new websocket TTS client added in the 2026-07-08 regen. `send_interrupt` carries no required payload so it takes the same optional-default treatment as the other control sends; `send_configure` deliberately keeps its required argument (a Configure with no settings is meaningless)
- `src/deepgram/listen/v1/socket_client.py` — same
- `src/deepgram/listen/v2/socket_client.py` — same + `send_configure` typing.Any/raw shim, response Union uses typing.Any instead of `ListenV2ConfigureSuccess`
- `src/deepgram/listen/v2/socket_client.py` — same (broad except, optional `send_close_stream` default). As of the 2026-08-11 regen the generator properly types `send_configure(ListenV2Configure)` and puts `ListenV2ConfigureSuccess` in the response Union, so those are taken from the generator; the only `send_configure` patch retained is runtime tolerance for a raw dict (sent verbatim) for back-compat with pre-typed-model callers
- `src/deepgram/agent/v1/socket_client.py` — same + `_sanitize_numeric_types`
- `src/deepgram/agent/v1/types/agent_v1settings_agent_context.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent.py`, `src/deepgram/agent/v1/types/agent_v1settings.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent.py`, `src/deepgram/agent/v1/requests/agent_v1settings.py` — backward-compat patches for the 2026-05-05 Agent Settings schema restructure. These preserve callable `AgentV1SettingsAgent(...)`, keep `AgentV1Settings.agent` accepting both that wrapper and `agent_id` strings, restore the legacy request TypedDict shapes, remap legacy `messages=[...]` / nested `context=AgentV1SettingsAgentContext(messages=[...])` usage into the new `context={"messages": [...]}` wire shape, and keep read-side `obj.messages` access working.
- `src/deepgram/core/api_error.py`, `src/deepgram/core/parse_error.py` — credential redaction. Every websocket `connect()` path raises `ApiError(headers=dict(headers), ...)` with the full request headers, and both error types stringify that dict, so an unredacted `Authorization` reached `str(e)`, tracebacks, log aggregators and error trackers (which serialise attributes as well as the message). Both now mask credential values at construction via `_secure_logging.redact_sensitive_headers`, preserving non-sensitive headers (`dg-request-id`) for debugging. This is the same threat `_secure_logging.py` covers for the `websockets` DEBUG handshake logs, via the other path to it. Regression coverage in `tests/custom/test_api_error_redaction.py`. Unfreeze if the generator starts redacting credentials itself.
- `src/deepgram/core/query_encoder.py` — coerces Python bools to lowercase `"true"`/`"false"` before they reach `urllib.parse.urlencode` (which would otherwise produce `"True"`/`"False"` via `str()` and break websocket query strings). Only the four `*/connect()` paths call `urlencode`; HTTP raw clients hand params to httpx, which lowercases bools itself, so the patch is a no-op for the HTTP path. Once Fern's websocket codegen normalizes bools (or the spec types these as `boolean` end-to-end), this can be unfrozen.
- `src/deepgram/core/client_wrapper.py` — carries `# x-release-please-version` annotations on the `User-Agent` and `X-Fern-SDK-Version` header lines. `client_wrapper.py` is listed as a `generic` extra-file in `.github/release-please-config.json`, but the generic updater only rewrites annotated lines, so without these comments release-please never bumps the wire telemetry version and it drifts from the published package version (e.g. main shipping 7.4.0 while sending 7.3.2). Fern regenerates this file from scratch and would strip the annotations, so it is frozen to protect them. On regen, re-apply the two annotation comments to the freshly generated header lines. Unfreeze only if Fern's generator starts emitting the annotations itself.
- `src/deepgram/types/deepgram_listen_provider_v2.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_listen_provider.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider.py` — behavioural back-compat shim for the `language_hint` -> `language_hints` rename (2026-06-15 regen). The public field was historically (incorrectly) singular and accepted a str or a list; the API field is `language_hints` (a list, and the server uses `deny_unknown_fields` so the singular key is rejected on the wire). Each carries a hand-added `model_validator(mode='before')` / `root_validator(pre=True)` that remaps a legacy `language_hint=` kwarg and drops the dead singular key. Remove and unfreeze when the singular alias is retired in a future major.
- `src/deepgram/agent/v1/types/agent_v1update_listen_listen.py` — backward-compat patch for the 2026-07-31 `AgentV1UpdateListen` provider retype. The `provider` field changed from a bare `DeepgramListenProviderV2` to the required discriminated union `AgentV1UpdateListenListenProvider` (`_V1`/`_V2`, discriminant `version`). Carries a hand-added `model_validator(mode='before')` / `root_validator(pre=True)` that coerces a legacy `DeepgramListenProviderV1`/`V2` (or a dict lacking the `version` discriminant) into the new shape so existing callers keep working. Remove and unfreeze when the old provider payloads are retired in a future major. NOTE: this patch was silently lost once (it was absent from `.fernignore`, so a regen overwrote it) — keep it frozen.
- `tests/wire/test_manage_v1_projects_keys.py` — restored wire coverage for the legacy `CreateKeyV1RequestOneParams` request alias so future regens do not silently drop that compatibility check
- `tests/wire/test_manage_v1_projects_requests.py` — restored query-parameter coverage for `manage.v1.projects.requests.list`. The 2026-08-11 regen simplified the upstream spec *example*, and Fern derives the wire test from the example, so all ten optional query params (and the `datetime` → ISO-8601 `Z` encoding) lost their assertions while the client signature still forwarded them. Frozen for the same reason as the `_keys.py` entry above.
- `src/deepgram/__init__.py`, `src/deepgram/agent/__init__.py`, `src/deepgram/agent/v1/__init__.py`, `src/deepgram/agent/v1/types/__init__.py`, `src/deepgram/agent/v1/requests/__init__.py`, `src/deepgram/types/__init__.py`, `src/deepgram/requests/__init__.py` — package `__init__.py` files carrying hand-applied legacy alias re-exports for `CreateKeyV1RequestOne`, `AgentV1HistoryContent`, `AgentV1HistoryFunctionCalls`, `AgentV1SettingsAgentContextMessagesItemContent`, `AgentV1SettingsAgentContextMessagesItemFunctionCalls` (and their `*Params` variants). Fern would otherwise regenerate these and strip the legacy entries. After unfreezing for the next regen and reviewing the new generated content, re-apply the legacy re-exports plus any genuine new entries Fern added.
- `src/deepgram/listen/__init__.py`, `src/deepgram/listen/v2/__init__.py`, `src/deepgram/listen/v2/types/__init__.py` — `__init__.py` files re-exporting the hand-written `ListenV2CloseStreamType` shim. Frozen so Fern won't strip the re-export on regen. Same handling as the package `__init__.py` files above: after unfreezing, re-apply the `ListenV2CloseStreamType` re-export plus any genuine new entries Fern added.

### Unfrozen files with residual manual concerns

Files Fern now owns outright, but that carry a caveat worth knowing before the next regen:

- `src/deepgram/core/client_wrapper.py` — unfrozen in the 2026-08-11 regen. The generator's `runtime_version: true` mode now derives the wire version from `importlib.metadata.version("deepgram-sdk")`, which supersedes the old hand-applied `# x-release-please-version` annotations (its `generic` entry was removed from `.github/release-please-config.json` at the same time, since with the annotations gone it was a no-op). **Caveat:** the `except PackageNotFoundError` fallback is a hardcoded version literal that nothing bumps — release-please's `extra-files` now covers only `pyproject.toml` and `.fern/metadata.json`. It only applies where package metadata is undiscoverable (source checkout on `sys.path`, vendored copy, zipapp, some frozen bundles), and it is refreshed only by the next regen. Accepted deliberately rather than re-freezing the file; if that fallback ever needs to be accurate on those paths, re-add a release-please `generic` entry with an annotation on the fallback line.
- `src/deepgram/agent/v1/types/agent_v1latency_report.py` and its `requests/` twin — unfrozen in the 2026-08-11 regen because the spec restored `stt_latency` natively, making the hand-added read-side field redundant. `tests/custom/test_latency_report_stt_compat.py` stays frozen and still guards the field's presence, so a future spec removal is caught rather than silently re-breaking readers.

### Prepare repo for regeneration

1. **Create a new branch** off `main` named `lo/sdk-gen-<YYYY-MM-DD>`.
Expand Down
Loading
Loading