diff --git a/CHANGELOG.md b/CHANGELOG.md index 6106b84..e1a167a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [4.41.6] + +- Add `rewrite_mode` to `DictationConfig` — the model tier that runs the dictation rewrite: `"fast"` (the server default) or `"smart"`, which follows detailed formatting instructions more reliably at higher latency. Unset, it is not sent. The `DictationRewriteMode` type is exported from the package root + ## [4.41.5] - Add `speakerLabelsRevisionIntervalMs` streaming param (sent as `speaker_labels_revision_interval_ms`) — the cadence, in ms of audio time, at which the server emits mid-stream `speakerRevision` events when `speakerLabels` is enabled. Unset or `0` sends only the end-of-stream revision; non-zero values are clamped server-side to 120 000–300 000 ms. The first mid-stream revision needs ~120 s of streamed speech, and one is sent only when some earlier turn's label changed diff --git a/CLAUDE.md b/CLAUDE.md index 7946799..d0b48de 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -360,6 +360,7 @@ const result = await client.dictation.transcribeLive(mic, { stt_prompt: "A doctor dictating a patient visit note.", // max 6000 chars; describes the recording keyterms_prompt: ["AssemblyAI", "U3-Pro"], // whitespace stripped, empties dropped, max 100 terms, 8000 chars total llm_instruction: "Format this as a SOAP note.", // max 2048 chars; follow-up LLM pass over the transcript + rewrite_mode: "smart", // rewrite model tier: "fast" (server default) or "smart" (follows detailed instructions, slower) }); ``` @@ -392,7 +393,7 @@ upload, the transcription and the LLM pass; the service caps audio at 120 s. `si **Exports** from the package root: `DictationTranscriber`, `DictationLiveSession`, `DictationError`, and the `DictationAudioInput`, `DictationConfig`, `DictationLiveOptions`, -`DictationWord` and `DictationResponse` types. +`DictationRewriteMode`, `DictationWord` and `DictationResponse` types. ## LLM Gateway diff --git a/README.md b/README.md index 7a5634b..96259bd 100644 --- a/README.md +++ b/README.md @@ -674,6 +674,17 @@ console.log(result.final_text); // llm_response when there is one, text otherwis When the LLM pass fails, `llm_response` is `null` and `llm_error` says why — the transcript itself still comes back. +`rewrite_mode` picks the model tier that runs the rewrite. `"fast"` is the +default; `"smart"` follows detailed formatting instructions more reliably, at +higher latency: + +```typescript +const result = await client.dictation.transcribeLive(micStream, { + llm_instruction: "Lowercase unless a name, no final punctuation.", + rewrite_mode: "smart", +}); +``` +
@@ -687,6 +698,7 @@ const result = await client.dictation.transcribeLive(micStream, { stt_prompt: "A doctor dictating a patient visit note.", // max 6000 chars keyterms_prompt: ["AssemblyAI", "Universal-3"], // max 100 terms, 8000 chars total llm_instruction: "Format this as a SOAP note.", // max 2048 chars + rewrite_mode: "smart", // rewrite model tier: "fast" (default) or "smart" }); ``` diff --git a/package.json b/package.json index 8266741..944ab0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "assemblyai", - "version": "4.41.5", + "version": "4.41.6", "description": "The AssemblyAI JavaScript SDK provides an easy-to-use interface for interacting with the AssemblyAI API, which supports async and real-time transcription.", "engines": { "node": ">=18" diff --git a/src/services/dictation/service.ts b/src/services/dictation/service.ts index 1f224e3..53eb229 100644 --- a/src/services/dictation/service.ts +++ b/src/services/dictation/service.ts @@ -403,6 +403,8 @@ function buildConfigJson(config: DictationConfig): Record { if (keytermsPrompt) json["keyterms_prompt"] = keytermsPrompt; if (config.llm_instruction !== undefined) json["llm_instruction"] = config.llm_instruction; + if (config.rewrite_mode !== undefined) + json["rewrite_mode"] = config.rewrite_mode; return json; } diff --git a/src/types/dictation/index.ts b/src/types/dictation/index.ts index ffe6ce2..3607d6c 100644 --- a/src/types/dictation/index.ts +++ b/src/types/dictation/index.ts @@ -21,6 +21,13 @@ export type DictationAudioInput = | AsyncIterable | Iterable; +/** + * The model tier that runs the transcript rewrite: `fast` (the server + * default) or `smart`, which follows detailed formatting instructions more + * reliably at higher latency. + */ +export type DictationRewriteMode = "fast" | "smart"; + /** * Options for a dictation request. * @@ -75,6 +82,12 @@ export type DictationConfig = { * characters; longer instructions are rejected. */ llm_instruction?: string; + /** + * The model tier that runs the rewrite: `"fast"` or `"smart"`. `"smart"` + * follows detailed formatting instructions more reliably at higher + * latency. Unset leaves the server default, `"fast"`. + */ + rewrite_mode?: DictationRewriteMode; }; /** diff --git a/tests/unit/dictation.test.ts b/tests/unit/dictation.test.ts index 4f79627..018156b 100644 --- a/tests/unit/dictation.test.ts +++ b/tests/unit/dictation.test.ts @@ -433,6 +433,7 @@ describe("dictation config", () => { stt_prompt: "A doctor dictating a patient visit note.", keyterms_prompt: ["AssemblyAI", "U3-Pro"], llm_instruction: "Format this as a SOAP note.", + rewrite_mode: "smart", }); expect(await configPart()).toEqual({ sample_rate: 16000, @@ -441,9 +442,18 @@ describe("dictation config", () => { stt_prompt: "A doctor dictating a patient visit note.", keyterms_prompt: ["AssemblyAI", "U3-Pro"], llm_instruction: "Format this as a SOAP note.", + rewrite_mode: "smart", }); }); + it("should leave rewrite_mode out when it is unset", async () => { + mockOk(); + await assembly.dictation.transcribeLive(chunks(bytes("RIFF")), { + llm_instruction: "Clean this up.", + }); + expect(await configPart()).toEqual({ llm_instruction: "Clean this up." }); + }); + it("should never send keys the dictation API does not accept", async () => { mockOk(); await assembly.dictation.transcribeLive(chunks(bytes("RIFF")), {