feat!: regenerate SDK for API 2026-09-13 with consent-challenge voice cloning - #16
feat!: regenerate SDK for API 2026-09-13 with consent-challenge voice cloning#16luke-speechify wants to merge 5 commits into
Conversation
|
Holding this as draft until the SSE response is modelled upstream. Live verification against production found
Also found:
All of this is in generated code, so the fixes belong in the Fern definition. The release-please wiring in this PR is verified and stays as-is. Everything else passed: 20/23 live cases, all 10 endpoints exercised, both new subpath exports resolve in ESM and CJS, |
Covers .fern/metadata.json, stamps the Fern-generated version strings from the release tag at publish time, corrects repository.url casing for npm provenance, restores AGENTS.md + manual-publish.yml, and gates publish on a version/tag assertion. src/BaseClient.ts is Fern-generated and cannot be .fernignore'd, so an x-release-please-version marker does not survive there: every regeneration strips it and the generic updater goes back to silently no-opping, leaving X-Fern-SDK-Version and User-Agent reporting a version the SDK is not. That is why main ships 3.0.1 while sending 2.0.1. src/version.ts was shielded in .fernignore as a workaround for the same problem, but 3e8ea41 had already proven regen wins. Both generic extra-files entries and both markers are gone, and src/version.ts leaves .fernignore so Fern owns it again. The publish job now rewrites those literals from the release tag, and the stamp fails when a target literal is not found, so a regeneration that renames or restructures those lines breaks the release loudly instead of shipping a stale version silently. Order is stamp, build, assert, publish: the build emits dist/, which is what npm ships, so a stamp after it would fix the sources and still publish stale strings inside the artifact. The assertion covers dist/ in both CJS and ESM as well as the sources, so a build that missed the stamp cannot pass. The stamp applies to the CI checkout only and is never committed back, so those strings read stale on main between releases by design; the published artifact is always built from the stamped and asserted tree. AGENTS.md documents this so it does not get "fixed" later.
dc26fdb to
42f1b8a
Compare
Summary
SDK regeneration against API version
2026-09-13. Adds the models endpoint, the consent-challenge flow for voice cloning, and streaming with word-level timestamps. Also repairs the release-please wiring so a release bumps every version-bearing file.Breaking changes
voices.create()signatureThe
consent: stringparameter is gone. Voice cloning now goes through a two-step consent challenge, and the create carries a second audio file — the speaker reading the challenge phrase aloud.A challenge is single-use and expires — see
challenge.expires_at, which is the only authority on the window.audio.stream()request shapeaudio.stream()now takesStreamAudioRequestinstead ofGetStreamRequest.Acceptstays a top-level header field; every body field moves under a new requiredbodyproperty.GetStreamRequesthas not been removed — it is now the body type (StreamAudioRequest["body"]) and has moved fromresources/audio/client/requests/toapi/types/.Default API version
Bumped from
2026-07-07to2026-09-13. Passversionexplicitly to stay on the old behaviour.New
client.models.list()— available TTS modelsclient.voices.consentChallenges.create()— consent challenge flowclient.audio.streamWithTimestamps()— SSE stream with word-level speech marksvoices.list()filters:type,locale,gender,modelContentTooLargeError(413) and new error codesStreamclass for JSON/SSE streamingRelease wiring
The generic release-please updater was silently no-opping —
maincurrently ships3.0.1while reportingX-Fern-SDK-Version: 2.0.1. Fixed here:x-release-please-versionmarkers.src/BaseClient.tsis Fern-generated and cannot be.fernignored — Fern legitimately owns it — so every regen strips the marker and thegenericupdater silently goes back to no-opping. Bothgenericextra-filesentries and both marker comments are gone.src/version.tsleaves.fernignoretoo: it no longer needs shielding, so Fern owns it again.SDK_VERSION,X-Fern-SDK-Version, theUser-Agentversion, andpackage.jsonversionfromtag_name. The stamp fails when a target literal is missing, so a regen that renames or restructures those lines breaks the release loudly instead of shipping a stale version silently. Prerelease suffixes survive verbatim (4.0.0-alpha.1).pnpm buildemitsdist/, anddist/is what npm ships — a stamp placed after it would fix the sources and still publish the stale strings baked into the artifact. Order is stamp → build → assert → publish, and the assertion now coversdist/in both CJS and ESM as well as the sources..fern/metadata.jsontoextra-files(it was stale at2.0.1). It is jsonpath-based, so no marker is involved and a regen cannot disarm it.repository.urlcasing toSpeechify-AI; npm provenance 422s on a case-inexact URL.AGENTS.mdandmanual-publish.yml, both now in.fernignore.dist/— or the repository URL disagrees with the tag.The stamp rewrites the CI checkout only and is never committed back, so
src/version.tsandsrc/BaseClient.tsread stale onmainbetween releases by design; the published artifact is always built from the stamped and asserted tree.AGENTS.mddocuments this so it does not get "fixed" later.Verified by executing the stamp and assertion scripts extracted from the workflow YAML against sandbox copies of the repo: matching tag, un-stamped tree at
4.0.0, assert-without-stamp control, three renamed/restructured literals, empty tag, non-semver tag, prerelease4.0.0-alpha.1, lowercaserepository.url, adist/built before the stamp, a missingdist/, and a repeat run for idempotency — 51 assertions, all passing. Running release-please's own updaters against the new config for4.0.0confirmspackage.jsonand.fern/metadata.jsonstill update and that zero entries depend on a marker.pnpm buildandpnpm testare clean (29 files, 523 tests).Merge with squash so the conventional title and this footer land on
main.BREAKING CHANGE:
voices.create()no longer acceptsconsent; it requiresconsent_challenge_idandconsent_recording.BREAKING CHANGE:
audio.stream()takesStreamAudioRequestwith body fields nested underbody.BREAKING CHANGE: default API version is now
2026-09-13.Release-As: 4.0.0