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
10 changes: 7 additions & 3 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-python-sdk",
"generatorVersion": "5.23.0",
"generatorVersion": "5.27.1",
"generatorConfig": {
"client": {
"class_name": "BaseClient",
Expand All @@ -13,11 +13,15 @@
"should_generate_websocket_clients": true,
"enable_wire_tests": true,
"runtime_version": true,
"extra_dev_dependencies": {
"pytest-cov": "^7.0.0",
"respx": ">=0.22.0,<1.0.0"
},
"pydantic_config": {
"skip_validation": true
}
},
"originGitCommit": "03f06776bbb692c49f8d76c4230bca7f4bc4bca7",
"originGitCommit": "068de888501fcc3b792086aab45de975587b89e1",
"originGitCommitIsDirty": true,
"invokedBy": "manual",
"sdkVersion": "7.7.1"
Expand Down
44 changes: 44 additions & 0 deletions .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,31 @@ src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_func
src/deepgram/types/create_key_v1request_one.py
src/deepgram/requests/create_key_v1request_one.py

# Backward-compatibility alias shims for the 2026-08-18 regen renames. The generator
# dropped the *ThinkProvider*/*SpeakProvider* prefixes from these public model/voice/
# version types (AnthropicThinkProviderModel -> AnthropicModel, CartesiaSpeakProvider* ->
# Cartesia*, DeepgramSpeakProviderModel -> DeepgramModel, GoogleThinkProvider* -> Google*,
# GroqThinkProviderReasoningMode -> GroqReasoningMode). Same regen renamed the agent
# conversation-history subtypes (AgentV1HistoryContentRole -> ConversationHistoryMessageRole,
# AgentV1HistoryFunctionCallsFunctionCallsItem -> FunctionCallHistoryMessageFunctionCallsItem)
# and deleted the doubled AgentV1SettingsAgentContextContextMessagesItem* leaf modules. These
# hand-written aliases preserve every old public import path. Regression coverage in
# tests/custom/test_compat_aliases.py. Remove and unfreeze when a future major retires them.
src/deepgram/types/anthropic_think_provider_model.py
src/deepgram/types/cartesia_speak_provider_model_id.py
src/deepgram/types/cartesia_speak_provider_voice.py
src/deepgram/types/deepgram_speak_provider_model.py
src/deepgram/types/google_think_provider_model.py
src/deepgram/types/google_think_provider_version.py
src/deepgram/types/groq_think_provider_reasoning_mode.py
src/deepgram/requests/cartesia_speak_provider_voice.py
src/deepgram/agent/v1/types/agent_v1history_content_role.py
src/deepgram/agent/v1/types/agent_v1history_function_calls_function_calls_item.py
src/deepgram/agent/v1/types/agent_v1settings_agent_context_context_messages_item_content_role.py
src/deepgram/agent/v1/types/agent_v1settings_agent_context_context_messages_item_function_calls_function_calls_item.py
src/deepgram/agent/v1/requests/agent_v1history_function_calls_function_calls_item.py
src/deepgram/agent/v1/requests/agent_v1settings_agent_context_context_messages_item_function_calls_function_calls_item.py

# Backward-compatibility alias shims for the 2026-05-14 listen-provider rename.
# The spec deduplicated AgentV1SettingsAgent[Context]ListenProviderV1/V2/V2LanguageHint
# into a single top-level DeepgramListenProvider* type. These hand-written aliases
Expand Down Expand Up @@ -107,6 +132,15 @@ src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider.py
# when the old provider payloads are retired in a future major.
src/deepgram/agent/v1/types/agent_v1update_listen_listen.py

# Backward-compat patch for the 2026-08-18 regen SpeakV2Speed retype. The generator
# changed this from `float` to `Union[Literal["0.85"..."1.15"], Any]` -- a string-literal
# enum that contradicts the API contract (a numeric multiplier; cf. SpeakV2SpeedValue =
# float, used by the Configure message) and silently changed the documented domain of the
# `speak.v2.connect(speed=...)` param from numeric to string. Restored to `float` so the
# connect param stays exactly what it was on main and consistent with Configure. Unfreeze
# when the spec types the connect `speed` as a number.
src/deepgram/types/speak_v2speed.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 Down Expand Up @@ -184,6 +218,7 @@ tests/custom/test_listen_v2_regen_constraints.py
tests/custom/test_logging_and_retry_branches.py
tests/custom/test_model_dict_compat.py
tests/custom/test_query_encoder.py
tests/custom/test_regen_response_fields.py
tests/custom/test_secure_logging.py
tests/custom/test_socket_client_shims.py
tests/custom/test_speak_v2_connect_wire.py
Expand All @@ -205,6 +240,15 @@ tests/wire/test_manage_v1_projects_keys.py
# still forwards them. Frozen so future regens do not silently drop that check again.
tests/wire/test_manage_v1_projects_requests.py

# Wire test with restored query-parameter coverage for listen.v1.media.transcribe_url.
# Third instance of the same mechanism as the two entries above: the 2026-08-18 regen
# simplified the upstream /v1/listen spec *example* (mapping renamed "default" ->
# "Remote File"), and Fern derives the wire test from the example, so the generated test
# dropped all 37 optional query params -- including the bool -> lowercase "true"/"false"
# assertions -- while the client signature still forwards every one of them. Frozen so
# future regens cannot silently drop that check again.
tests/wire/test_listen_v1_media.py

# Manual standalone tests
tests/manual

Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Current permanently frozen files:
- `src/deepgram/agent/v1/types/agent_v1history_content.py`, `src/deepgram/agent/v1/types/agent_v1history_function_calls.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_content_role.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_messages_item_function_calls_function_calls_item.py` — hand-written compatibility aliases preserving old public Agent History type imports after regen renames
- `src/deepgram/agent/v1/requests/agent_v1history_content.py`, `src/deepgram/agent/v1/requests/agent_v1history_function_calls.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_content.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_messages_item_function_calls_function_calls_item.py` — hand-written compatibility aliases preserving old public Agent History request-param imports after regen renames
- `src/deepgram/types/create_key_v1request_one.py`, `src/deepgram/requests/create_key_v1request_one.py` — hand-written compatibility aliases preserving the old public create-key request imports after the regen rename to `CreateKeyV1Request`
- `src/deepgram/types/anthropic_think_provider_model.py`, `src/deepgram/types/cartesia_speak_provider_model_id.py`, `src/deepgram/types/cartesia_speak_provider_voice.py`, `src/deepgram/types/deepgram_speak_provider_model.py`, `src/deepgram/types/google_think_provider_model.py`, `src/deepgram/types/google_think_provider_version.py`, `src/deepgram/types/groq_think_provider_reasoning_mode.py`, `src/deepgram/requests/cartesia_speak_provider_voice.py`, `src/deepgram/agent/v1/types/agent_v1history_content_role.py`, `src/deepgram/agent/v1/types/agent_v1history_function_calls_function_calls_item.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_context_messages_item_content_role.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_context_messages_item_function_calls_function_calls_item.py`, `src/deepgram/agent/v1/requests/agent_v1history_function_calls_function_calls_item.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_context_messages_item_function_calls_function_calls_item.py` — hand-written compatibility aliases for the 2026-08-18 regen renames. The generator dropped the `*ThinkProvider*`/`*SpeakProvider*` prefixes from the public model/voice/version types (`AnthropicThinkProviderModel`→`AnthropicModel`, `CartesiaSpeakProvider*`→`Cartesia*`, `DeepgramSpeakProviderModel`→`DeepgramModel`, `GoogleThinkProvider*`→`Google*`, `GroqThinkProviderReasoningMode`→`GroqReasoningMode`), renamed the agent conversation-history subtypes (`AgentV1HistoryContentRole`→`ConversationHistoryMessageRole`, `AgentV1HistoryFunctionCallsFunctionCallsItem`→`FunctionCallHistoryMessageFunctionCallsItem`), and deleted the doubled `AgentV1SettingsAgentContextContextMessagesItem*` leaf modules. These aliases preserve every old public import path. (The parallel single-`Context` `agent_v1settings_agent_context_messages_item_content_role.py` / `..._function_calls_function_calls_item.py` shims, already listed in this permanently-frozen block above, were also re-pointed to the new targets in the same regen.) Regression coverage in `tests/custom/test_compat_aliases.py`.
- `src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider_v1.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider_v2.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_context_listen_provider_v2language_hint.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_listen_provider_v1.py`, `src/deepgram/agent/v1/types/agent_v1settings_agent_listen_provider_v2.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_listen_provider_v1.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_listen_provider_v2.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_context_listen_provider_v2language_hint.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_listen_provider_v1.py`, `src/deepgram/agent/v1/requests/agent_v1settings_agent_listen_provider_v2.py` — hand-written compatibility aliases for the 2026-05-14 spec dedup that consolidated `AgentV1SettingsAgent[Context]ListenProviderV{1,2,V2LanguageHint}` into top-level `DeepgramListenProvider*` types
- `src/deepgram/types/deepgram_listen_provider_v2language_hint.py`, `src/deepgram/requests/deepgram_listen_provider_v2language_hint.py` — hand-written shims recreating the top-level `DeepgramListenProviderV2LanguageHint`/`...Params` type (`Union[str, List[str]]`) that Fern removed in the 2026-06-15 regen. The `*V2LanguageHint` listen-provider aliases above import from these and they remain part of the public import surface, so they are recreated by hand and frozen so Fern won't delete them again
- `src/deepgram/listen/v2/types/listen_v2close_stream_type.py` — hand-written 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 enum); a CloseStream message's `type` can only ever be `"CloseStream"`. Recreated as the corrected `Literal["CloseStream"]` to preserve the public import path without resurrecting the invalid values. Re-exported from the three `listen` `__init__.py` files (temporarily frozen, below).
Expand All @@ -37,6 +38,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_model_dict_compat.py` — hand-written regression coverage for the read-only subscript compatibility shim on typed Listen V2 response models, including sync/async parsing, every response variant, nested objects, unknown fields, omitted-key behavior, and scope isolation from unrelated generated models
- `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_regen_response_fields.py` — hand-written regression test guarding the response fields added by the 2026-08-18 regen: `ListenV1Response/ResultsMetadata.diarize_info` (`model_uuid`, `arch`), per-word `speaker` / `speaker_confidence`, and `ListenV2TurnInfo.trigger`. Same rationale as `test_latency_report_stt_compat.py`: `UncheckedBaseModel` + `skip_validation` makes response parsing lenient, so a future spec removal would silently turn these into `None` rather than failing. Fixtures are real captured payloads; the `trigger` cases pin the parsing contract for the values the server sends (`model` / `manual` / `timeout`) plus the absent case, which is what a deployment without the server-gated `ForceEndTurn` feature returns. Live coverage of the same field lives in `tests/manual/listen/v2/force_end_turn/`
- `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
Expand Down Expand Up @@ -67,9 +69,11 @@ Current temporarily frozen files:
- `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/listen/v2/types/listen_v2connected.py`, `src/deepgram/listen/v2/types/listen_v2turn_info.py`, `src/deepgram/listen/v2/types/listen_v2turn_info_words_item.py`, `src/deepgram/listen/v2/types/listen_v2configure_success.py`, `src/deepgram/listen/v2/types/listen_v2configure_success_thresholds.py`, `src/deepgram/listen/v2/types/listen_v2configure_failure.py`, `src/deepgram/listen/v2/types/listen_v2fatal_error.py` — read-side compatibility for the SDK 7.7 Listen V2 response retype. Through 7.6, `V2SocketClientResponse` contained `typing.Any`, so every response was returned as a raw dict; fixing the union made responses typed models and broke callers using `response["field"]`. These generated response classes inherit the hand-written base above, preserving read-only wire-key subscript access alongside canonical attribute access. Restore direct `UncheckedBaseModel` inheritance and unfreeze these files in the next major release.
- `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/types/speak_v2speed.py` — behavioural back-compat patch for the 2026-08-18 regen `SpeakV2Speed` retype. The generator changed it from `float` to `Union[Literal["0.85"…"1.15"], Any]` (a string-literal enum), which silently changed the documented domain of the `speak.v2.connect(speed=...)` parameter from numeric to string and contradicts the actual API contract (`SpeakV2SpeedValue = float`, used by the mid-stream `SpeakV2Configure` message). Only the `Any` fallback kept `speed=1.05` working. Restored to `float` so the connect param stays exactly what it was on `main`, mypy-precise, and consistent with the `Configure` message. Regression coverage in `tests/custom/test_speak_v2_coverage.py`. Unfreeze when the spec types the connect `speed` as a number.
- `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.
- `tests/wire/test_listen_v1_media.py` — restored query-parameter coverage for `listen.v1.media.transcribe_url`. **Third instance of the same mechanism as the two entries above**, this time on the SDK's highest-traffic endpoint: the 2026-08-18 regen simplified the upstream `/v1/listen` spec *example* (the wiremock mapping was renamed `"default"` → `"Remote File"`), so the generated wire test dropped all 37 optional query params — including the bool → lowercase `"true"`/`"false"` assertions — while the client signature still forwards every one of them. The generated test is left untouched; a second hand-written test with its own `test_id` carries the assertions, which is why no change to `wiremock/wiremock-mappings.json` is needed (`verify_request_count` matches WireMock's *recorded* requests via the `X-Test-Id` header, not the stub matcher). **Pattern to watch:** any regen that simplifies an upstream example silently erodes that endpoint's wire coverage; check `git diff` on `tests/wire/` every cycle.
- `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.

Expand Down
Loading
Loading