diff --git a/packages/ai/src/protocols/assemblyai-transcription.ts b/packages/ai/src/protocols/assemblyai-transcription.ts index d6a556315d0..423868c15d7 100644 --- a/packages/ai/src/protocols/assemblyai-transcription.ts +++ b/packages/ai/src/protocols/assemblyai-transcription.ts @@ -110,8 +110,11 @@ const fromRequest = Effect.fn("AssemblyAITranscription.fromRequest")(function* ( language_code: request.language, language_detection: request.language === undefined ? true : undefined, prompt: request.prompt, - // Turn-level `utterances`, the only segments AssemblyAI returns, require speaker labels. - speaker_labels: request.diarize === true || request.timestamps === "segment" ? true : undefined, + // Turn-level `utterances`, the only segments AssemblyAI returns, and `speakers_expected` require speaker labels. + speaker_labels: + request.diarize === true || request.timestamps === "segment" || request.speakers !== undefined + ? true + : undefined, speakers_expected: request.speakers, }, request.providerOptions, diff --git a/packages/ai/test/transcription.test.ts b/packages/ai/test/transcription.test.ts index aa469a141b2..cdb0e088fc7 100644 --- a/packages/ai/test/transcription.test.ts +++ b/packages/ai/test/transcription.test.ts @@ -5,7 +5,7 @@ import { HttpClientRequest } from "effect/unstable/http" import { Media, Transcription, TranscriptionClient } from "../src/index.js" import { AssemblyAI, Deepgram, Google, OpenAI } from "../src/providers.js" import { it } from "./lib/effect.js" -import { dynamicResponse } from "./lib/http.js" +import { dynamicResponse, json, observe, type Call } from "./lib/http.js" const layer = (handler: Parameters[0]) => TranscriptionClient.layer.pipe(Layer.provideMerge(dynamicResponse(handler))) @@ -171,4 +171,24 @@ describe("Transcription", () => { expect(failure.reason).toMatchObject({ _tag: "ProviderInternal", body: failed }) }), ) + + it.effect("enables AssemblyAI speaker labels when only an expected speaker count is given", () => + Effect.gen(function* () { + const calls: Array = [] + yield* Transcription.start({ model: assemblyai, audio: Media.url("https://a.test/call.mp3"), speakers: 2 }).pipe( + Effect.provide( + layer((input) => observe(calls, input).pipe(Effect.as(json(input, { id: "tr_1", status: "queued" })))), + ), + ) + expect(calls.map((call) => JSON.parse(call.body))).toEqual([ + { + audio_url: "https://a.test/call.mp3", + speech_models: ["universal-3-5-pro"], + language_detection: true, + speaker_labels: true, + speakers_expected: 2, + }, + ]) + }), + ) })