|
| 1 | +# Agents |
| 2 | + |
| 3 | +## Fern SDK Regeneration |
| 4 | + |
| 5 | +### Overview |
| 6 | + |
| 7 | +This SDK is generated by [Fern](https://buildwithfern.com/). Most files under `src/deepgram/` are auto-generated and should not be edited directly. Some files have manual patches and are listed in `.fernignore` to prevent the generator from overwriting them. |
| 8 | + |
| 9 | +When a new Fern generator release is available, we prepare the repo so the generator can overwrite previously-frozen files, then re-apply manual patches after reviewing the diff. |
| 10 | + |
| 11 | +### Freeze classification rules |
| 12 | + |
| 13 | +Every entry in `.fernignore` falls into one of two categories. The **comment above each entry** in `.fernignore` indicates which category it belongs to, but when in doubt, apply these rules: |
| 14 | + |
| 15 | +#### Never unfreeze (permanently frozen) |
| 16 | + |
| 17 | +These files are **entirely hand-written** — they have no Fern-generated counterpart. The generator would delete or replace them with something unrelated. They must stay in `.fernignore` at all times. |
| 18 | + |
| 19 | +How to identify: |
| 20 | +- The file was **created by us**, not by Fern (e.g., `src/deepgram/client.py`, custom tests, helpers, transport layer) |
| 21 | +- The file is a **doc, config, or folder** we maintain independently (README, CHANGELOG, .github, examples, etc.) |
| 22 | +- The file lives **outside `src/deepgram/`** in a hand-maintained location (e.g., `.claude/`, `docs/`) |
| 23 | + |
| 24 | +Current permanently frozen files: |
| 25 | +- `src/deepgram/client.py` — entirely custom (Bearer auth, session ID); no Fern equivalent |
| 26 | +- `src/deepgram/helpers/` — hand-written TextBuilder helpers |
| 27 | +- `src/deepgram/transport_interface.py`, `src/deepgram/transport.py`, `src/deepgram/transports/` — custom transport layer |
| 28 | +- `tests/custom/test_text_builder.py`, `tests/custom/test_transport.py` — hand-written tests |
| 29 | +- `tests/manual/` — manual standalone tests |
| 30 | +- `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md`, `reference.md` — docs |
| 31 | +- `CLAUDE.md`, `AGENTS.md`, `.claude/` — agent files |
| 32 | +- `.github/`, `docs/`, `examples/` — folders |
| 33 | + |
| 34 | +#### Unfreeze for regen (temporarily frozen) |
| 35 | + |
| 36 | +These files are **Fern-generated but carry manual patches** to fix issues in the generator output. We freeze them to protect our patches between regenerations, but unfreeze them before a regen so we can compare the new output against our patches. |
| 37 | + |
| 38 | +How to identify: |
| 39 | +- The file **exists in Fern's output** — if you removed it from `.fernignore` and ran the generator, Fern would produce a version of it |
| 40 | +- Our version is a **modified copy** of what Fern generates (e.g., changed `float` to `int`, added optional defaults, broadened a Union type) |
| 41 | + |
| 42 | +Current temporarily frozen files: |
| 43 | +- `src/deepgram/speak/v1/socket_client.py` — optional message param defaults, broad exception catch |
| 44 | +- `src/deepgram/listen/v1/socket_client.py` — same + `construct_type` for unknown WS messages |
| 45 | +- `src/deepgram/listen/v2/socket_client.py` — same |
| 46 | +- `src/deepgram/agent/v1/socket_client.py` — same + `_sanitize_numeric_types` |
| 47 | +- `src/deepgram/types/listen_v1response_results_utterances_item.py` — `float` → `int` fix |
| 48 | +- `src/deepgram/types/listen_v1response_results_utterances_item_words_item.py` — `float` → `int` fix |
| 49 | +- `src/deepgram/types/listen_v1response_results_channels_item_alternatives_item_paragraphs_paragraphs_item.py` — `float` → `int` fix |
| 50 | +- `src/deepgram/types/listen_v1redact.py` — Union[str, Sequence[str]] support |
| 51 | +- `src/deepgram/listen/v1/client.py` — Union[str, Sequence[str]] array param support |
| 52 | +- `src/deepgram/listen/v2/client.py` — same |
| 53 | +- `tests/wire/test_listen_v1_media.py` — `transcribe_file()` bytes param fix |
| 54 | +- `wiremock/wiremock-mappings.json` — removed duplicate stub |
| 55 | + |
| 56 | +### Prepare repo for regeneration |
| 57 | + |
| 58 | +1. **Create a new branch** off `main` named `lo/sdk-gen-<YYYY-MM-DD>`. |
| 59 | +2. **Push the branch** and create a PR titled `chore: SDK regeneration <YYYY-MM-DD>` (empty commit if needed). |
| 60 | +3. **Read `.fernignore`** and classify each entry using the rules above. |
| 61 | +4. **For each temporarily frozen file only:** |
| 62 | + - Copy the file to `<filename>.bak` alongside the original. |
| 63 | + - In `.fernignore`, **replace the original path with the `.bak` path**. This protects our patched version from the generator while allowing Fern to overwrite the original. |
| 64 | +5. **Never touch permanently frozen entries.** Leave them in `.fernignore` as-is. |
| 65 | +6. **Commit** as `chore: unfreeze files pending regen` and push. |
| 66 | +7. The branch is now ready for the Fern generator to push changes. |
| 67 | + |
| 68 | +### After regeneration |
| 69 | + |
| 70 | +The `.bak` files are our manually-patched versions (protected by `.fernignore`). The original paths now contain the freshly generated versions. By comparing the two, we can see what the generator now produces vs what we had patched. |
| 71 | + |
| 72 | +1. **Diff each `.bak` file against the new generated version** to understand what changed and whether our patches are still needed. |
| 73 | +2. **Re-apply any patches** that are still necessary to the newly generated files. |
| 74 | +3. **In `.fernignore`, replace each `.bak` path back to the original path** for any files that still need manual patches. |
| 75 | +4. **Remove `.fernignore` entries entirely** for any files where the generator now produces correct output (patches no longer needed). |
| 76 | +5. **Delete all `.bak` files** once review is complete. |
| 77 | +6. **Run tests** (`pytest`) and linting (`ruff check`, `mypy`) to verify. |
| 78 | +7. **Commit** as `chore: re-apply manual patches after regen` and push. |
0 commit comments