@effect-uai/elevenlabs 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/ElevenLabsMusicGenerator.d.mts +1 -3
  2. package/dist/ElevenLabsMusicGenerator.d.mts.map +1 -1
  3. package/dist/ElevenLabsMusicGenerator.mjs +6 -4
  4. package/dist/ElevenLabsMusicGenerator.mjs.map +1 -1
  5. package/dist/ElevenLabsMusicGenerator.test.d.mts +1 -1
  6. package/dist/ElevenLabsMusicGenerator.test.mjs +10 -6
  7. package/dist/ElevenLabsMusicGenerator.test.mjs.map +1 -1
  8. package/dist/ElevenLabsSynthesizer.d.mts +4 -7
  9. package/dist/ElevenLabsSynthesizer.d.mts.map +1 -1
  10. package/dist/ElevenLabsSynthesizer.mjs +1 -1
  11. package/dist/ElevenLabsSynthesizer.mjs.map +1 -1
  12. package/dist/ElevenLabsTranscriber.d.mts +5 -9
  13. package/dist/ElevenLabsTranscriber.d.mts.map +1 -1
  14. package/dist/ElevenLabsTranscriber.mjs +1 -1
  15. package/dist/ElevenLabsTranscriber.mjs.map +1 -1
  16. package/dist/ElevenLabsTranscriber.test.d.mts +1 -1
  17. package/dist/ElevenLabsTranscriber.test.mjs +10 -5
  18. package/dist/ElevenLabsTranscriber.test.mjs.map +1 -1
  19. package/dist/codec.d.mts +4 -6
  20. package/dist/codec.d.mts.map +1 -1
  21. package/dist/codec.mjs +1 -1
  22. package/dist/codec.mjs.map +1 -1
  23. package/dist/codec.test.d.mts +1 -1
  24. package/dist/codec.test.mjs +19 -13
  25. package/dist/codec.test.mjs.map +1 -1
  26. package/dist/dist-C0AvqZTC.mjs +145 -0
  27. package/dist/dist-C0AvqZTC.mjs.map +1 -0
  28. package/dist/{magic-string.es-CaWgF-3p.mjs → magic-string.es-CUAnjKYC.mjs} +14 -13
  29. package/dist/{magic-string.es-CaWgF-3p.mjs.map → magic-string.es-CUAnjKYC.mjs.map} +1 -1
  30. package/dist/models.d.mts.map +1 -1
  31. package/dist/{musicCodec-CZni1gAQ.d.mts → musicCodec-DjmvNC4W.d.mts} +1 -2
  32. package/dist/musicCodec-DjmvNC4W.d.mts.map +1 -0
  33. package/dist/musicCodec.d.mts +1 -1
  34. package/dist/musicCodec.mjs.map +1 -1
  35. package/dist/realtimeStt.d.mts +0 -1
  36. package/dist/realtimeStt.d.mts.map +1 -1
  37. package/dist/realtimeStt.mjs.map +1 -1
  38. package/dist/realtimeTts.d.mts +2 -2
  39. package/dist/realtimeTts.d.mts.map +1 -1
  40. package/dist/realtimeTts.mjs.map +1 -1
  41. package/dist/region.d.mts.map +1 -1
  42. package/dist/region.mjs.map +1 -1
  43. package/dist/region.test.d.mts +1 -1
  44. package/dist/region.test.mjs +1 -1
  45. package/dist/region.test.mjs.map +1 -1
  46. package/dist/{dist-CWoAuwS9.mjs → test.DNmyFkvJ-N3QqMRwZ.mjs} +257 -381
  47. package/dist/test.DNmyFkvJ-N3QqMRwZ.mjs.map +1 -0
  48. package/package.json +5 -5
  49. package/src/ElevenLabsMusicGenerator.ts +7 -10
  50. package/src/ElevenLabsSynthesizer.ts +10 -13
  51. package/src/ElevenLabsTranscriber.ts +5 -8
  52. package/src/realtimeStt.ts +12 -14
  53. package/dist/dist-CWoAuwS9.mjs.map +0 -1
  54. package/dist/musicCodec-CZni1gAQ.d.mts.map +0 -1
  55. /package/dist/{chunk-uyGKjUfl.mjs → rolldown-runtime-EAsCxrDo.mjs} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { ElevenLabsMusicModel } from "./models.mjs";
2
- import { t as ElevenLabsCompositionPlan } from "./musicCodec-CZni1gAQ.mjs";
2
+ import { t as ElevenLabsCompositionPlan } from "./musicCodec-DjmvNC4W.mjs";
3
3
  import { ElevenLabsRegion } from "./region.mjs";
4
4
  import { Context, Duration, Effect, Layer, Redacted, Stream } from "effect";
5
5
  import { HttpClient } from "effect/unstable/http";
@@ -7,8 +7,6 @@ import { CommonGenerateMusicRequest, CommonStreamGenerateMusicRequest, GenerateR
7
7
  import { MusicGenerator } from "@effect-uai/core/MusicGenerator";
8
8
  import * as AiError from "@effect-uai/core/AiError";
9
9
  import { AudioChunk } from "@effect-uai/core/Audio";
10
-
11
- //#region src/ElevenLabsMusicGenerator.d.ts
12
10
  declare namespace ElevenLabsMusicGenerator_d_exports {
13
11
  export { Config, CreateCompositionPlanRequest, ElevenLabsMusicGenerateRequest, ElevenLabsMusicGenerator, ElevenLabsMusicGeneratorService, layer, make };
14
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsMusicGenerator.d.mts","names":[],"sources":["../src/ElevenLabsMusicGenerator.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA;;;;;KAAY,8BAAA,GAAiC,IAAA,CAAK,0BAAA;EAAA,SACvC,KAAA,GAAQ,oBAAA;EAAA,SACR,eAAA,GAAkB,yBAAA;EAAA,SAClB,iBAAA;EAAA,SACA,YAAA;EAAA,SACA,wBAAA;AAAA;AAAA,KAGC,4BAAA;EAAA,SACD,MAAA;EAAA,SACA,QAAA,GAAW,QAAA,CAAS,QAAA;EAAA,SACpB,qBAAA,GAAwB,yBAAA;EAAA,SACxB,KAAA,GAAQ,oBAAA;AAAA;AAAA,KAGP,+BAAA;EAAA,SACD,QAAA,GACP,OAAA,EAAS,8BAAA,KACN,MAAA,CAAO,MAAA,CAAO,cAAA,EAAgB,OAAA,CAAQ,OAAA;EAAA,SAClC,gBAAA,GACP,OAAA,EAAS,8BAAA,KACN,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,OAAA;EAAA,SAC9B,oBAAA,SACP,KAAA,EAAO,MAAA,CAAO,MAAA,CAAO,iBAAA,EAAmB,CAAA,EAAG,CAAA,GAC3C,OAAA,EAAS,gCAAA,KACN,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,OAAA,CAAQ,OAAA,GAAU,CAAA,EAAG,CAAA;;;;;;WAMjD,qBAAA,GACP,OAAA,EAAS,4BAAA,KACN,MAAA,CAAO,MAAA,CAAO,yBAAA,EAA2B,OAAA,CAAQ,OAAA;AAAA;AAAA,cACvD,6BAAA;cAEY,wBAAA,SAAiC,6BAAA;AAAA,KAKlC,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;EAAA,SACA,MAAA,GAAS,gBAAA;AAAA;AAAA,cA8NP,IAAA,GACX,GAAA,EAAK,MAAA,KACJ,MAAA,CAAO,MAAA,CAAO,+BAAA,SAAwC,UAAA,CAAW,UAAA;AA7PpE;;;;;;;;AAAA,cAkRa,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CAAM,wBAAA,GAA2B,cAAA,SAAuB,UAAA,CAAW,UAAA"}
1
+ {"version":3,"file":"ElevenLabsMusicGenerator.d.mts","names":[],"sources":["../src/ElevenLabsMusicGenerator.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6CY,iCAAiC,KAAK;WACvC,QAAQ;WACR,kBAAkB;WAClB;WACA;WACA;;KAGC;WACD;WACA,WAAW,SAAS;WACpB,wBAAwB;WACxB,QAAQ;;KAGP;WACD,WACP,SAAS,mCACN,OAAO,OAAO,gBAAgB,QAAQ;WAClC,mBACP,SAAS,mCACN,OAAO,OAAO,YAAY,QAAQ;WAC9B,uBAAuB,GAAG,GACjC,OAAO,OAAO,OAAO,mBAAmB,GAAG,IAC3C,SAAS,qCACN,OAAO,OAAO,kBAAkB,QAAQ,UAAU,GAAG;;;;;;WAMjD,wBACP,SAAS,iCACN,OAAO,OAAO,2BAA2B,QAAQ;;;cAG3C,iCAAiC;KAKlC;WACD,QAAQ,SAAS;WACjB;WACA,SAAS;;cA8NP,OAAI,KACV,WACJ,OAAO,OAAO,wCAAwC,WAAW;;;;;;;;;cAqBvD,QAAK,KACX,WACJ,MAAM,MAAM,2BAA2B,uBAAuB,WAAW"}
@@ -1,4 +1,4 @@
1
- import { n as __exportAll } from "./chunk-uyGKjUfl.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.mjs";
2
2
  import { defaultFormat, formatToOutputSlug } from "./codec.mjs";
3
3
  import { decodeCompositionPlan, warnDroppedPromptModeHints, wireCompositionPlan } from "./musicCodec.mjs";
4
4
  import { resolveHost } from "./region.mjs";
@@ -113,7 +113,7 @@ const generateImpl = (cfg) => (request) => Effect.gen(function* () {
113
113
  const buffer = yield* response.arrayBuffer.pipe(Effect.mapError(musicTransportFailure));
114
114
  const bytes = new Uint8Array(buffer);
115
115
  const songId = response.headers["song_id"] ?? response.headers["x-song-id"];
116
- return singleVariant({
116
+ const result = {
117
117
  audio: {
118
118
  format,
119
119
  bytes
@@ -121,7 +121,8 @@ const generateImpl = (cfg) => (request) => Effect.gen(function* () {
121
121
  provider: "elevenlabs-music",
122
122
  ...typeof songId === "string" && { songId },
123
123
  ...request.signWithC2pa === true && { watermark: "c2pa" }
124
- });
124
+ };
125
+ return singleVariant(result);
125
126
  });
126
127
  const streamGenerationImpl = (cfg) => (request) => Stream.unwrap(Effect.gen(function* () {
127
128
  const client = yield* HttpClient.HttpClient;
@@ -158,7 +159,8 @@ const createCompositionPlanImpl = (cfg) => (request) => Effect.gen(function* ()
158
159
  const text = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
159
160
  return yield* Effect.fail(musicHttpStatusError(response.status, text));
160
161
  }
161
- return decodeCompositionPlan(yield* response.json.pipe(Effect.mapError(musicTransportFailure)));
162
+ const json = yield* response.json.pipe(Effect.mapError(musicTransportFailure));
163
+ return decodeCompositionPlan(json);
162
164
  });
163
165
  const make = (cfg) => Effect.map(HttpClient.HttpClient, (client) => ({
164
166
  generate: (request) => generateImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsMusicGenerator.mjs","names":[],"sources":["../src/ElevenLabsMusicGenerator.ts"],"sourcesContent":["import { Context, Duration, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport type { AudioChunk, AudioFormat } from \"@effect-uai/core/Audio\"\nimport type {\n CommonGenerateMusicRequest,\n CommonStreamGenerateMusicRequest,\n GenerateResult,\n MusicResult,\n MusicSessionInput,\n MusicStreamEvent,\n} from \"@effect-uai/core/Music\"\nimport { singleVariant } from \"@effect-uai/core/Music\"\nimport { MusicGenerator, type MusicGeneratorService } from \"@effect-uai/core/MusicGenerator\"\nimport { defaultFormat, formatToOutputSlug } from \"./codec.js\"\nimport type { ElevenLabsMusicModel } from \"./models.js\"\nimport {\n decodeCompositionPlan,\n type ElevenLabsCompositionPlan,\n warnDroppedPromptModeHints,\n wireCompositionPlan,\n} from \"./musicCodec.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed music request. Narrows `model` to\n * `ElevenLabsMusicModel` and adds provider-specific extras:\n *\n * - `compositionPlan` — switch from prompt mode to plan mode. Mutually\n * exclusive with `prompt` on the wire.\n * - `forceInstrumental` — skip vocals. ElevenLabs has no `instrumental`\n * on the cross-provider Common request (the field was removed in\n * v0.7 because it has wildly different semantics per provider); the\n * typed surface restores it.\n * - `signWithC2pa` — opt-in C2PA Content Credentials, MP3 output only.\n * - `respectSectionsDurations` — composition-plan mode only. False\n * trades section-duration accuracy for quality + latency.\n *\n * Setting `compositionPlan` with a non-empty `prompt`, or with\n * `duration`, fails `InvalidRequest` at the codec layer.\n */\nexport type ElevenLabsMusicGenerateRequest = Omit<CommonGenerateMusicRequest, \"model\"> & {\n readonly model?: ElevenLabsMusicModel\n readonly compositionPlan?: ElevenLabsCompositionPlan\n readonly forceInstrumental?: boolean\n readonly signWithC2pa?: boolean\n readonly respectSectionsDurations?: boolean\n}\n\nexport type CreateCompositionPlanRequest = {\n readonly prompt: string\n readonly duration?: Duration.Duration\n readonly sourceCompositionPlan?: ElevenLabsCompositionPlan\n readonly model?: ElevenLabsMusicModel\n}\n\nexport type ElevenLabsMusicGeneratorService = {\n readonly generate: (\n request: ElevenLabsMusicGenerateRequest,\n ) => Effect.Effect<GenerateResult, AiError.AiError>\n readonly streamGeneration: (\n request: ElevenLabsMusicGenerateRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError>\n readonly streamGenerationFrom: <E, R>(\n input: Stream.Stream<MusicSessionInput, E, R>,\n request: CommonStreamGenerateMusicRequest,\n ) => Stream.Stream<MusicStreamEvent, AiError.AiError | E, R>\n /**\n * Free endpoint (rate-limited, no credit cost): turn a prompt into a\n * structured `MusicPrompt` plan. Feed the result back into\n * `generate` / `streamGeneration` via `compositionPlan`.\n */\n readonly createCompositionPlan: (\n request: CreateCompositionPlanRequest,\n ) => Effect.Effect<ElevenLabsCompositionPlan, AiError.AiError>\n}\n\nexport class ElevenLabsMusicGenerator extends Context.Service<\n ElevenLabsMusicGenerator,\n ElevenLabsMusicGeneratorService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsMusicGenerator\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\nconst DEFAULT_MODEL: ElevenLabsMusicModel = \"music_v1\"\n\n// ---------------------------------------------------------------------------\n// HTTP errors (music namespace; reuses the same status taxonomy)\n// ---------------------------------------------------------------------------\n\nconst musicTransportFailure = (cause: unknown): AiError.AiError =>\n new AiError.Unavailable({ provider: \"elevenlabs-music\", raw: cause })\n\nconst musicHttpStatusError = (status: number, body: string): AiError.AiError => {\n if (status === 429) return new AiError.RateLimited({ provider: \"elevenlabs-music\", raw: body })\n if (status === 408 || status === 504)\n return new AiError.Timeout({ provider: \"elevenlabs-music\", raw: body })\n if (status === 401)\n return new AiError.AuthFailed({ provider: \"elevenlabs-music\", subtype: \"auth\", raw: body })\n if (status === 403)\n return new AiError.AuthFailed({\n provider: \"elevenlabs-music\",\n subtype: \"permission\",\n raw: body,\n })\n if (status === 402)\n return new AiError.AuthFailed({\n provider: \"elevenlabs-music\",\n subtype: \"billing\",\n raw: body,\n })\n if (status >= 500)\n return new AiError.Unavailable({ provider: \"elevenlabs-music\", status, raw: body })\n return new AiError.InvalidRequest({ provider: \"elevenlabs-music\", raw: body })\n}\n\n// ---------------------------------------------------------------------------\n// Wire body\n// ---------------------------------------------------------------------------\n\n/**\n * Build the JSON body for `/v1/music` (sync + stream share the body).\n *\n * Mutual exclusion: `compositionPlan` and prompt-mode fields cannot\n * coexist. When `compositionPlan` is set, `prompt` must be empty and\n * `duration` must be unset (section durations live on the plan).\n */\nconst buildBody = (request: ElevenLabsMusicGenerateRequest) =>\n Effect.gen(function* () {\n const model = request.model ?? DEFAULT_MODEL\n if (request.compositionPlan !== undefined) {\n if (request.prompt.length > 0) {\n return yield* Effect.fail(\n new AiError.InvalidRequest({\n provider: \"elevenlabs-music\",\n param: \"prompt\",\n raw: \"`prompt` and `compositionPlan` are mutually exclusive. Pass one or the other (compositionPlan carries its own per-section lyrics and styles).\",\n }),\n )\n }\n if (request.duration !== undefined) {\n return yield* Effect.fail(\n new AiError.InvalidRequest({\n provider: \"elevenlabs-music\",\n param: \"duration\",\n raw: \"`duration` is ignored when `compositionPlan` is set; section durations live on the plan. Remove `duration`.\",\n }),\n )\n }\n return {\n composition_plan: wireCompositionPlan(request.compositionPlan),\n model_id: model,\n ...(request.seed !== undefined && { seed: request.seed }),\n ...(request.forceInstrumental !== undefined && {\n force_instrumental: request.forceInstrumental,\n }),\n ...(request.respectSectionsDurations !== undefined && {\n respect_sections_durations: request.respectSectionsDurations,\n }),\n ...(request.signWithC2pa !== undefined && { sign_with_c2pa: request.signWithC2pa }),\n }\n }\n yield* warnDroppedPromptModeHints(request as CommonGenerateMusicRequest)\n return {\n prompt: request.prompt,\n model_id: model,\n ...(request.duration !== undefined && {\n music_length_ms: Duration.toMillis(request.duration),\n }),\n ...(request.seed !== undefined && { seed: request.seed }),\n ...(request.forceInstrumental !== undefined && {\n force_instrumental: request.forceInstrumental,\n }),\n ...(request.signWithC2pa !== undefined && { sign_with_c2pa: request.signWithC2pa }),\n }\n })\n\nconst buildMusicHttpRequest = (\n cfg: Config,\n request: ElevenLabsMusicGenerateRequest,\n path: \"\" | \"/stream\",\n) =>\n Effect.gen(function* () {\n const format: AudioFormat = request.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const body = yield* buildBody(request)\n const url = `${resolveHost(cfg)}/music${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(body),\n )\n return { httpRequest, format }\n })\n\n// ---------------------------------------------------------------------------\n// Service implementation\n// ---------------------------------------------------------------------------\n\nconst generateImpl =\n (cfg: Config) =>\n (\n request: ElevenLabsMusicGenerateRequest,\n ): Effect.Effect<GenerateResult, AiError.AiError, HttpClient.HttpClient> =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildMusicHttpRequest(cfg, request, \"\")\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(musicHttpStatusError(response.status, text))\n }\n const buffer = yield* response.arrayBuffer.pipe(Effect.mapError(musicTransportFailure))\n const bytes = new Uint8Array(buffer)\n const songId = response.headers[\"song_id\"] ?? response.headers[\"x-song-id\"]\n const result: MusicResult = {\n audio: { format, bytes },\n provider: \"elevenlabs-music\",\n ...(typeof songId === \"string\" && { songId }),\n ...(request.signWithC2pa === true && { watermark: \"c2pa\" as const }),\n }\n return singleVariant(result)\n })\n\nconst streamGenerationImpl =\n (cfg: Config) =>\n (\n request: ElevenLabsMusicGenerateRequest,\n ): Stream.Stream<AudioChunk, AiError.AiError, HttpClient.HttpClient> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildMusicHttpRequest(cfg, request, \"/stream\")\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(musicHttpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(musicTransportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n/**\n * ElevenLabs music has no bidirectional session at the wire level.\n * Layer does not register `MusicInteractiveSession`, so callers using\n * `MusicGenerator.streamGenerationFrom` get a compile-time error\n * before this runtime fallback fires.\n */\nconst streamGenerationFromUnsupported = <E, R>(\n _input: Stream.Stream<MusicSessionInput, E, R>,\n _request: CommonStreamGenerateMusicRequest,\n): Stream.Stream<MusicStreamEvent, AiError.AiError | E, R> =>\n Stream.fail(\n new AiError.Unsupported({\n provider: \"elevenlabs-music\",\n capability: \"streamGenerationFrom\",\n reason:\n \"ElevenLabs music has no bidirectional session. Use `streamGeneration` for chunked output, or `createCompositionPlan` + `generate` for structured plans.\",\n }),\n )\n\nconst createCompositionPlanImpl =\n (cfg: Config) =>\n (\n request: CreateCompositionPlanRequest,\n ): Effect.Effect<ElevenLabsCompositionPlan, AiError.AiError, HttpClient.HttpClient> =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const body = {\n prompt: request.prompt,\n model_id: request.model ?? DEFAULT_MODEL,\n ...(request.duration !== undefined && {\n music_length_ms: Duration.toMillis(request.duration),\n }),\n ...(request.sourceCompositionPlan !== undefined && {\n source_composition_plan: wireCompositionPlan(request.sourceCompositionPlan),\n }),\n }\n const httpRequest = HttpClientRequest.post(`${resolveHost(cfg)}/music/plan`).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(body),\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(musicHttpStatusError(response.status, text))\n }\n const json = yield* response.json.pipe(Effect.mapError(musicTransportFailure))\n return decodeCompositionPlan(json)\n })\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (\n cfg: Config,\n): Effect.Effect<ElevenLabsMusicGeneratorService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient, (client) => ({\n generate: (request) =>\n generateImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamGeneration: (request) =>\n streamGenerationImpl(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client)),\n streamGenerationFrom: streamGenerationFromUnsupported,\n createCompositionPlan: (request) =>\n createCompositionPlanImpl(cfg)(request).pipe(\n Effect.provideService(HttpClient.HttpClient, client),\n ),\n }))\n\n/**\n * Layer that registers the provider-specific `ElevenLabsMusicGenerator`\n * tag and the generic `MusicGenerator` tag.\n *\n * Does NOT register `MusicInteractiveSession`. ElevenLabs music has no\n * bidirectional wire endpoint; `streamGenerationFrom` against this\n * Layer alone fails to typecheck.\n */\nexport const layer = (\n cfg: Config,\n): Layer.Layer<ElevenLabsMusicGenerator | MusicGenerator, never, HttpClient.HttpClient> =>\n Layer.merge(\n Layer.effect(ElevenLabsMusicGenerator, make(cfg)),\n Layer.effect(\n MusicGenerator,\n Effect.map(\n make(cfg),\n (s): MusicGeneratorService => ({\n generate: (req: CommonGenerateMusicRequest) =>\n s.generate({ ...req, model: req.model as ElevenLabsMusicModel }),\n streamGeneration: (req: CommonStreamGenerateMusicRequest) =>\n s.streamGeneration({ ...req, model: req.model as ElevenLabsMusicModel }),\n streamGenerationFrom: s.streamGenerationFrom,\n }),\n ),\n ),\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"ElevenLabsMusicGenerator.mjs","names":[],"sources":["../src/ElevenLabsMusicGenerator.ts"],"sourcesContent":["import { Context, Duration, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport type { AudioChunk, AudioFormat } from \"@effect-uai/core/Audio\"\nimport type {\n CommonGenerateMusicRequest,\n CommonStreamGenerateMusicRequest,\n GenerateResult,\n MusicResult,\n MusicSessionInput,\n MusicStreamEvent,\n} from \"@effect-uai/core/Music\"\nimport { singleVariant } from \"@effect-uai/core/Music\"\nimport { MusicGenerator, type MusicGeneratorService } from \"@effect-uai/core/MusicGenerator\"\nimport { defaultFormat, formatToOutputSlug } from \"./codec.js\"\nimport type { ElevenLabsMusicModel } from \"./models.js\"\nimport {\n decodeCompositionPlan,\n type ElevenLabsCompositionPlan,\n warnDroppedPromptModeHints,\n wireCompositionPlan,\n} from \"./musicCodec.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed music request. Narrows `model` to\n * `ElevenLabsMusicModel` and adds provider-specific extras:\n *\n * - `compositionPlan` — switch from prompt mode to plan mode. Mutually\n * exclusive with `prompt` on the wire.\n * - `forceInstrumental` — skip vocals. ElevenLabs has no `instrumental`\n * on the cross-provider Common request (the field was removed in\n * v0.7 because it has wildly different semantics per provider); the\n * typed surface restores it.\n * - `signWithC2pa` — opt-in C2PA Content Credentials, MP3 output only.\n * - `respectSectionsDurations` — composition-plan mode only. False\n * trades section-duration accuracy for quality + latency.\n *\n * Setting `compositionPlan` with a non-empty `prompt`, or with\n * `duration`, fails `InvalidRequest` at the codec layer.\n */\nexport type ElevenLabsMusicGenerateRequest = Omit<CommonGenerateMusicRequest, \"model\"> & {\n readonly model?: ElevenLabsMusicModel\n readonly compositionPlan?: ElevenLabsCompositionPlan\n readonly forceInstrumental?: boolean\n readonly signWithC2pa?: boolean\n readonly respectSectionsDurations?: boolean\n}\n\nexport type CreateCompositionPlanRequest = {\n readonly prompt: string\n readonly duration?: Duration.Duration\n readonly sourceCompositionPlan?: ElevenLabsCompositionPlan\n readonly model?: ElevenLabsMusicModel\n}\n\nexport type ElevenLabsMusicGeneratorService = {\n readonly generate: (\n request: ElevenLabsMusicGenerateRequest,\n ) => Effect.Effect<GenerateResult, AiError.AiError>\n readonly streamGeneration: (\n request: ElevenLabsMusicGenerateRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError>\n readonly streamGenerationFrom: <E, R>(\n input: Stream.Stream<MusicSessionInput, E, R>,\n request: CommonStreamGenerateMusicRequest,\n ) => Stream.Stream<MusicStreamEvent, AiError.AiError | E, R>\n /**\n * Free endpoint (rate-limited, no credit cost): turn a prompt into a\n * structured `MusicPrompt` plan. Feed the result back into\n * `generate` / `streamGeneration` via `compositionPlan`.\n */\n readonly createCompositionPlan: (\n request: CreateCompositionPlanRequest,\n ) => Effect.Effect<ElevenLabsCompositionPlan, AiError.AiError>\n}\n\nexport class ElevenLabsMusicGenerator extends Context.Service<\n ElevenLabsMusicGenerator,\n ElevenLabsMusicGeneratorService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsMusicGenerator\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\nconst DEFAULT_MODEL: ElevenLabsMusicModel = \"music_v1\"\n\n// ---------------------------------------------------------------------------\n// HTTP errors (music namespace; reuses the same status taxonomy)\n// ---------------------------------------------------------------------------\n\nconst musicTransportFailure = (cause: unknown): AiError.AiError =>\n new AiError.Unavailable({ provider: \"elevenlabs-music\", raw: cause })\n\nconst musicHttpStatusError = (status: number, body: string): AiError.AiError => {\n if (status === 429) return new AiError.RateLimited({ provider: \"elevenlabs-music\", raw: body })\n if (status === 408 || status === 504)\n return new AiError.Timeout({ provider: \"elevenlabs-music\", raw: body })\n if (status === 401)\n return new AiError.AuthFailed({ provider: \"elevenlabs-music\", subtype: \"auth\", raw: body })\n if (status === 403)\n return new AiError.AuthFailed({\n provider: \"elevenlabs-music\",\n subtype: \"permission\",\n raw: body,\n })\n if (status === 402)\n return new AiError.AuthFailed({\n provider: \"elevenlabs-music\",\n subtype: \"billing\",\n raw: body,\n })\n if (status >= 500)\n return new AiError.Unavailable({ provider: \"elevenlabs-music\", status, raw: body })\n return new AiError.InvalidRequest({ provider: \"elevenlabs-music\", raw: body })\n}\n\n// ---------------------------------------------------------------------------\n// Wire body\n// ---------------------------------------------------------------------------\n\n/**\n * Build the JSON body for `/v1/music` (sync + stream share the body).\n *\n * Mutual exclusion: `compositionPlan` and prompt-mode fields cannot\n * coexist. When `compositionPlan` is set, `prompt` must be empty and\n * `duration` must be unset (section durations live on the plan).\n */\nconst buildBody = (request: ElevenLabsMusicGenerateRequest) =>\n Effect.gen(function* () {\n const model = request.model ?? DEFAULT_MODEL\n if (request.compositionPlan !== undefined) {\n if (request.prompt.length > 0) {\n return yield* Effect.fail(\n new AiError.InvalidRequest({\n provider: \"elevenlabs-music\",\n param: \"prompt\",\n raw: \"`prompt` and `compositionPlan` are mutually exclusive. Pass one or the other (compositionPlan carries its own per-section lyrics and styles).\",\n }),\n )\n }\n if (request.duration !== undefined) {\n return yield* Effect.fail(\n new AiError.InvalidRequest({\n provider: \"elevenlabs-music\",\n param: \"duration\",\n raw: \"`duration` is ignored when `compositionPlan` is set; section durations live on the plan. Remove `duration`.\",\n }),\n )\n }\n return {\n composition_plan: wireCompositionPlan(request.compositionPlan),\n model_id: model,\n ...(request.seed !== undefined && { seed: request.seed }),\n ...(request.forceInstrumental !== undefined && {\n force_instrumental: request.forceInstrumental,\n }),\n ...(request.respectSectionsDurations !== undefined && {\n respect_sections_durations: request.respectSectionsDurations,\n }),\n ...(request.signWithC2pa !== undefined && { sign_with_c2pa: request.signWithC2pa }),\n }\n }\n yield* warnDroppedPromptModeHints(request as CommonGenerateMusicRequest)\n return {\n prompt: request.prompt,\n model_id: model,\n ...(request.duration !== undefined && {\n music_length_ms: Duration.toMillis(request.duration),\n }),\n ...(request.seed !== undefined && { seed: request.seed }),\n ...(request.forceInstrumental !== undefined && {\n force_instrumental: request.forceInstrumental,\n }),\n ...(request.signWithC2pa !== undefined && { sign_with_c2pa: request.signWithC2pa }),\n }\n })\n\nconst buildMusicHttpRequest = (\n cfg: Config,\n request: ElevenLabsMusicGenerateRequest,\n path: \"\" | \"/stream\",\n) =>\n Effect.gen(function* () {\n const format: AudioFormat = request.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const body = yield* buildBody(request)\n const url = `${resolveHost(cfg)}/music${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(body),\n )\n return { httpRequest, format }\n })\n\n// ---------------------------------------------------------------------------\n// Service implementation\n// ---------------------------------------------------------------------------\n\nconst generateImpl =\n (cfg: Config) =>\n (\n request: ElevenLabsMusicGenerateRequest,\n ): Effect.Effect<GenerateResult, AiError.AiError, HttpClient.HttpClient> =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildMusicHttpRequest(cfg, request, \"\")\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(musicHttpStatusError(response.status, text))\n }\n const buffer = yield* response.arrayBuffer.pipe(Effect.mapError(musicTransportFailure))\n const bytes = new Uint8Array(buffer)\n const songId = response.headers[\"song_id\"] ?? response.headers[\"x-song-id\"]\n const result: MusicResult = {\n audio: { format, bytes },\n provider: \"elevenlabs-music\",\n ...(typeof songId === \"string\" && { songId }),\n ...(request.signWithC2pa === true && { watermark: \"c2pa\" as const }),\n }\n return singleVariant(result)\n })\n\nconst streamGenerationImpl =\n (cfg: Config) =>\n (\n request: ElevenLabsMusicGenerateRequest,\n ): Stream.Stream<AudioChunk, AiError.AiError, HttpClient.HttpClient> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildMusicHttpRequest(cfg, request, \"/stream\")\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(musicHttpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(musicTransportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n/**\n * ElevenLabs music has no bidirectional session at the wire level.\n * Layer does not register `MusicInteractiveSession`, so callers using\n * `MusicGenerator.streamGenerationFrom` get a compile-time error\n * before this runtime fallback fires.\n */\nconst streamGenerationFromUnsupported = <E, R>(\n _input: Stream.Stream<MusicSessionInput, E, R>,\n _request: CommonStreamGenerateMusicRequest,\n): Stream.Stream<MusicStreamEvent, AiError.AiError | E, R> =>\n Stream.fail(\n new AiError.Unsupported({\n provider: \"elevenlabs-music\",\n capability: \"streamGenerationFrom\",\n reason:\n \"ElevenLabs music has no bidirectional session. Use `streamGeneration` for chunked output, or `createCompositionPlan` + `generate` for structured plans.\",\n }),\n )\n\nconst createCompositionPlanImpl =\n (cfg: Config) =>\n (\n request: CreateCompositionPlanRequest,\n ): Effect.Effect<ElevenLabsCompositionPlan, AiError.AiError, HttpClient.HttpClient> =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const body = {\n prompt: request.prompt,\n model_id: request.model ?? DEFAULT_MODEL,\n ...(request.duration !== undefined && {\n music_length_ms: Duration.toMillis(request.duration),\n }),\n ...(request.sourceCompositionPlan !== undefined && {\n source_composition_plan: wireCompositionPlan(request.sourceCompositionPlan),\n }),\n }\n const httpRequest = HttpClientRequest.post(`${resolveHost(cfg)}/music/plan`).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(body),\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(Effect.mapError(musicTransportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(musicHttpStatusError(response.status, text))\n }\n const json = yield* response.json.pipe(Effect.mapError(musicTransportFailure))\n return decodeCompositionPlan(json)\n })\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (\n cfg: Config,\n): Effect.Effect<ElevenLabsMusicGeneratorService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient, (client) => ({\n generate: (request) =>\n generateImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamGeneration: (request) =>\n streamGenerationImpl(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client)),\n streamGenerationFrom: streamGenerationFromUnsupported,\n createCompositionPlan: (request) =>\n createCompositionPlanImpl(cfg)(request).pipe(\n Effect.provideService(HttpClient.HttpClient, client),\n ),\n }))\n\n/**\n * Layer that registers the provider-specific `ElevenLabsMusicGenerator`\n * tag and the generic `MusicGenerator` tag.\n *\n * Does NOT register `MusicInteractiveSession`. ElevenLabs music has no\n * bidirectional wire endpoint; `streamGenerationFrom` against this\n * Layer alone fails to typecheck.\n */\nexport const layer = (\n cfg: Config,\n): Layer.Layer<ElevenLabsMusicGenerator | MusicGenerator, never, HttpClient.HttpClient> =>\n Layer.merge(\n Layer.effect(ElevenLabsMusicGenerator, make(cfg)),\n Layer.effect(\n MusicGenerator,\n Effect.map(make(cfg), (s): MusicGeneratorService => ({\n generate: (req: CommonGenerateMusicRequest) =>\n s.generate({ ...req, model: req.model as ElevenLabsMusicModel }),\n streamGeneration: (req: CommonStreamGenerateMusicRequest) =>\n s.streamGeneration({ ...req, model: req.model as ElevenLabsMusicModel }),\n streamGenerationFrom: s.streamGenerationFrom,\n })),\n ),\n )\n"],"mappings":"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"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,4 +1,5 @@
1
- import { i as it, n as globalExpect, r as describe, t as import_dist } from "./dist-CWoAuwS9.mjs";
1
+ import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-N3QqMRwZ.mjs";
2
+ import { t as import_dist } from "./dist-C0AvqZTC.mjs";
2
3
  import { ElevenLabsMusicGenerator, layer } from "./ElevenLabsMusicGenerator.mjs";
3
4
  import { Duration, Effect, Layer, Redacted, Stream } from "effect";
4
5
  import { FetchHttpClient } from "effect/unstable/http";
@@ -27,16 +28,18 @@ describe("ElevenLabsMusicGenerator Layer (compile-time)", () => {
27
28
  model: "music_v1",
28
29
  prompt: ""
29
30
  }));
30
- (0, import_dist.expectTypeOf)(Stream.runDrain(events).pipe(Effect.provide(live))).toEqualTypeOf();
31
+ const provided = Stream.runDrain(events).pipe(Effect.provide(live));
32
+ (0, import_dist.expectTypeOf)(provided).toEqualTypeOf();
31
33
  });
32
34
  it("sync `generate` returns GenerateResult and requires no marker", () => {
33
- (0, import_dist.expectTypeOf)(MusicGenerator$1.generate({
35
+ const gen = MusicGenerator$1.generate({
34
36
  model: "music_v1",
35
37
  prompt: "house"
36
- }).pipe(Effect.provide(live))).toEqualTypeOf();
38
+ }).pipe(Effect.provide(live));
39
+ (0, import_dist.expectTypeOf)(gen).toEqualTypeOf();
37
40
  });
38
41
  it("typed request accepts compositionPlan, forceInstrumental, signWithC2pa", () => {
39
- globalExpect({
42
+ const _req = {
40
43
  model: "music_v1",
41
44
  prompt: "",
42
45
  compositionPlan: {
@@ -52,7 +55,8 @@ describe("ElevenLabsMusicGenerator Layer (compile-time)", () => {
52
55
  },
53
56
  forceInstrumental: true,
54
57
  signWithC2pa: true
55
- }).toBeDefined();
58
+ };
59
+ globalExpect(_req).toBeDefined();
56
60
  });
57
61
  });
58
62
  describe("ElevenLabsMusicGenerator codec validation (runtime, no HTTP)", () => {
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsMusicGenerator.test.mjs","names":["ElevenLabsMusicGenerator.layer","MusicGenerator"],"sources":["../src/ElevenLabsMusicGenerator.test.ts"],"sourcesContent":["import { Duration, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { FetchHttpClient } from \"effect/unstable/http\"\nimport { describe, expect, expectTypeOf, it } from \"vitest\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { GenerateResult } from \"@effect-uai/core/Music\"\nimport { promptsInput } from \"@effect-uai/core/Music\"\nimport * as MusicGenerator from \"@effect-uai/core/MusicGenerator\"\nimport * as ElevenLabsMusicGenerator from \"./ElevenLabsMusicGenerator.js\"\n\nconst cfg: ElevenLabsMusicGenerator.Config = { apiKey: Redacted.make(\"test-key\") }\nconst live = Layer.provide(ElevenLabsMusicGenerator.layer(cfg), FetchHttpClient.layer)\n\ndescribe(\"ElevenLabsMusicGenerator capability guards (runtime)\", () => {\n it(\"streamGenerationFrom returns an Unsupported stream\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n Stream.runDrain(\n s.streamGenerationFrom(Stream.fromIterable([promptsInput([{ text: \"x\" }])]), {\n model: \"music_v1\",\n prompt: \"\",\n }),\n ),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"Unsupported\")\n expect(JSON.stringify(exit.cause)).toContain(\"streamGenerationFrom\")\n }\n })\n})\n\ndescribe(\"ElevenLabsMusicGenerator Layer (compile-time)\", () => {\n it(\"leaves `MusicInteractiveSession` unsatisfied via the generic surface\", () => {\n const inputs = Stream.fromIterable([promptsInput([{ text: \"techno\" }])])\n const events = inputs.pipe(\n MusicGenerator.streamGenerationFrom({ model: \"music_v1\", prompt: \"\" }),\n )\n const provided = Stream.runDrain(events).pipe(Effect.provide(live))\n expectTypeOf(provided).toEqualTypeOf<\n Effect.Effect<void, AiError.AiError, MusicGenerator.MusicInteractiveSession>\n >()\n })\n\n it(\"sync `generate` returns GenerateResult and requires no marker\", () => {\n const gen = MusicGenerator.generate({ model: \"music_v1\", prompt: \"house\" }).pipe(\n Effect.provide(live),\n )\n expectTypeOf(gen).toEqualTypeOf<Effect.Effect<GenerateResult, AiError.AiError, never>>()\n })\n\n it(\"typed request accepts compositionPlan, forceInstrumental, signWithC2pa\", () => {\n const _req: ElevenLabsMusicGenerator.ElevenLabsMusicGenerateRequest = {\n model: \"music_v1\",\n prompt: \"\",\n compositionPlan: {\n positiveGlobalStyles: [\"lo-fi\", \"warm\"],\n negativeGlobalStyles: [\"distorted\"],\n sections: [\n {\n sectionName: \"Intro\",\n positiveLocalStyles: [\"piano\"],\n negativeLocalStyles: [],\n duration: Duration.seconds(15),\n lines: [],\n },\n ],\n },\n forceInstrumental: true,\n signWithC2pa: true,\n }\n expect(_req).toBeDefined()\n })\n})\n\ndescribe(\"ElevenLabsMusicGenerator codec validation (runtime, no HTTP)\", () => {\n it(\"rejects compositionPlan + non-empty prompt\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n s.generate({\n model: \"music_v1\",\n prompt: \"house\",\n compositionPlan: {\n positiveGlobalStyles: [],\n negativeGlobalStyles: [],\n sections: [],\n },\n }),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"InvalidRequest\")\n expect(JSON.stringify(exit.cause)).toContain(\"mutually exclusive\")\n }\n })\n\n it(\"rejects compositionPlan + duration\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n s.generate({\n model: \"music_v1\",\n prompt: \"\",\n duration: Duration.seconds(30),\n compositionPlan: {\n positiveGlobalStyles: [],\n negativeGlobalStyles: [],\n sections: [],\n },\n }),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"InvalidRequest\")\n expect(JSON.stringify(exit.cause)).toContain(\"`duration` is ignored\")\n }\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"ElevenLabsMusicGenerator.test.mjs","names":["ElevenLabsMusicGenerator.layer","MusicGenerator"],"sources":["../src/ElevenLabsMusicGenerator.test.ts"],"sourcesContent":["import { Duration, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { FetchHttpClient } from \"effect/unstable/http\"\nimport { describe, expect, expectTypeOf, it } from \"vitest\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { GenerateResult } from \"@effect-uai/core/Music\"\nimport { promptsInput } from \"@effect-uai/core/Music\"\nimport * as MusicGenerator from \"@effect-uai/core/MusicGenerator\"\nimport * as ElevenLabsMusicGenerator from \"./ElevenLabsMusicGenerator.js\"\n\nconst cfg: ElevenLabsMusicGenerator.Config = { apiKey: Redacted.make(\"test-key\") }\nconst live = Layer.provide(ElevenLabsMusicGenerator.layer(cfg), FetchHttpClient.layer)\n\ndescribe(\"ElevenLabsMusicGenerator capability guards (runtime)\", () => {\n it(\"streamGenerationFrom returns an Unsupported stream\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n Stream.runDrain(\n s.streamGenerationFrom(Stream.fromIterable([promptsInput([{ text: \"x\" }])]), {\n model: \"music_v1\",\n prompt: \"\",\n }),\n ),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"Unsupported\")\n expect(JSON.stringify(exit.cause)).toContain(\"streamGenerationFrom\")\n }\n })\n})\n\ndescribe(\"ElevenLabsMusicGenerator Layer (compile-time)\", () => {\n it(\"leaves `MusicInteractiveSession` unsatisfied via the generic surface\", () => {\n const inputs = Stream.fromIterable([promptsInput([{ text: \"techno\" }])])\n const events = inputs.pipe(\n MusicGenerator.streamGenerationFrom({ model: \"music_v1\", prompt: \"\" }),\n )\n const provided = Stream.runDrain(events).pipe(Effect.provide(live))\n expectTypeOf(provided).toEqualTypeOf<\n Effect.Effect<void, AiError.AiError, MusicGenerator.MusicInteractiveSession>\n >()\n })\n\n it(\"sync `generate` returns GenerateResult and requires no marker\", () => {\n const gen = MusicGenerator.generate({ model: \"music_v1\", prompt: \"house\" }).pipe(\n Effect.provide(live),\n )\n expectTypeOf(gen).toEqualTypeOf<Effect.Effect<GenerateResult, AiError.AiError, never>>()\n })\n\n it(\"typed request accepts compositionPlan, forceInstrumental, signWithC2pa\", () => {\n const _req: ElevenLabsMusicGenerator.ElevenLabsMusicGenerateRequest = {\n model: \"music_v1\",\n prompt: \"\",\n compositionPlan: {\n positiveGlobalStyles: [\"lo-fi\", \"warm\"],\n negativeGlobalStyles: [\"distorted\"],\n sections: [\n {\n sectionName: \"Intro\",\n positiveLocalStyles: [\"piano\"],\n negativeLocalStyles: [],\n duration: Duration.seconds(15),\n lines: [],\n },\n ],\n },\n forceInstrumental: true,\n signWithC2pa: true,\n }\n expect(_req).toBeDefined()\n })\n})\n\ndescribe(\"ElevenLabsMusicGenerator codec validation (runtime, no HTTP)\", () => {\n it(\"rejects compositionPlan + non-empty prompt\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n s.generate({\n model: \"music_v1\",\n prompt: \"house\",\n compositionPlan: {\n positiveGlobalStyles: [],\n negativeGlobalStyles: [],\n sections: [],\n },\n }),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"InvalidRequest\")\n expect(JSON.stringify(exit.cause)).toContain(\"mutually exclusive\")\n }\n })\n\n it(\"rejects compositionPlan + duration\", async () => {\n const program = ElevenLabsMusicGenerator.ElevenLabsMusicGenerator.use((s) =>\n s.generate({\n model: \"music_v1\",\n prompt: \"\",\n duration: Duration.seconds(30),\n compositionPlan: {\n positiveGlobalStyles: [],\n negativeGlobalStyles: [],\n sections: [],\n },\n }),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"InvalidRequest\")\n expect(JSON.stringify(exit.cause)).toContain(\"`duration` is ignored\")\n }\n })\n})\n"],"mappings":"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"}
@@ -6,10 +6,7 @@ import { HttpClient } from "effect/unstable/http";
6
6
  import * as AiError from "@effect-uai/core/AiError";
7
7
  import * as Socket from "effect/unstable/socket/Socket";
8
8
  import { CommonStreamSynthesizeRequest, CommonSynthesizeDialogueRequest, CommonSynthesizeRequest, MultiSpeakerTts, SpeechSynthesizer, SpeechSynthesizerService, TtsIncrementalText } from "@effect-uai/core/SpeechSynthesizer";
9
- import * as _$_effect_uai_core_Audio0 from "@effect-uai/core/Audio";
10
9
  import { AudioBlob, AudioChunk } from "@effect-uai/core/Audio";
11
-
12
- //#region src/ElevenLabsSynthesizer.d.ts
13
10
  declare namespace ElevenLabsSynthesizer_d_exports {
14
11
  export { Config, ElevenLabsSynthesizeRequest, ElevenLabsSynthesizer, ElevenLabsSynthesizerService, layer, make };
15
12
  }
@@ -49,13 +46,13 @@ type Config = {
49
46
  };
50
47
  declare const make: (cfg: Config) => Effect.Effect<{
51
48
  synthesize: (r: ElevenLabsSynthesizeRequest) => Effect.Effect<{
52
- format: _$_effect_uai_core_Audio0.AudioFormat;
49
+ format: import("@effect-uai/core/Audio").AudioFormat;
53
50
  bytes: Uint8Array<ArrayBuffer>;
54
51
  }, AiError.AiError, never>;
55
52
  streamSynthesis: (r: ElevenLabsSynthesizeRequest) => Stream.Stream<AudioChunk, AiError.AiError, never>;
56
- streamSynthesisFrom: <E, R>(textIn: Stream.Stream<string, E, R>, request: CommonStreamSynthesizeRequest) => Stream.Stream<AudioChunk, AiError.AiError | E, Exclude<R, Socket.WebSocketConstructor>>;
53
+ streamSynthesisFrom: <E, R>(textIn: Stream.Stream<string, E, R>, request: CommonStreamSynthesizeRequest) => Stream.Stream<AudioChunk, E | AiError.AiError, Exclude<R, Socket.WebSocketConstructor>>;
57
54
  synthesizeDialogue: (request: CommonSynthesizeDialogueRequest) => Effect.Effect<{
58
- format: _$_effect_uai_core_Audio0.AudioFormat;
55
+ format: import("@effect-uai/core/Audio").AudioFormat;
59
56
  bytes: Uint8Array<ArrayBuffer>;
60
57
  }, AiError.AiError, never>;
61
58
  streamSynthesizeDialogue: (request: CommonSynthesizeDialogueRequest) => Stream.Stream<AudioChunk, AiError.AiError, never>;
@@ -69,7 +66,7 @@ declare const make: (cfg: Config) => Effect.Effect<{
69
66
  * `Socket.layerWebSocketConstructorGlobal` and an `HttpClient` Layer
70
67
  * at the call site.
71
68
  */
72
- declare const layer: (cfg: Config) => Layer.Layer<ElevenLabsSynthesizer | SpeechSynthesizer | TtsIncrementalText | MultiSpeakerTts, never, HttpClient.HttpClient | Socket.WebSocketConstructor>;
69
+ declare const layer: (cfg: Config) => Layer.Layer<ElevenLabsSynthesizer | MultiSpeakerTts | SpeechSynthesizer | TtsIncrementalText, never, HttpClient.HttpClient | Socket.WebSocketConstructor>;
73
70
  //#endregion
74
71
  export { Config, ElevenLabsSynthesizeRequest, ElevenLabsSynthesizer, ElevenLabsSynthesizerService, layer, make, ElevenLabsSynthesizer_d_exports as t };
75
72
  //# sourceMappingURL=ElevenLabsSynthesizer.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsSynthesizer.d.mts","names":[],"sources":["../src/ElevenLabsSynthesizer.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;KA4CY,2BAAA,GAA8B,IAAA,CAAK,uBAAA;EAAA,SACpC,KAAA,EAAO,kBAAA;EAAA,SACP,OAAA,EAAS,iBAAA;EAAA,SACT,aAAA,GAAgB,aAAA;EAAA,SAChB,IAAA;EAAA,SACA,YAAA;EAAA,SACA,QAAA;EAAA,SACA,+BAAA,GAAkC,aAAA,CAAc,8BAAA;AAAA;AAAA,KAG/C,4BAAA;EAAA,SACD,UAAA,GAAa,CAAA,EAAG,2BAAA,KAAgC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,CAAQ,OAAA;EAAA,SACjF,eAAA,GACP,CAAA,EAAG,2BAAA,KACA,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,OAAA;EAAA,SAC9B,mBAAA,EAAqB,wBAAA;EAAA,SACrB,kBAAA,EAAoB,wBAAA;EAAA,SACpB,wBAAA,EAA0B,wBAAA;AAAA;AAAA,cACpC,0BAAA;cAEY,qBAAA,SAA8B,0BAAA;AAAA,KAK/B,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;EAAA,SACA,MAAA,GAAS,gBAAA;AAAA;AAAA,cAqIP,IAAA,GAAQ,GAAA,EAAK,MAAA,KAAM,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;cAiCnB,KAAA,GAAS,GAAA,EAAK,MAAA,KAAM,KAAA,CAAA,KAAA,CAAA,qBAAA,GAAA,iBAAA,GAAA,kBAAA,GAAA,eAAA,SAAA,UAAA,CAAA,UAAA,GAAA,MAAA,CAAA,oBAAA"}
1
+ {"version":3,"file":"ElevenLabsSynthesizer.d.mts","names":[],"sources":["../src/ElevenLabsSynthesizer.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;KA4CY,8BAA8B,KAAK;WACpC,OAAO;WACP,SAAS;WACT,gBAAgB;WAChB;WACA;WACA;WACA,kCAAkC,cAAc;;KAG/C;WACD,aAAa,GAAG,gCAAgC,OAAO,OAAO,WAAW,QAAQ;WACjF,kBACP,GAAG,gCACA,OAAO,OAAO,YAAY,QAAQ;WAC9B,qBAAqB;WACrB,oBAAoB;WACpB,0BAA0B;;;cAGxB,8BAA8B;KAK/B;WACD,QAAQ,SAAS;WACjB;WACA,SAAS;;cAqIP,OAAI,KAAS,WAAM,OAAA;;;;;;;;;;;;UAsB5B,WAAA,aAAA,OAAA;;;;;;;;;;cAWS,QAAK,KAAS,WAAM,MAAA,MAAA,wBAAA,kBAAA,oBAAA,2BAAA,WAAA,aAAA,OAAA"}
@@ -1,4 +1,4 @@
1
- import { n as __exportAll } from "./chunk-uyGKjUfl.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.mjs";
2
2
  import { defaultFormat, formatToOutputSlug, httpStatusError, rejectInlinePronunciations, transportFailure, wirePronunciationLocators, wireVoiceSettings } from "./codec.mjs";
3
3
  import { resolveHost } from "./region.mjs";
4
4
  import { streamSynthesis } from "./realtimeTts.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsSynthesizer.mjs","names":["realtimeStream"],"sources":["../src/ElevenLabsSynthesizer.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { AudioBlob, AudioChunk } from \"@effect-uai/core/Audio\"\nimport {\n type CommonStreamSynthesizeRequest,\n type CommonSynthesizeDialogueRequest,\n type CommonSynthesizeRequest,\n MultiSpeakerTts,\n SpeechSynthesizer,\n type SpeechSynthesizerService,\n TtsIncrementalText,\n} from \"@effect-uai/core/SpeechSynthesizer\"\nimport {\n defaultFormat,\n formatToOutputSlug,\n httpStatusError,\n type PronunciationDictionaryLocator,\n rejectInlinePronunciations,\n transportFailure,\n type VoiceSettings,\n wirePronunciationLocators,\n wireVoiceSettings,\n} from \"./codec.js\"\nimport type { ElevenLabsTtsModel, ElevenLabsVoiceId } from \"./models.js\"\nimport { streamSynthesis as realtimeStream } from \"./realtimeTts.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed synthesize request. `voiceSettings` exposes the\n * provider's prosody/timbre controls; `seed` makes generation\n * deterministic; `previousText` / `nextText` thread context across\n * sequential calls for natural prosody.\n *\n * `pronunciationDictionaryLocators` references pre-provisioned\n * pronunciation dictionaries by ID. Inline `pronunciations` (IPA) on\n * the Common request are not supported by ElevenLabs and fail\n * `Unsupported`; use a dictionary for phonetic control.\n */\nexport type ElevenLabsSynthesizeRequest = Omit<CommonSynthesizeRequest, \"model\" | \"voiceId\"> & {\n readonly model: ElevenLabsTtsModel\n readonly voiceId: ElevenLabsVoiceId\n readonly voiceSettings?: VoiceSettings\n readonly seed?: number\n readonly previousText?: string\n readonly nextText?: string\n readonly pronunciationDictionaryLocators?: ReadonlyArray<PronunciationDictionaryLocator>\n}\n\nexport type ElevenLabsSynthesizerService = {\n readonly synthesize: (r: ElevenLabsSynthesizeRequest) => Effect.Effect<AudioBlob, AiError.AiError>\n readonly streamSynthesis: (\n r: ElevenLabsSynthesizeRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError>\n readonly streamSynthesisFrom: SpeechSynthesizerService[\"streamSynthesisFrom\"]\n readonly synthesizeDialogue: SpeechSynthesizerService[\"synthesizeDialogue\"]\n readonly streamSynthesizeDialogue: SpeechSynthesizerService[\"streamSynthesizeDialogue\"]\n}\n\nexport class ElevenLabsSynthesizer extends Context.Service<\n ElevenLabsSynthesizer,\n ElevenLabsSynthesizerService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsSynthesizer\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\n// ---------------------------------------------------------------------------\n// Codec — request → JSON body\n// ---------------------------------------------------------------------------\n\nconst buildBody = (r: ElevenLabsSynthesizeRequest) => ({\n text: r.text,\n model_id: r.model,\n ...(r.languageCode !== undefined && { language_code: r.languageCode }),\n ...(r.seed !== undefined && { seed: r.seed }),\n ...(r.previousText !== undefined && { previous_text: r.previousText }),\n ...(r.nextText !== undefined && { next_text: r.nextText }),\n ...wirePronunciationLocators(r.pronunciationDictionaryLocators),\n ...(r.voiceSettings !== undefined && { voice_settings: wireVoiceSettings(r.voiceSettings) }),\n})\n\n// ---------------------------------------------------------------------------\n// Dialogue — POST /v1/text-to-dialogue (+ /stream variant)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_DIALOGUE_MODEL = \"eleven_v3\"\n\nconst buildDialogueBody = (r: CommonSynthesizeDialogueRequest) => ({\n inputs: r.turns.map((t) => ({\n voice_id: t.voiceId,\n text: t.text,\n })),\n model_id: r.model ?? DEFAULT_DIALOGUE_MODEL,\n ...(r.languageCode !== undefined && { language_code: r.languageCode }),\n})\n\nconst buildDialogueHttpRequest = (\n cfg: Config,\n r: CommonSynthesizeDialogueRequest,\n path: \"\" | \"/stream\",\n) =>\n Effect.gen(function* () {\n const format = r.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const url = `${resolveHost(cfg)}/text-to-dialogue${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(buildDialogueBody(r)),\n )\n return { httpRequest, format }\n })\n\nconst synthesizeDialogueImpl = (cfg: Config) => (request: CommonSynthesizeDialogueRequest) =>\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildDialogueHttpRequest(cfg, request, \"\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const bytes = yield* response.arrayBuffer.pipe(Effect.mapError(transportFailure))\n return { format, bytes: new Uint8Array(bytes) } satisfies AudioBlob\n })\n\nconst streamSynthesizeDialogueImpl = (cfg: Config) => (request: CommonSynthesizeDialogueRequest) =>\n Stream.unwrap(\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildDialogueHttpRequest(cfg, request, \"/stream\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(transportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n// ---------------------------------------------------------------------------\n// HTTP plumbing (sync + chunked-HTTP streaming)\n// ---------------------------------------------------------------------------\n\nconst buildHttpRequest = (cfg: Config, r: ElevenLabsSynthesizeRequest, path: \"\" | \"/stream\") =>\n Effect.gen(function* () {\n const format = r.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const url = `${resolveHost(cfg)}/text-to-speech/${r.voiceId}${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(buildBody(r)),\n )\n return { httpRequest, format }\n })\n\nconst synthesizeImpl = (cfg: Config) => (request: ElevenLabsSynthesizeRequest) =>\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildHttpRequest(cfg, request, \"\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const bytes = yield* response.arrayBuffer.pipe(Effect.mapError(transportFailure))\n return { format, bytes: new Uint8Array(bytes) } satisfies AudioBlob\n })\n\nconst streamSynthesisImpl = (cfg: Config) => (request: ElevenLabsSynthesizeRequest) =>\n Stream.unwrap(\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildHttpRequest(cfg, request, \"/stream\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(transportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (cfg: Config) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const ctor = yield* Socket.WebSocketConstructor\n return {\n synthesize: (r) =>\n synthesizeImpl(cfg)(r).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamSynthesis: (r) =>\n streamSynthesisImpl(cfg)(r).pipe(Stream.provideService(HttpClient.HttpClient, client)),\n streamSynthesisFrom: (textIn, request) =>\n realtimeStream(cfg)(textIn, request as ElevenLabsSynthesizeRequest).pipe(\n Stream.provideService(Socket.WebSocketConstructor, ctor),\n ),\n synthesizeDialogue: (request) =>\n synthesizeDialogueImpl(cfg)(request).pipe(\n Effect.provideService(HttpClient.HttpClient, client),\n ),\n streamSynthesizeDialogue: (request) =>\n streamSynthesizeDialogueImpl(cfg)(request).pipe(\n Stream.provideService(HttpClient.HttpClient, client),\n ),\n } satisfies ElevenLabsSynthesizerService\n })\n\n/**\n * Layer registers `ElevenLabsSynthesizer`, the generic\n * `SpeechSynthesizer`, the `TtsIncrementalText` marker (incremental\n * text-in via `/stream-input` WebSocket), **and `MultiSpeakerTts`** —\n * multi-speaker dialogue is wired to `POST /v1/text-to-dialogue`\n * (sync) and `/v1/text-to-dialogue/stream` (chunked). Provide\n * `Socket.layerWebSocketConstructorGlobal` and an `HttpClient` Layer\n * at the call site.\n */\nexport const layer = (cfg: Config) =>\n Layer.mergeAll(\n Layer.effect(ElevenLabsSynthesizer, make(cfg)),\n Layer.effect(\n SpeechSynthesizer,\n Effect.map(\n make(cfg),\n (s): SpeechSynthesizerService => ({\n synthesize: (req: CommonSynthesizeRequest) =>\n s.synthesize(req as ElevenLabsSynthesizeRequest),\n streamSynthesis: (req: CommonSynthesizeRequest) =>\n s.streamSynthesis(req as ElevenLabsSynthesizeRequest),\n streamSynthesisFrom: (textIn, req: CommonStreamSynthesizeRequest) =>\n s.streamSynthesisFrom(textIn, req),\n synthesizeDialogue: s.synthesizeDialogue,\n streamSynthesizeDialogue: s.streamSynthesizeDialogue,\n }),\n ),\n ),\n Layer.succeed(TtsIncrementalText, undefined),\n Layer.succeed(MultiSpeakerTts, undefined),\n )\n"],"mappings":"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"}
1
+ {"version":3,"file":"ElevenLabsSynthesizer.mjs","names":["realtimeStream"],"sources":["../src/ElevenLabsSynthesizer.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { AudioBlob, AudioChunk } from \"@effect-uai/core/Audio\"\nimport {\n type CommonStreamSynthesizeRequest,\n type CommonSynthesizeDialogueRequest,\n type CommonSynthesizeRequest,\n MultiSpeakerTts,\n SpeechSynthesizer,\n type SpeechSynthesizerService,\n TtsIncrementalText,\n} from \"@effect-uai/core/SpeechSynthesizer\"\nimport {\n defaultFormat,\n formatToOutputSlug,\n httpStatusError,\n type PronunciationDictionaryLocator,\n rejectInlinePronunciations,\n transportFailure,\n type VoiceSettings,\n wirePronunciationLocators,\n wireVoiceSettings,\n} from \"./codec.js\"\nimport type { ElevenLabsTtsModel, ElevenLabsVoiceId } from \"./models.js\"\nimport { streamSynthesis as realtimeStream } from \"./realtimeTts.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed synthesize request. `voiceSettings` exposes the\n * provider's prosody/timbre controls; `seed` makes generation\n * deterministic; `previousText` / `nextText` thread context across\n * sequential calls for natural prosody.\n *\n * `pronunciationDictionaryLocators` references pre-provisioned\n * pronunciation dictionaries by ID. Inline `pronunciations` (IPA) on\n * the Common request are not supported by ElevenLabs and fail\n * `Unsupported`; use a dictionary for phonetic control.\n */\nexport type ElevenLabsSynthesizeRequest = Omit<CommonSynthesizeRequest, \"model\" | \"voiceId\"> & {\n readonly model: ElevenLabsTtsModel\n readonly voiceId: ElevenLabsVoiceId\n readonly voiceSettings?: VoiceSettings\n readonly seed?: number\n readonly previousText?: string\n readonly nextText?: string\n readonly pronunciationDictionaryLocators?: ReadonlyArray<PronunciationDictionaryLocator>\n}\n\nexport type ElevenLabsSynthesizerService = {\n readonly synthesize: (r: ElevenLabsSynthesizeRequest) => Effect.Effect<AudioBlob, AiError.AiError>\n readonly streamSynthesis: (\n r: ElevenLabsSynthesizeRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError>\n readonly streamSynthesisFrom: SpeechSynthesizerService[\"streamSynthesisFrom\"]\n readonly synthesizeDialogue: SpeechSynthesizerService[\"synthesizeDialogue\"]\n readonly streamSynthesizeDialogue: SpeechSynthesizerService[\"streamSynthesizeDialogue\"]\n}\n\nexport class ElevenLabsSynthesizer extends Context.Service<\n ElevenLabsSynthesizer,\n ElevenLabsSynthesizerService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsSynthesizer\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\n// ---------------------------------------------------------------------------\n// Codec — request → JSON body\n// ---------------------------------------------------------------------------\n\nconst buildBody = (r: ElevenLabsSynthesizeRequest) => ({\n text: r.text,\n model_id: r.model,\n ...(r.languageCode !== undefined && { language_code: r.languageCode }),\n ...(r.seed !== undefined && { seed: r.seed }),\n ...(r.previousText !== undefined && { previous_text: r.previousText }),\n ...(r.nextText !== undefined && { next_text: r.nextText }),\n ...wirePronunciationLocators(r.pronunciationDictionaryLocators),\n ...(r.voiceSettings !== undefined && { voice_settings: wireVoiceSettings(r.voiceSettings) }),\n})\n\n// ---------------------------------------------------------------------------\n// Dialogue — POST /v1/text-to-dialogue (+ /stream variant)\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_DIALOGUE_MODEL = \"eleven_v3\"\n\nconst buildDialogueBody = (r: CommonSynthesizeDialogueRequest) => ({\n inputs: r.turns.map((t) => ({\n voice_id: t.voiceId,\n text: t.text,\n })),\n model_id: r.model ?? DEFAULT_DIALOGUE_MODEL,\n ...(r.languageCode !== undefined && { language_code: r.languageCode }),\n})\n\nconst buildDialogueHttpRequest = (\n cfg: Config,\n r: CommonSynthesizeDialogueRequest,\n path: \"\" | \"/stream\",\n) =>\n Effect.gen(function* () {\n const format = r.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const url = `${resolveHost(cfg)}/text-to-dialogue${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(buildDialogueBody(r)),\n )\n return { httpRequest, format }\n })\n\nconst synthesizeDialogueImpl = (cfg: Config) => (request: CommonSynthesizeDialogueRequest) =>\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildDialogueHttpRequest(cfg, request, \"\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const bytes = yield* response.arrayBuffer.pipe(Effect.mapError(transportFailure))\n return { format, bytes: new Uint8Array(bytes) } satisfies AudioBlob\n })\n\nconst streamSynthesizeDialogueImpl = (cfg: Config) => (request: CommonSynthesizeDialogueRequest) =>\n Stream.unwrap(\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildDialogueHttpRequest(cfg, request, \"/stream\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(transportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n// ---------------------------------------------------------------------------\n// HTTP plumbing (sync + chunked-HTTP streaming)\n// ---------------------------------------------------------------------------\n\nconst buildHttpRequest = (cfg: Config, r: ElevenLabsSynthesizeRequest, path: \"\" | \"/stream\") =>\n Effect.gen(function* () {\n const format = r.outputFormat ?? defaultFormat\n const slug = yield* formatToOutputSlug(format)\n const url = `${resolveHost(cfg)}/text-to-speech/${r.voiceId}${path}?output_format=${slug}`\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyJsonUnsafe(buildBody(r)),\n )\n return { httpRequest, format }\n })\n\nconst synthesizeImpl = (cfg: Config) => (request: ElevenLabsSynthesizeRequest) =>\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest, format } = yield* buildHttpRequest(cfg, request, \"\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const bytes = yield* response.arrayBuffer.pipe(Effect.mapError(transportFailure))\n return { format, bytes: new Uint8Array(bytes) } satisfies AudioBlob\n })\n\nconst streamSynthesisImpl = (cfg: Config) => (request: ElevenLabsSynthesizeRequest) =>\n Stream.unwrap(\n Effect.gen(function* () {\n yield* rejectInlinePronunciations(request.pronunciations)\n const client = yield* HttpClient.HttpClient\n const { httpRequest } = yield* buildHttpRequest(cfg, request, \"/stream\")\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n return response.stream.pipe(\n Stream.mapError(transportFailure),\n Stream.map((bytes): AudioChunk => ({ bytes })),\n )\n }),\n )\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (cfg: Config) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const ctor = yield* Socket.WebSocketConstructor\n return {\n synthesize: (r) =>\n synthesizeImpl(cfg)(r).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamSynthesis: (r) =>\n streamSynthesisImpl(cfg)(r).pipe(Stream.provideService(HttpClient.HttpClient, client)),\n streamSynthesisFrom: (textIn, request) =>\n realtimeStream(cfg)(textIn, request as ElevenLabsSynthesizeRequest).pipe(\n Stream.provideService(Socket.WebSocketConstructor, ctor),\n ),\n synthesizeDialogue: (request) =>\n synthesizeDialogueImpl(cfg)(request).pipe(\n Effect.provideService(HttpClient.HttpClient, client),\n ),\n streamSynthesizeDialogue: (request) =>\n streamSynthesizeDialogueImpl(cfg)(request).pipe(\n Stream.provideService(HttpClient.HttpClient, client),\n ),\n } satisfies ElevenLabsSynthesizerService\n })\n\n/**\n * Layer registers `ElevenLabsSynthesizer`, the generic\n * `SpeechSynthesizer`, the `TtsIncrementalText` marker (incremental\n * text-in via `/stream-input` WebSocket), **and `MultiSpeakerTts`** —\n * multi-speaker dialogue is wired to `POST /v1/text-to-dialogue`\n * (sync) and `/v1/text-to-dialogue/stream` (chunked). Provide\n * `Socket.layerWebSocketConstructorGlobal` and an `HttpClient` Layer\n * at the call site.\n */\nexport const layer = (cfg: Config) =>\n Layer.mergeAll(\n Layer.effect(ElevenLabsSynthesizer, make(cfg)),\n Layer.effect(\n SpeechSynthesizer,\n Effect.map(make(cfg), (s): SpeechSynthesizerService => ({\n synthesize: (req: CommonSynthesizeRequest) =>\n s.synthesize(req as ElevenLabsSynthesizeRequest),\n streamSynthesis: (req: CommonSynthesizeRequest) =>\n s.streamSynthesis(req as ElevenLabsSynthesizeRequest),\n streamSynthesisFrom: (textIn, req: CommonStreamSynthesizeRequest) =>\n s.streamSynthesisFrom(textIn, req),\n synthesizeDialogue: s.synthesizeDialogue,\n streamSynthesizeDialogue: s.streamSynthesizeDialogue,\n })),\n ),\n Layer.succeed(TtsIncrementalText, undefined),\n Layer.succeed(MultiSpeakerTts, undefined),\n )\n"],"mappings":"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"}
@@ -4,12 +4,8 @@ import { Context, Effect, Layer, Redacted, Schema, Stream } from "effect";
4
4
  import { HttpClient } from "effect/unstable/http";
5
5
  import * as AiError from "@effect-uai/core/AiError";
6
6
  import * as Socket from "effect/unstable/socket/Socket";
7
- import * as _$_effect_uai_core_Transcriber0 from "@effect-uai/core/Transcriber";
8
7
  import { CommonTranscribeRequest, SttStreaming, Transcriber, TranscriberService } from "@effect-uai/core/Transcriber";
9
- import * as _$_effect_uai_core_Transcript0 from "@effect-uai/core/Transcript";
10
8
  import { TranscriptResult, WordTimestamp } from "@effect-uai/core/Transcript";
11
-
12
- //#region src/ElevenLabsTranscriber.d.ts
13
9
  declare namespace ElevenLabsTranscriber_d_exports {
14
10
  export { Config, ElevenLabsTranscribeRequest, ElevenLabsTranscriber, ElevenLabsTranscriberService, layer, make };
15
11
  }
@@ -39,12 +35,12 @@ type Config = {
39
35
  };
40
36
  declare const make: (cfg: Config) => Effect.Effect<{
41
37
  transcribe: (r: ElevenLabsTranscribeRequest) => Effect.Effect<{
42
- raw: Schema.Json;
43
- words?: WordTimestamp[];
44
- languageCode?: string;
45
38
  text: string;
39
+ languageCode?: string;
40
+ words?: WordTimestamp[];
41
+ raw: Schema.Json;
46
42
  }, AiError.AiError, never>;
47
- streamTranscriptionFrom: <E, R>(audioIn: Stream.Stream<Uint8Array<ArrayBufferLike>, E, R>, request: _$_effect_uai_core_Transcriber0.CommonStreamTranscribeRequest) => Stream.Stream<_$_effect_uai_core_Transcript0.TranscriptEvent, AiError.AiError | E, Exclude<Exclude<R, HttpClient.HttpClient>, Socket.WebSocketConstructor>>;
43
+ streamTranscriptionFrom: <E, R>(audioIn: Stream.Stream<Uint8Array<ArrayBufferLike>, E, R>, request: import("@effect-uai/core/Transcriber").CommonStreamTranscribeRequest) => Stream.Stream<import("@effect-uai/core/Transcript").TranscriptEvent, E | AiError.AiError, Exclude<Exclude<R, HttpClient.HttpClient>, Socket.WebSocketConstructor>>;
48
44
  }, never, HttpClient.HttpClient | Socket.WebSocketConstructor>;
49
45
  /**
50
46
  * Layer registers `ElevenLabsTranscriber`, the generic `Transcriber`,
@@ -53,7 +49,7 @@ declare const make: (cfg: Config) => Effect.Effect<{
53
49
  * `Socket.layerWebSocketConstructorGlobal` (or a custom constructor) +
54
50
  * an `HttpClient` Layer at the call site.
55
51
  */
56
- declare const layer: (cfg: Config) => Layer.Layer<ElevenLabsTranscriber | Transcriber | SttStreaming, never, HttpClient.HttpClient | Socket.WebSocketConstructor>;
52
+ declare const layer: (cfg: Config) => Layer.Layer<ElevenLabsTranscriber | SttStreaming | Transcriber, never, HttpClient.HttpClient | Socket.WebSocketConstructor>;
57
53
  //#endregion
58
54
  export { Config, ElevenLabsTranscribeRequest, ElevenLabsTranscriber, ElevenLabsTranscriberService, layer, make, ElevenLabsTranscriber_d_exports as t };
59
55
  //# sourceMappingURL=ElevenLabsTranscriber.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsTranscriber.d.mts","names":[],"sources":["../src/ElevenLabsTranscriber.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;KA4BY,2BAAA,GAA8B,IAAA,CAAK,uBAAA;EAAA,SACpC,KAAA,EAAO,kBAAA;EAAA,SACP,WAAA;EAAA,SACA,WAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,4BAAA;EAAA,SACD,UAAA,GACP,CAAA,EAAG,2BAAA,KACA,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,OAAA,CAAQ,OAAA;EAAA,SACpC,uBAAA,EAAyB,kBAAA;AAAA;AAAA,cACnC,0BAAA;cAEY,qBAAA,SAA8B,0BAAA;AAAA,KAK/B,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;EAAA,SACA,MAAA,GAAS,gBAAA;AAAA;AAAA,cAyGP,IAAA,GAAQ,GAAA,EAAK,MAAA,KAAM,MAAA,CAAA,MAAA;;;;;;;;;;;;;;;;cAsBnB,KAAA,GAAS,GAAA,EAAK,MAAA,KAAM,KAAA,CAAA,KAAA,CAAA,qBAAA,GAAA,WAAA,GAAA,YAAA,SAAA,UAAA,CAAA,UAAA,GAAA,MAAA,CAAA,oBAAA"}
1
+ {"version":3,"file":"ElevenLabsTranscriber.d.mts","names":[],"sources":["../src/ElevenLabsTranscriber.ts"],"mappings":";;;;;;;;;;;;;;;;;;KA4BY,8BAA8B,KAAK;WACpC,OAAO;WACP;WACA;WACA;;KAGC;WACD,aACP,GAAG,gCACA,OAAO,OAAO,kBAAkB,QAAQ;WACpC,yBAAyB;;;cAGvB,8BAA8B;KAK/B;WACD,QAAQ,SAAS;WACjB;WACA,SAAS;;cAyGP,OAAI,KAAS,WAAM,OAAA;;;;;;;;UAa5B,WAAA,aAAA,OAAA;;;;;;;;cASS,QAAK,KAAS,WAAM,MAAA,MAAA,wBAAA,eAAA,oBAAA,WAAA,aAAA,OAAA"}
@@ -1,4 +1,4 @@
1
- import { n as __exportAll } from "./chunk-uyGKjUfl.mjs";
1
+ import { n as __exportAll } from "./rolldown-runtime-EAsCxrDo.mjs";
2
2
  import { audioToBlob, defaultFileName, httpStatusError, transportFailure } from "./codec.mjs";
3
3
  import { resolveHost } from "./region.mjs";
4
4
  import { streamTranscription } from "./realtimeStt.mjs";
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsTranscriber.mjs","names":[],"sources":["../src/ElevenLabsTranscriber.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted, Schema, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport * as Capabilities from \"@effect-uai/core/Capabilities\"\nimport type { TranscriptResult, WordTimestamp } from \"@effect-uai/core/Transcript\"\nimport {\n type CommonTranscribeRequest,\n SttStreaming,\n Transcriber,\n type TranscriberService,\n} from \"@effect-uai/core/Transcriber\"\nimport { audioToBlob, defaultFileName, httpStatusError, transportFailure } from \"./codec.js\"\nimport type { ElevenLabsSttModel } from \"./models.js\"\nimport { streamTranscription } from \"./realtimeStt.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed transcribe request. `model` narrows to\n * `ElevenLabsSttModel`. `numSpeakers` hints diarization. `audioEvents`\n * surfaces `(laughter)` / `(music)` tags inline in `text` (provider\n * default: true). `fileName` overrides the multipart upload's\n * `filename`; ElevenLabs uses the extension to detect format.\n */\nexport type ElevenLabsTranscribeRequest = Omit<CommonTranscribeRequest, \"model\"> & {\n readonly model: ElevenLabsSttModel\n readonly numSpeakers?: number\n readonly audioEvents?: boolean\n readonly fileName?: string\n}\n\nexport type ElevenLabsTranscriberService = {\n readonly transcribe: (\n r: ElevenLabsTranscribeRequest,\n ) => Effect.Effect<TranscriptResult, AiError.AiError>\n readonly streamTranscriptionFrom: TranscriberService[\"streamTranscriptionFrom\"]\n}\n\nexport class ElevenLabsTranscriber extends Context.Service<\n ElevenLabsTranscriber,\n ElevenLabsTranscriberService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsTranscriber\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\n// ---------------------------------------------------------------------------\n// Response schema\n// ---------------------------------------------------------------------------\n\nconst Word = Schema.Struct({\n text: Schema.String,\n start: Schema.optional(Schema.Number),\n end: Schema.optional(Schema.Number),\n type: Schema.optional(Schema.String),\n speaker_id: Schema.optional(Schema.String),\n logprob: Schema.optional(Schema.Number),\n})\n\nconst Wire = Schema.Struct({\n text: Schema.String,\n language_code: Schema.optional(Schema.String),\n language_probability: Schema.optional(Schema.Number),\n words: Schema.optional(Schema.Array(Word)),\n transcription_id: Schema.optional(Schema.String),\n})\nconst decodeWire = Schema.decodeUnknownEffect(Wire)\n\nconst toWordTimestamp = (w: typeof Word.Type): WordTimestamp | undefined =>\n w.start === undefined || w.end === undefined\n ? undefined\n : {\n text: w.text,\n startSeconds: w.start,\n endSeconds: w.end,\n ...(w.logprob !== undefined && { confidence: Math.exp(w.logprob) }),\n ...(w.speaker_id !== undefined && { speakerId: w.speaker_id }),\n }\n\n// ---------------------------------------------------------------------------\n// Multipart body\n// ---------------------------------------------------------------------------\n\nconst buildForm = (request: ElevenLabsTranscribeRequest) =>\n Effect.gen(function* () {\n const blob = yield* audioToBlob(request.audio)\n const fileName = request.fileName ?? defaultFileName(request.audio.mimeType ?? \"\")\n const form = new FormData()\n form.set(\"model_id\", request.model)\n form.set(\"file\", blob, fileName)\n if (request.language !== undefined) form.set(\"language_code\", request.language)\n if (request.diarization !== undefined)\n form.set(\"diarize\", request.diarization ? \"true\" : \"false\")\n if (request.wordTimestamps === true) form.set(\"timestamps_granularity\", \"word\")\n if (request.numSpeakers !== undefined) form.set(\"num_speakers\", String(request.numSpeakers))\n if (request.audioEvents !== undefined)\n form.set(\"tag_audio_events\", request.audioEvents ? \"true\" : \"false\")\n // Vocab biasing → Scribe `keyterms` (≤1000 terms, ≤50 chars). Each\n // term is a repeated form field (`keyterms=a&keyterms=b`), matching\n // the ElevenLabs SDK. Scribe has no free-form prompt field.\n for (const term of request.biasingTerms ?? []) form.append(\"keyterms\", term)\n yield* Capabilities.warnDroppedWhen(request.prompt, {\n provider: \"elevenlabs\",\n capability: \"prompt\",\n field: \"prompt\",\n reason: \"ElevenLabs Scribe has no free-form prompt field; bias via `biasingTerms`.\",\n })\n return form\n })\n\n// ---------------------------------------------------------------------------\n// HTTP plumbing\n// ---------------------------------------------------------------------------\n\nconst transcribeImpl = (cfg: Config) => (request: ElevenLabsTranscribeRequest) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const form = yield* buildForm(request)\n const httpRequest = HttpClientRequest.post(`${resolveHost(cfg)}/speech-to-text`).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyFormData(form),\n )\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const json = yield* response.json.pipe(Effect.mapError(transportFailure))\n const wire = yield* decodeWire(json).pipe(\n Effect.mapError(\n (cause) => new AiError.GenerationFailed({ provider: \"elevenlabs\", raw: cause }),\n ),\n )\n const words = wire.words\n ?.map(toWordTimestamp)\n .filter((w): w is WordTimestamp => w !== undefined)\n return {\n text: wire.text,\n ...(wire.language_code !== undefined && { languageCode: wire.language_code }),\n ...(words !== undefined && words.length > 0 && { words }),\n raw: json,\n } satisfies TranscriptResult\n })\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (cfg: Config) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const ctor = yield* Socket.WebSocketConstructor\n return {\n transcribe: (r) =>\n transcribeImpl(cfg)(r).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamTranscriptionFrom: (audioIn, request) =>\n streamTranscription(cfg)(audioIn, request).pipe(\n Stream.provideService(HttpClient.HttpClient, client),\n Stream.provideService(Socket.WebSocketConstructor, ctor),\n ),\n } satisfies ElevenLabsTranscriberService\n })\n\n/**\n * Layer registers `ElevenLabsTranscriber`, the generic `Transcriber`,\n * **and the `SttStreaming` capability marker** — `streamTranscriptionFrom`\n * is wired to the realtime WebSocket. Provide\n * `Socket.layerWebSocketConstructorGlobal` (or a custom constructor) +\n * an `HttpClient` Layer at the call site.\n */\nexport const layer = (cfg: Config) =>\n Layer.mergeAll(\n Layer.effect(ElevenLabsTranscriber, make(cfg)),\n Layer.effect(\n Transcriber,\n Effect.map(\n make(cfg),\n (s): TranscriberService => ({\n transcribe: (req: CommonTranscribeRequest) =>\n s.transcribe(req as ElevenLabsTranscribeRequest),\n streamTranscriptionFrom: s.streamTranscriptionFrom,\n }),\n ),\n ),\n Layer.succeed(SttStreaming, undefined),\n )\n"],"mappings":";;;;;;;;;;;;;;;;AA0CA,IAAa,wBAAb,cAA2C,QAAQ,SAGhD,CAAC,kEAAkE,CAAC;AAYvE,MAAM,OAAO,OAAO,OAAO;CACzB,MAAM,OAAO;CACb,OAAO,OAAO,SAAS,OAAO,OAAO;CACrC,KAAK,OAAO,SAAS,OAAO,OAAO;CACnC,MAAM,OAAO,SAAS,OAAO,OAAO;CACpC,YAAY,OAAO,SAAS,OAAO,OAAO;CAC1C,SAAS,OAAO,SAAS,OAAO,OAAO;CACxC,CAAC;AAEF,MAAM,OAAO,OAAO,OAAO;CACzB,MAAM,OAAO;CACb,eAAe,OAAO,SAAS,OAAO,OAAO;CAC7C,sBAAsB,OAAO,SAAS,OAAO,OAAO;CACpD,OAAO,OAAO,SAAS,OAAO,MAAM,KAAK,CAAC;CAC1C,kBAAkB,OAAO,SAAS,OAAO,OAAO;CACjD,CAAC;AACF,MAAM,aAAa,OAAO,oBAAoB,KAAK;AAEnD,MAAM,mBAAmB,MACvB,EAAE,UAAU,KAAA,KAAa,EAAE,QAAQ,KAAA,IAC/B,KAAA,IACA;CACE,MAAM,EAAE;CACR,cAAc,EAAE;CAChB,YAAY,EAAE;CACd,GAAI,EAAE,YAAY,KAAA,KAAa,EAAE,YAAY,KAAK,IAAI,EAAE,QAAQ,EAAE;CAClE,GAAI,EAAE,eAAe,KAAA,KAAa,EAAE,WAAW,EAAE,YAAY;CAC9D;AAMP,MAAM,aAAa,YACjB,OAAO,IAAI,aAAa;CACtB,MAAM,OAAO,OAAO,YAAY,QAAQ,MAAM;CAC9C,MAAM,WAAW,QAAQ,YAAY,gBAAgB,QAAQ,MAAM,YAAY,GAAG;CAClF,MAAM,OAAO,IAAI,UAAU;AAC3B,MAAK,IAAI,YAAY,QAAQ,MAAM;AACnC,MAAK,IAAI,QAAQ,MAAM,SAAS;AAChC,KAAI,QAAQ,aAAa,KAAA,EAAW,MAAK,IAAI,iBAAiB,QAAQ,SAAS;AAC/E,KAAI,QAAQ,gBAAgB,KAAA,EAC1B,MAAK,IAAI,WAAW,QAAQ,cAAc,SAAS,QAAQ;AAC7D,KAAI,QAAQ,mBAAmB,KAAM,MAAK,IAAI,0BAA0B,OAAO;AAC/E,KAAI,QAAQ,gBAAgB,KAAA,EAAW,MAAK,IAAI,gBAAgB,OAAO,QAAQ,YAAY,CAAC;AAC5F,KAAI,QAAQ,gBAAgB,KAAA,EAC1B,MAAK,IAAI,oBAAoB,QAAQ,cAAc,SAAS,QAAQ;AAItE,MAAK,MAAM,QAAQ,QAAQ,gBAAgB,EAAE,CAAE,MAAK,OAAO,YAAY,KAAK;AAC5E,QAAO,aAAa,gBAAgB,QAAQ,QAAQ;EAClD,UAAU;EACV,YAAY;EACZ,OAAO;EACP,QAAQ;EACT,CAAC;AACF,QAAO;EACP;AAMJ,MAAM,kBAAkB,SAAiB,YACvC,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,OAAO,OAAO,UAAU,QAAQ;CACtC,MAAM,cAAc,kBAAkB,KAAK,GAAG,YAAY,IAAI,CAAC,iBAAiB,CAAC,KAC/E,kBAAkB,UAAU,cAAc,SAAS,MAAM,IAAI,OAAO,CAAC,EACrE,kBAAkB,aAAa,KAAK,CACrC;CACD,MAAM,WAAW,OAAO,OAAO,QAAQ,YAAY,CAAC,KAAK,OAAO,SAAS,iBAAiB,CAAC;AAC3F,KAAI,SAAS,UAAU,KAAK;EAC1B,MAAM,OAAO,OAAO,SAAS,KAAK,KAAK,OAAO,oBAAoB,GAAG,CAAC;AACtE,SAAO,OAAO,OAAO,KAAK,gBAAgB,SAAS,QAAQ,KAAK,CAAC;;CAEnE,MAAM,OAAO,OAAO,SAAS,KAAK,KAAK,OAAO,SAAS,iBAAiB,CAAC;CACzE,MAAM,OAAO,OAAO,WAAW,KAAK,CAAC,KACnC,OAAO,UACJ,UAAU,IAAI,QAAQ,iBAAiB;EAAE,UAAU;EAAc,KAAK;EAAO,CAAC,CAChF,CACF;CACD,MAAM,QAAQ,KAAK,OACf,IAAI,gBAAgB,CACrB,QAAQ,MAA0B,MAAM,KAAA,EAAU;AACrD,QAAO;EACL,MAAM,KAAK;EACX,GAAI,KAAK,kBAAkB,KAAA,KAAa,EAAE,cAAc,KAAK,eAAe;EAC5E,GAAI,UAAU,KAAA,KAAa,MAAM,SAAS,KAAK,EAAE,OAAO;EACxD,KAAK;EACN;EACD;AAMJ,MAAa,QAAQ,QACnB,OAAO,IAAI,aAAa;CACtB,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,OAAO,OAAO,OAAO;AAC3B,QAAO;EACL,aAAa,MACX,eAAe,IAAI,CAAC,EAAE,CAAC,KAAK,OAAO,eAAe,WAAW,YAAY,OAAO,CAAC;EACnF,0BAA0B,SAAS,YACjC,oBAAoB,IAAI,CAAC,SAAS,QAAQ,CAAC,KACzC,OAAO,eAAe,WAAW,YAAY,OAAO,EACpD,OAAO,eAAe,OAAO,sBAAsB,KAAK,CACzD;EACJ;EACD;;;;;;;;AASJ,MAAa,SAAS,QACpB,MAAM,SACJ,MAAM,OAAO,uBAAuB,KAAK,IAAI,CAAC,EAC9C,MAAM,OACJ,aACA,OAAO,IACL,KAAK,IAAI,GACR,OAA2B;CAC1B,aAAa,QACX,EAAE,WAAW,IAAmC;CAClD,yBAAyB,EAAE;CAC5B,EACF,CACF,EACD,MAAM,QAAQ,cAAc,KAAA,EAAU,CACvC"}
1
+ {"version":3,"file":"ElevenLabsTranscriber.mjs","names":[],"sources":["../src/ElevenLabsTranscriber.ts"],"sourcesContent":["import { Context, Effect, Layer, Redacted, Schema, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport * as Capabilities from \"@effect-uai/core/Capabilities\"\nimport type { TranscriptResult, WordTimestamp } from \"@effect-uai/core/Transcript\"\nimport {\n type CommonTranscribeRequest,\n SttStreaming,\n Transcriber,\n type TranscriberService,\n} from \"@effect-uai/core/Transcriber\"\nimport { audioToBlob, defaultFileName, httpStatusError, transportFailure } from \"./codec.js\"\nimport type { ElevenLabsSttModel } from \"./models.js\"\nimport { streamTranscription } from \"./realtimeStt.js\"\nimport { type ElevenLabsRegion, resolveHost } from \"./region.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * ElevenLabs-typed transcribe request. `model` narrows to\n * `ElevenLabsSttModel`. `numSpeakers` hints diarization. `audioEvents`\n * surfaces `(laughter)` / `(music)` tags inline in `text` (provider\n * default: true). `fileName` overrides the multipart upload's\n * `filename`; ElevenLabs uses the extension to detect format.\n */\nexport type ElevenLabsTranscribeRequest = Omit<CommonTranscribeRequest, \"model\"> & {\n readonly model: ElevenLabsSttModel\n readonly numSpeakers?: number\n readonly audioEvents?: boolean\n readonly fileName?: string\n}\n\nexport type ElevenLabsTranscriberService = {\n readonly transcribe: (\n r: ElevenLabsTranscribeRequest,\n ) => Effect.Effect<TranscriptResult, AiError.AiError>\n readonly streamTranscriptionFrom: TranscriberService[\"streamTranscriptionFrom\"]\n}\n\nexport class ElevenLabsTranscriber extends Context.Service<\n ElevenLabsTranscriber,\n ElevenLabsTranscriberService\n>()(\"@betalyra/effect-uai/providers/elevenlabs/ElevenLabsTranscriber\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n readonly region?: ElevenLabsRegion\n}\n\n// ---------------------------------------------------------------------------\n// Response schema\n// ---------------------------------------------------------------------------\n\nconst Word = Schema.Struct({\n text: Schema.String,\n start: Schema.optional(Schema.Number),\n end: Schema.optional(Schema.Number),\n type: Schema.optional(Schema.String),\n speaker_id: Schema.optional(Schema.String),\n logprob: Schema.optional(Schema.Number),\n})\n\nconst Wire = Schema.Struct({\n text: Schema.String,\n language_code: Schema.optional(Schema.String),\n language_probability: Schema.optional(Schema.Number),\n words: Schema.optional(Schema.Array(Word)),\n transcription_id: Schema.optional(Schema.String),\n})\nconst decodeWire = Schema.decodeUnknownEffect(Wire)\n\nconst toWordTimestamp = (w: typeof Word.Type): WordTimestamp | undefined =>\n w.start === undefined || w.end === undefined\n ? undefined\n : {\n text: w.text,\n startSeconds: w.start,\n endSeconds: w.end,\n ...(w.logprob !== undefined && { confidence: Math.exp(w.logprob) }),\n ...(w.speaker_id !== undefined && { speakerId: w.speaker_id }),\n }\n\n// ---------------------------------------------------------------------------\n// Multipart body\n// ---------------------------------------------------------------------------\n\nconst buildForm = (request: ElevenLabsTranscribeRequest) =>\n Effect.gen(function* () {\n const blob = yield* audioToBlob(request.audio)\n const fileName = request.fileName ?? defaultFileName(request.audio.mimeType ?? \"\")\n const form = new FormData()\n form.set(\"model_id\", request.model)\n form.set(\"file\", blob, fileName)\n if (request.language !== undefined) form.set(\"language_code\", request.language)\n if (request.diarization !== undefined)\n form.set(\"diarize\", request.diarization ? \"true\" : \"false\")\n if (request.wordTimestamps === true) form.set(\"timestamps_granularity\", \"word\")\n if (request.numSpeakers !== undefined) form.set(\"num_speakers\", String(request.numSpeakers))\n if (request.audioEvents !== undefined)\n form.set(\"tag_audio_events\", request.audioEvents ? \"true\" : \"false\")\n // Vocab biasing → Scribe `keyterms` (≤1000 terms, ≤50 chars). Each\n // term is a repeated form field (`keyterms=a&keyterms=b`), matching\n // the ElevenLabs SDK. Scribe has no free-form prompt field.\n for (const term of request.biasingTerms ?? []) form.append(\"keyterms\", term)\n yield* Capabilities.warnDroppedWhen(request.prompt, {\n provider: \"elevenlabs\",\n capability: \"prompt\",\n field: \"prompt\",\n reason: \"ElevenLabs Scribe has no free-form prompt field; bias via `biasingTerms`.\",\n })\n return form\n })\n\n// ---------------------------------------------------------------------------\n// HTTP plumbing\n// ---------------------------------------------------------------------------\n\nconst transcribeImpl = (cfg: Config) => (request: ElevenLabsTranscribeRequest) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const form = yield* buildForm(request)\n const httpRequest = HttpClientRequest.post(`${resolveHost(cfg)}/speech-to-text`).pipe(\n HttpClientRequest.setHeader(\"xi-api-key\", Redacted.value(cfg.apiKey)),\n HttpClientRequest.bodyFormData(form),\n )\n const response = yield* client.execute(httpRequest).pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const json = yield* response.json.pipe(Effect.mapError(transportFailure))\n const wire = yield* decodeWire(json).pipe(\n Effect.mapError(\n (cause) => new AiError.GenerationFailed({ provider: \"elevenlabs\", raw: cause }),\n ),\n )\n const words = wire.words\n ?.map(toWordTimestamp)\n .filter((w): w is WordTimestamp => w !== undefined)\n return {\n text: wire.text,\n ...(wire.language_code !== undefined && { languageCode: wire.language_code }),\n ...(words !== undefined && words.length > 0 && { words }),\n raw: json,\n } satisfies TranscriptResult\n })\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (cfg: Config) =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const ctor = yield* Socket.WebSocketConstructor\n return {\n transcribe: (r) =>\n transcribeImpl(cfg)(r).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamTranscriptionFrom: (audioIn, request) =>\n streamTranscription(cfg)(audioIn, request).pipe(\n Stream.provideService(HttpClient.HttpClient, client),\n Stream.provideService(Socket.WebSocketConstructor, ctor),\n ),\n } satisfies ElevenLabsTranscriberService\n })\n\n/**\n * Layer registers `ElevenLabsTranscriber`, the generic `Transcriber`,\n * **and the `SttStreaming` capability marker** — `streamTranscriptionFrom`\n * is wired to the realtime WebSocket. Provide\n * `Socket.layerWebSocketConstructorGlobal` (or a custom constructor) +\n * an `HttpClient` Layer at the call site.\n */\nexport const layer = (cfg: Config) =>\n Layer.mergeAll(\n Layer.effect(ElevenLabsTranscriber, make(cfg)),\n Layer.effect(\n Transcriber,\n Effect.map(make(cfg), (s): TranscriberService => ({\n transcribe: (req: CommonTranscribeRequest) =>\n s.transcribe(req as ElevenLabsTranscribeRequest),\n streamTranscriptionFrom: s.streamTranscriptionFrom,\n })),\n ),\n Layer.succeed(SttStreaming, undefined),\n )\n"],"mappings":"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"}
@@ -1 +1 @@
1
- export { };
1
+ export {}
@@ -1,10 +1,13 @@
1
- import { i as it, n as globalExpect, r as describe, t as import_dist } from "./dist-CWoAuwS9.mjs";
1
+ import { n as describe, r as it, t as globalExpect } from "./test.DNmyFkvJ-N3QqMRwZ.mjs";
2
+ import { t as import_dist } from "./dist-C0AvqZTC.mjs";
2
3
  import { ElevenLabsTranscriber, layer } from "./ElevenLabsTranscriber.mjs";
3
4
  import { Effect, Layer, Redacted, Stream } from "effect";
4
5
  import { FetchHttpClient } from "effect/unstable/http";
5
6
  import * as Socket from "effect/unstable/socket/Socket";
6
7
  import * as Transcriber$1 from "@effect-uai/core/Transcriber";
7
- const live = layer({ apiKey: Redacted.make("test-key") }).pipe(Layer.provide(FetchHttpClient.layer), Layer.provide(Socket.layerWebSocketConstructorGlobal));
8
+ //#region src/ElevenLabsTranscriber.test.ts
9
+ const cfg = { apiKey: Redacted.make("test-key") };
10
+ const live = layer(cfg).pipe(Layer.provide(FetchHttpClient.layer), Layer.provide(Socket.layerWebSocketConstructorGlobal));
8
11
  const dummyAudio = {
9
12
  _tag: "bytes",
10
13
  bytes: new Uint8Array([
@@ -43,13 +46,15 @@ describe("ElevenLabsTranscriber Layer (compile-time)", () => {
43
46
  sampleRate: 16e3
44
47
  }
45
48
  }));
46
- (0, import_dist.expectTypeOf)(Stream.runDrain(events).pipe(Effect.provide(live))).toEqualTypeOf();
49
+ const provided = Stream.runDrain(events).pipe(Effect.provide(live));
50
+ (0, import_dist.expectTypeOf)(provided).toEqualTypeOf();
47
51
  });
48
52
  it("sync `transcribe` requires no marker", () => {
49
- (0, import_dist.expectTypeOf)(Transcriber$1.transcribe({
53
+ const t = Transcriber$1.transcribe({
50
54
  audio: dummyAudio,
51
55
  model: "scribe_v2"
52
- }).pipe(Effect.provide(live))).toEqualTypeOf();
56
+ }).pipe(Effect.provide(live));
57
+ (0, import_dist.expectTypeOf)(t).toEqualTypeOf();
53
58
  });
54
59
  });
55
60
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"ElevenLabsTranscriber.test.mjs","names":["ElevenLabsTranscriber.layer","Transcriber"],"sources":["../src/ElevenLabsTranscriber.test.ts"],"sourcesContent":["import { Effect, Layer, Redacted, Stream } from \"effect\"\nimport { FetchHttpClient } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport { describe, expect, expectTypeOf, it } from \"vitest\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { TranscriptResult } from \"@effect-uai/core/Transcript\"\nimport * as Transcriber from \"@effect-uai/core/Transcriber\"\nimport * as ElevenLabsTranscriber from \"./ElevenLabsTranscriber.js\"\n\nconst cfg: ElevenLabsTranscriber.Config = { apiKey: Redacted.make(\"test-key\") }\n// FetchHttpClient + globalThis.WebSocket are required for `make`, but these\n// tests only exercise the codec + compile-time / runtime branches — no real\n// HTTP or WS connection is opened.\nconst live = ElevenLabsTranscriber.layer(cfg).pipe(\n Layer.provide(FetchHttpClient.layer),\n Layer.provide(Socket.layerWebSocketConstructorGlobal),\n)\n\nconst dummyAudio = {\n _tag: \"bytes\" as const,\n bytes: new Uint8Array([0, 1, 2, 3]),\n mimeType: \"audio/wav\" as const,\n}\n\ndescribe(\"ElevenLabsTranscriber input format guard (runtime)\", () => {\n it(\"fails Unsupported for unsupported raw encodings\", async () => {\n const program = ElevenLabsTranscriber.ElevenLabsTranscriber.use((s) =>\n Stream.runDrain(\n s.streamTranscriptionFrom(Stream.fromIterable([new Uint8Array([0])]), {\n model: \"scribe_v2_realtime\",\n inputFormat: { container: \"mp3\", encoding: \"mp3\", sampleRate: 44100 },\n }),\n ),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"Unsupported\")\n expect(JSON.stringify(exit.cause)).toContain(\"inputFormat\")\n }\n })\n})\n\ndescribe(\"ElevenLabsTranscriber Layer (compile-time)\", () => {\n it(\"registers `SttStreaming` — `streamTranscriptionFrom` clears R to never\", () => {\n const audio: Stream.Stream<Uint8Array> = Stream.fromIterable([new Uint8Array([0])])\n const events = audio.pipe(\n Transcriber.streamTranscriptionFrom({\n model: \"scribe_v2_realtime\",\n inputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 16000 },\n }),\n )\n const provided = Stream.runDrain(events).pipe(Effect.provide(live))\n expectTypeOf(provided).toEqualTypeOf<Effect.Effect<void, AiError.AiError, never>>()\n })\n\n it(\"sync `transcribe` requires no marker\", () => {\n const t = Transcriber.transcribe({ audio: dummyAudio, model: \"scribe_v2\" }).pipe(\n Effect.provide(live),\n )\n expectTypeOf(t).toEqualTypeOf<Effect.Effect<TranscriptResult, AiError.AiError, never>>()\n })\n})\n"],"mappings":";;;;;;AAaA,MAAM,OAAOA,MAA4B,EAJG,QAAQ,SAAS,KAAK,WAAW,EAIpC,CAAI,CAAC,KAC5C,MAAM,QAAQ,gBAAgB,MAAM,EACpC,MAAM,QAAQ,OAAO,gCAAgC,CACtD;AAED,MAAM,aAAa;CACjB,MAAM;CACN,OAAO,IAAI,WAAW;EAAC;EAAG;EAAG;EAAG;EAAE,CAAC;CACnC,UAAU;CACX;AAED,SAAS,4DAA4D;AACnE,IAAG,mDAAmD,YAAY;EAChE,MAAM,UAAA,sBAAsD,KAAK,MAC/D,OAAO,SACL,EAAE,wBAAwB,OAAO,aAAa,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;GACpE,OAAO;GACP,aAAa;IAAE,WAAW;IAAO,UAAU;IAAO,YAAY;IAAO;GACtE,CAAC,CACH,CACF;EACD,MAAM,OAAO,MAAM,OAAO,eAAe,QAAQ,KAAK,OAAO,QAAQ,KAAK,CAAC,CAAC;AAC5E,eAAO,KAAK,KAAK,CAAC,KAAK,UAAU;AACjC,MAAI,KAAK,SAAS,WAAW;AAC3B,gBAAO,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC,UAAU,cAAc;AAC3D,gBAAO,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC,UAAU,cAAc;;GAE7D;EACF;AAEF,SAAS,oDAAoD;AAC3D,IAAG,gFAAgF;EAEjF,MAAM,SADmC,OAAO,aAAa,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC,CAC9D,CAAC,KACnBC,cAAY,wBAAwB;GAClC,OAAO;GACP,aAAa;IAAE,WAAW;IAAO,UAAU;IAAa,YAAY;IAAO;GAC5E,CAAC,CACH;AAED,GAAA,GAAA,YAAA,cADiB,OAAO,SAAS,OAAO,CAAC,KAAK,OAAO,QAAQ,KAAK,CAC7C,CAAC,CAAC,eAA4D;GACnF;AAEF,IAAG,8CAA8C;AAI/C,GAAA,GAAA,YAAA,cAHUA,cAAY,WAAW;GAAE,OAAO;GAAY,OAAO;GAAa,CAAC,CAAC,KAC1E,OAAO,QAAQ,KAAK,CAER,CAAC,CAAC,eAAwE;GACxF;EACF"}
1
+ {"version":3,"file":"ElevenLabsTranscriber.test.mjs","names":["ElevenLabsTranscriber.layer","Transcriber"],"sources":["../src/ElevenLabsTranscriber.test.ts"],"sourcesContent":["import { Effect, Layer, Redacted, Stream } from \"effect\"\nimport { FetchHttpClient } from \"effect/unstable/http\"\nimport * as Socket from \"effect/unstable/socket/Socket\"\nimport { describe, expect, expectTypeOf, it } from \"vitest\"\nimport type * as AiError from \"@effect-uai/core/AiError\"\nimport type { TranscriptResult } from \"@effect-uai/core/Transcript\"\nimport * as Transcriber from \"@effect-uai/core/Transcriber\"\nimport * as ElevenLabsTranscriber from \"./ElevenLabsTranscriber.js\"\n\nconst cfg: ElevenLabsTranscriber.Config = { apiKey: Redacted.make(\"test-key\") }\n// FetchHttpClient + globalThis.WebSocket are required for `make`, but these\n// tests only exercise the codec + compile-time / runtime branches — no real\n// HTTP or WS connection is opened.\nconst live = ElevenLabsTranscriber.layer(cfg).pipe(\n Layer.provide(FetchHttpClient.layer),\n Layer.provide(Socket.layerWebSocketConstructorGlobal),\n)\n\nconst dummyAudio = {\n _tag: \"bytes\" as const,\n bytes: new Uint8Array([0, 1, 2, 3]),\n mimeType: \"audio/wav\" as const,\n}\n\ndescribe(\"ElevenLabsTranscriber input format guard (runtime)\", () => {\n it(\"fails Unsupported for unsupported raw encodings\", async () => {\n const program = ElevenLabsTranscriber.ElevenLabsTranscriber.use((s) =>\n Stream.runDrain(\n s.streamTranscriptionFrom(Stream.fromIterable([new Uint8Array([0])]), {\n model: \"scribe_v2_realtime\",\n inputFormat: { container: \"mp3\", encoding: \"mp3\", sampleRate: 44100 },\n }),\n ),\n )\n const exit = await Effect.runPromiseExit(program.pipe(Effect.provide(live)))\n expect(exit._tag).toBe(\"Failure\")\n if (exit._tag === \"Failure\") {\n expect(JSON.stringify(exit.cause)).toContain(\"Unsupported\")\n expect(JSON.stringify(exit.cause)).toContain(\"inputFormat\")\n }\n })\n})\n\ndescribe(\"ElevenLabsTranscriber Layer (compile-time)\", () => {\n it(\"registers `SttStreaming` — `streamTranscriptionFrom` clears R to never\", () => {\n const audio: Stream.Stream<Uint8Array> = Stream.fromIterable([new Uint8Array([0])])\n const events = audio.pipe(\n Transcriber.streamTranscriptionFrom({\n model: \"scribe_v2_realtime\",\n inputFormat: { container: \"raw\", encoding: \"pcm_s16le\", sampleRate: 16000 },\n }),\n )\n const provided = Stream.runDrain(events).pipe(Effect.provide(live))\n expectTypeOf(provided).toEqualTypeOf<Effect.Effect<void, AiError.AiError, never>>()\n })\n\n it(\"sync `transcribe` requires no marker\", () => {\n const t = Transcriber.transcribe({ audio: dummyAudio, model: \"scribe_v2\" }).pipe(\n Effect.provide(live),\n )\n expectTypeOf(t).toEqualTypeOf<Effect.Effect<TranscriptResult, AiError.AiError, never>>()\n })\n})\n"],"mappings":";;;;;;;;AASA,MAAM,MAAoC,EAAE,QAAQ,SAAS,KAAK,UAAU,EAAE;AAI9E,MAAM,OAAOA,MAA4B,GAAG,CAAC,CAAC,KAC5C,MAAM,QAAQ,gBAAgB,KAAK,GACnC,MAAM,QAAQ,OAAO,+BAA+B,CACtD;AAEA,MAAM,aAAa;CACjB,MAAM;CACN,OAAO,IAAI,WAAW;EAAC;EAAG;EAAG;EAAG;CAAC,CAAC;CAClC,UAAU;AACZ;AAEA,SAAS,4DAA4D;CACnE,GAAG,mDAAmD,YAAY;EAChE,MAAM,UAAA,sBAAsD,KAAK,MAC/D,OAAO,SACL,EAAE,wBAAwB,OAAO,aAAa,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;GACpE,OAAO;GACP,aAAa;IAAE,WAAW;IAAO,UAAU;IAAO,YAAY;GAAM;EACtE,CAAC,CACH,CACF;EACA,MAAM,OAAO,MAAM,OAAO,eAAe,QAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC,CAAC;EAC3E,aAAO,KAAK,IAAI,CAAC,CAAC,KAAK,SAAS;EAChC,IAAI,KAAK,SAAS,WAAW;GAC3B,aAAO,KAAK,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,aAAa;GAC1D,aAAO,KAAK,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,UAAU,aAAa;EAC5D;CACF,CAAC;AACH,CAAC;AAED,SAAS,oDAAoD;CAC3D,GAAG,gFAAgF;EAEjF,MAAM,SADmC,OAAO,aAAa,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAC9D,CAAC,CAAC,KACnBC,cAAY,wBAAwB;GAClC,OAAO;GACP,aAAa;IAAE,WAAW;IAAO,UAAU;IAAa,YAAY;GAAM;EAC5E,CAAC,CACH;EACA,MAAM,WAAW,OAAO,SAAS,MAAM,CAAC,CAAC,KAAK,OAAO,QAAQ,IAAI,CAAC;EAClE,CAAA,GAAA,YAAA,aAAA,CAAa,QAAQ,CAAC,CAAC,cAA2D;CACpF,CAAC;CAED,GAAG,8CAA8C;EAC/C,MAAM,IAAIA,cAAY,WAAW;GAAE,OAAO;GAAY,OAAO;EAAY,CAAC,CAAC,CAAC,KAC1E,OAAO,QAAQ,IAAI,CACrB;EACA,CAAA,GAAA,YAAA,aAAA,CAAa,CAAC,CAAC,CAAC,cAAuE;CACzF,CAAC;AACH,CAAC"}
package/dist/codec.d.mts CHANGED
@@ -2,8 +2,6 @@ import { Effect } from "effect";
2
2
  import * as AiError from "@effect-uai/core/AiError";
3
3
  import { CustomPronunciation } from "@effect-uai/core/SpeechSynthesizer";
4
4
  import { AudioFormat, AudioSource } from "@effect-uai/core/Audio";
5
-
6
- //#region src/codec.d.ts
7
5
  declare namespace codec_d_exports {
8
6
  export { PronunciationDictionaryLocator, VoiceSettings, audioToBlob, defaultFileName, defaultFormat, formatToOutputSlug, httpStatusError, rejectInlinePronunciations, transportFailure, wirePronunciationLocators, wireVoiceSettings };
9
7
  }
@@ -15,11 +13,11 @@ type VoiceSettings = {
15
13
  readonly speed?: number;
16
14
  };
17
15
  declare const wireVoiceSettings: (v: VoiceSettings | undefined) => {
18
- speed?: number;
19
- use_speaker_boost?: boolean;
20
- style?: number;
21
- similarity_boost?: number;
22
16
  stability?: number;
17
+ similarity_boost?: number;
18
+ style?: number;
19
+ use_speaker_boost?: boolean;
20
+ speed?: number;
23
21
  } | undefined;
24
22
  /**
25
23
  * Reference to a pre-provisioned ElevenLabs pronunciation dictionary.
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.mts","names":[],"sources":["../src/codec.ts"],"mappings":";;;;;;;;;KASY,aAAA;EAAA,SACD,SAAA;EAAA,SACA,eAAA;EAAA,SACA,KAAA;EAAA,SACA,eAAA;EAAA,SACA,KAAA;AAAA;AAAA,cAGE,iBAAA,GAAqB,CAAA,EAAG,aAAA;;;;;;;;;AARrC;;;KA4BY,8BAAA;EAAA,SACD,YAAA;EAAA,SACA,SAAA;AAAA;AAAA,cAGE,yBAAA,GACX,QAAA,EAAU,aAAA,CAAc,8BAAA;;;;;;;;;;;;cAiBb,0BAAA,GACX,cAAA,EAAgB,aAAA,CAAc,mBAAA,kBAC7B,MAAA,CAAO,MAAA,OAAa,OAAA,CAAQ,OAAA;;;;;AAzB/B;;;;;AAKA;;cA+Ca,kBAAA,GAAqB,MAAA,EAAQ,WAAA,KAAgB,MAAA,CAAO,MAAA,SAAe,OAAA,CAAQ,OAAA;;cAgC3E,aAAA,EAAe,WAAA;AAAA,cA6Bf,WAAA,GAAc,KAAA,EAAO,WAAA,KAAgB,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAA,CAAQ,OAAA;AAAA,cA2BjE,eAAA,GAAmB,QAAA;AAAA,cAYnB,eAAA,GAAkB,MAAA,UAAgB,IAAA,aAAiB,OAAA,CAAQ,OAAA;AAAA,cAyC3D,gBAAA,GAAoB,KAAA,cAAiB,OAAA,CAAQ,OAAA"}
1
+ {"version":3,"file":"codec.d.mts","names":[],"sources":["../src/codec.ts"],"mappings":";;;;;;;KASY;WACD;WACA;WACA;WACA;WACA;;cAGE,oBAAiB,GAAO;;;;;;;;;;;;KAoBzB;WACD;WACA;;cAGE,4BAAyB,UAC1B,cAAc;;;;;;;;;;;;cAiBb,6BAA0B,gBACrB,cAAc,qCAC7B,OAAO,aAAa,QAAQ;;;;;;;;;;;;cA2BlB,qBAAqB,QAAQ,gBAAgB,OAAO,eAAe,QAAQ;;cAgC3E,eAAe;cA6Bf,cAAc,OAAO,gBAAgB,OAAO,OAAO,MAAM,QAAQ;cA2BjE,kBAAe;cAYf,kBAAkB,gBAAgB,iBAAiB,QAAQ;cAyC3D,mBAAgB,mBAAqB,QAAQ"}