@effect-uai/mistral 0.8.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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -0
  3. package/dist/Mistral.d.mts +48 -0
  4. package/dist/Mistral.d.mts.map +1 -0
  5. package/dist/Mistral.mjs +88 -0
  6. package/dist/Mistral.mjs.map +1 -0
  7. package/dist/MistralRealtimeTranscriber.d.mts +15 -0
  8. package/dist/MistralRealtimeTranscriber.d.mts.map +1 -0
  9. package/dist/MistralRealtimeTranscriber.mjs +34 -0
  10. package/dist/MistralRealtimeTranscriber.mjs.map +1 -0
  11. package/dist/MistralSynthesizer.d.mts +43 -0
  12. package/dist/MistralSynthesizer.d.mts.map +1 -0
  13. package/dist/MistralSynthesizer.mjs +121 -0
  14. package/dist/MistralSynthesizer.mjs.map +1 -0
  15. package/dist/MistralTranscriber.d.mts +44 -0
  16. package/dist/MistralTranscriber.d.mts.map +1 -0
  17. package/dist/MistralTranscriber.mjs +111 -0
  18. package/dist/MistralTranscriber.mjs.map +1 -0
  19. package/dist/audioCodec.d.mts +27 -0
  20. package/dist/audioCodec.d.mts.map +1 -0
  21. package/dist/audioCodec.mjs +82 -0
  22. package/dist/audioCodec.mjs.map +1 -0
  23. package/dist/chunk-CfYAbeIz.mjs +13 -0
  24. package/dist/codec.d.mts +100 -0
  25. package/dist/codec.d.mts.map +1 -0
  26. package/dist/codec.mjs +244 -0
  27. package/dist/codec.mjs.map +1 -0
  28. package/dist/codec.test.d.mts +1 -0
  29. package/dist/codec.test.mjs +13800 -0
  30. package/dist/codec.test.mjs.map +1 -0
  31. package/dist/http.d.mts +9 -0
  32. package/dist/http.d.mts.map +1 -0
  33. package/dist/http.mjs +41 -0
  34. package/dist/http.mjs.map +1 -0
  35. package/dist/index.d.mts +7 -0
  36. package/dist/index.mjs +7 -0
  37. package/dist/magic-string.es-PAZgLX4h.mjs +1013 -0
  38. package/dist/magic-string.es-PAZgLX4h.mjs.map +1 -0
  39. package/dist/models-DnDmylpj.d.mts +22 -0
  40. package/dist/models-DnDmylpj.d.mts.map +1 -0
  41. package/dist/models.d.mts +2 -0
  42. package/dist/models.mjs +1 -0
  43. package/dist/realtimeStt-ClXWXbXX.d.mts +21 -0
  44. package/dist/realtimeStt-ClXWXbXX.d.mts.map +1 -0
  45. package/dist/realtimeStt.d.mts +2 -0
  46. package/dist/realtimeStt.mjs +136 -0
  47. package/dist/realtimeStt.mjs.map +1 -0
  48. package/package.json +82 -0
  49. package/src/Mistral.ts +189 -0
  50. package/src/MistralRealtimeTranscriber.ts +60 -0
  51. package/src/MistralSynthesizer.ts +285 -0
  52. package/src/MistralTranscriber.ts +224 -0
  53. package/src/audioCodec.ts +123 -0
  54. package/src/codec.test.ts +121 -0
  55. package/src/codec.ts +338 -0
  56. package/src/http.ts +46 -0
  57. package/src/index.ts +6 -0
  58. package/src/models.ts +47 -0
  59. package/src/realtimeStt.ts +256 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Betalyra Sociedade Unipessoal Lda.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @effect-uai/mistral
2
+
3
+ Mistral provider for [`@effect-uai/core`](https://www.npmjs.com/package/@effect-uai/core).
4
+
5
+ One package, the whole Mistral surface:
6
+
7
+ - **`Mistral`** — the `LanguageModel` contract against Mistral's
8
+ chat-completions API, with SSE streaming, function calling, and
9
+ `json_schema` structured output.
10
+ - **`MistralTranscriber`** — batch speech-to-text (Voxtral) via
11
+ `/v1/audio/transcriptions`.
12
+ - **`MistralRealtimeTranscriber`** — live speech-to-text over the
13
+ Voxtral Realtime WebSocket (registers the `SttStreaming` capability).
14
+ - **`MistralSynthesizer`** — Voxtral text-to-speech, including streaming
15
+ output and zero-shot voice cloning via a reference clip.
16
+
17
+ ## Install
18
+
19
+ ```sh
20
+ pnpm add @effect-uai/mistral @effect-uai/core effect
21
+ ```
22
+
23
+ ESM-only. Requires `effect@4.x` and `@effect-uai/core` as peers. The
24
+ realtime transcriber additionally needs the optional `ws` peer (Node /
25
+ Bun only).
26
+
27
+ ## Usage
28
+
29
+ ### Chat completions (LanguageModel)
30
+
31
+ ```ts
32
+ import { Config, Effect, Layer } from "effect"
33
+ import { FetchHttpClient } from "effect/unstable/http"
34
+ import { layer as mistralLayer } from "@effect-uai/mistral/Mistral"
35
+
36
+ const provider = Layer.unwrap(
37
+ Effect.gen(function* () {
38
+ const apiKey = yield* Config.redacted("MISTRAL_API_KEY")
39
+ return mistralLayer({ apiKey })
40
+ }),
41
+ )
42
+
43
+ const layer = Layer.provide(provider, FetchHttpClient.layer)
44
+ ```
45
+
46
+ The layer registers both the provider-typed `Mistral` tag and the
47
+ generic `LanguageModel` tag.
48
+
49
+ ### Voxtral speech (STT + TTS)
50
+
51
+ ```ts
52
+ import { layer as transcriber } from "@effect-uai/mistral/MistralRealtimeTranscriber"
53
+ import { layer as synthesizer } from "@effect-uai/mistral/MistralSynthesizer"
54
+
55
+ // transcriber({ apiKey }) registers Transcriber + SttStreaming
56
+ // synthesizer({ apiKey }) registers SpeechSynthesizer + TtsIncrementalText
57
+ ```
58
+
59
+ For batch (non-streaming) transcription, import
60
+ `@effect-uai/mistral/MistralTranscriber` instead — it omits the `ws`
61
+ dependency.
62
+
63
+ ## Notes
64
+
65
+ - `tool_choice` maps `"required"` to Mistral's `"any"`.
66
+ - Voxtral TTS `pcm` output is float32 LE; `wav` is s16le.
67
+ - The realtime STT wire frames are reconstructed from the SDK; verify
68
+ against the live API before production use.
69
+
70
+ ## Docs
71
+
72
+ <https://effect-uai.betalyra.com/providers/mistral/>
73
+
74
+ ## License
75
+
76
+ MIT
@@ -0,0 +1,48 @@
1
+ import { t as MistralModel } from "./models-DnDmylpj.mjs";
2
+ import { Context, Effect, Layer, Redacted, Stream } from "effect";
3
+ import { HttpClient } from "effect/unstable/http";
4
+ import * as AiError from "@effect-uai/core/AiError";
5
+ import { CommonRequest, LanguageModel } from "@effect-uai/core/LanguageModel";
6
+ import { Turn, TurnEvent } from "@effect-uai/core/Turn";
7
+
8
+ //#region src/Mistral.d.ts
9
+ declare namespace Mistral_d_exports {
10
+ export { Config, Mistral, MistralRequest, MistralService, layer, make };
11
+ }
12
+ type MistralRequest = Omit<CommonRequest, "model"> & {
13
+ /**
14
+ * Narrows `CommonRequest.model` (`string`) to the typed `MistralModel`
15
+ * literal union for autocomplete.
16
+ */
17
+ readonly model: MistralModel;
18
+ /**
19
+ * Prepend a safety system prompt (`safe_prompt` on the wire). Off by default.
20
+ */
21
+ readonly safePrompt?: boolean; /** Deterministic sampling seed (`random_seed` on the wire). */
22
+ readonly randomSeed?: number;
23
+ };
24
+ type MistralService = {
25
+ /** Stream canonical `TurnEvent`s for one turn. */readonly streamTurn: (request: MistralRequest) => Stream.Stream<TurnEvent, AiError.AiError>; /** Drain a single turn and return the assembled `Turn`. */
26
+ readonly turn: (request: MistralRequest) => Effect.Effect<Turn, AiError.AiError>;
27
+ };
28
+ declare const Mistral_base: Context.ServiceClass<Mistral, "@betalyra/effect-uai/providers/mistral/Mistral", MistralService>;
29
+ /**
30
+ * Provider-typed service tag. Yield this when you want Mistral-specific options
31
+ * (`safePrompt`, `randomSeed`); yield the generic `LanguageModel` tag for
32
+ * provider-portable code. Both are registered by `layer`.
33
+ */
34
+ declare class Mistral extends Mistral_base {}
35
+ type Config = {
36
+ readonly apiKey: Redacted.Redacted;
37
+ readonly baseUrl?: string;
38
+ };
39
+ /** Build a `MistralService` value. For Layer-based setup, prefer `layer`. */
40
+ declare const make: (cfg: Config) => Effect.Effect<MistralService, never, HttpClient.HttpClient>;
41
+ /**
42
+ * Layer that registers both the provider-specific `Mistral` tag and the
43
+ * generic `LanguageModel` tag, sharing one underlying implementation.
44
+ */
45
+ declare const layer: (cfg: Config) => Layer.Layer<Mistral | LanguageModel, never, HttpClient.HttpClient>;
46
+ //#endregion
47
+ export { Config, Mistral, MistralRequest, MistralService, layer, make, Mistral_d_exports as t };
48
+ //# sourceMappingURL=Mistral.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mistral.d.mts","names":[],"sources":["../src/Mistral.ts"],"mappings":";;;;;;;;;;;KA+BY,cAAA,GAAiB,IAAA,CAAK,aAAA;;;;;WAKvB,KAAA,EAAO,YAAA;;;;WAIP,UAAA;WAEA,UAAA;AAAA;AAAA,KAGC,cAAA;EAdsB,2DAgBvB,UAAA,GAAa,OAAA,EAAS,cAAA,KAAmB,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,CAAQ,OAAA,GAXnE;EAAA,SAaP,IAAA,GAAO,OAAA,EAAS,cAAA,KAAmB,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,OAAA,CAAQ,OAAA;AAAA;AAAA,cACzE,YAAA;;;;;;cAOY,OAAA,SAAgB,YAAA;AAAA,KAIjB,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;AAAA;;cAgGE,IAAA,GAAQ,GAAA,EAAK,MAAA,KAAS,MAAA,CAAO,MAAA,CAAO,cAAA,SAAuB,UAAA,CAAW,UAAA;;;;;cActE,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CAAM,OAAA,GAAU,aAAA,SAAsB,UAAA,CAAW,UAAA"}
@@ -0,0 +1,88 @@
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
+ import { accumulatorToTurn, applyChunk, decodeChunk, emptyAccumulator, itemsToMessages, responseFormatWire, toolChoiceWire, toolsWire } from "./codec.mjs";
3
+ import { httpStatusError } from "./http.mjs";
4
+ import { Context, Effect, Layer, Option, Redacted, Result, Schema, Stream } from "effect";
5
+ import { HttpClient, HttpClientRequest } from "effect/unstable/http";
6
+ import * as AiError from "@effect-uai/core/AiError";
7
+ import { LanguageModel, turnFromStream } from "@effect-uai/core/LanguageModel";
8
+ import * as SSE from "@effect-uai/core/SSE";
9
+ import { descriptorsOf } from "@effect-uai/core/Tool";
10
+ import { TurnEvent } from "@effect-uai/core/Turn";
11
+ //#region src/Mistral.ts
12
+ var Mistral_exports = /* @__PURE__ */ __exportAll({
13
+ Mistral: () => Mistral,
14
+ layer: () => layer,
15
+ make: () => make
16
+ });
17
+ /**
18
+ * Provider-typed service tag. Yield this when you want Mistral-specific options
19
+ * (`safePrompt`, `randomSeed`); yield the generic `LanguageModel` tag for
20
+ * provider-portable code. Both are registered by `layer`.
21
+ */
22
+ var Mistral = class extends Context.Service()("@betalyra/effect-uai/providers/mistral/Mistral") {};
23
+ const buildRequestBody = (request) => {
24
+ const tools = toolsWire(descriptorsOf(request.tools));
25
+ return {
26
+ model: request.model,
27
+ stream: true,
28
+ messages: itemsToMessages(request.history),
29
+ ...request.temperature !== void 0 && { temperature: request.temperature },
30
+ ...request.topP !== void 0 && { top_p: request.topP },
31
+ ...request.maxOutputTokens !== void 0 && { max_tokens: request.maxOutputTokens },
32
+ ...request.safePrompt !== void 0 && { safe_prompt: request.safePrompt },
33
+ ...request.randomSeed !== void 0 && { random_seed: request.randomSeed },
34
+ ...Option.isSome(tools) && { tools: tools.value },
35
+ ...request.toolChoice !== void 0 && { tool_choice: toolChoiceWire(request.toolChoice) },
36
+ ...request.structured !== void 0 && { response_format: responseFormatWire(request.structured) }
37
+ };
38
+ };
39
+ const parseJsonUnknown = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Unknown));
40
+ /**
41
+ * Decode one SSE event's `data` payload into a `WireChunk`. Returns `None`
42
+ * for the `[DONE]` sentinel and for any payload that isn't a chunk we model,
43
+ * so a stray keep-alive never aborts the turn.
44
+ */
45
+ const decodeEvent = (data) => data.trim() === "[DONE]" ? Effect.succeedNone : parseJsonUnknown(data).pipe(Effect.flatMap(decodeChunk), Effect.option);
46
+ const buildStream = (cfg) => {
47
+ const url = `${cfg.baseUrl ?? "https://api.mistral.ai"}/v1/chat/completions`;
48
+ return (request) => Stream.unwrap(Effect.gen(function* () {
49
+ const client = yield* HttpClient.HttpClient;
50
+ const httpRequest = HttpClientRequest.post(url).pipe(HttpClientRequest.setHeader("authorization", `Bearer ${Redacted.value(cfg.apiKey)}`), HttpClientRequest.bodyJsonUnsafe(buildRequestBody(request)), HttpClientRequest.accept("text/event-stream"));
51
+ const response = yield* client.execute(httpRequest).pipe(Effect.mapError((cause) => new AiError.Unavailable({
52
+ provider: "mistral",
53
+ raw: cause
54
+ })));
55
+ if (response.status >= 400) {
56
+ const text = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
57
+ return Stream.fail(httpStatusError(response.status, text));
58
+ }
59
+ return response.stream.pipe(Stream.mapError((cause) => new AiError.Unavailable({
60
+ provider: "mistral",
61
+ raw: cause
62
+ })), SSE.fromBytes, Stream.mapEffect((ev) => decodeEvent(ev.data)), Stream.filterMap((chunk) => Option.isSome(chunk) ? Result.succeed(chunk.value) : Result.failVoid), Stream.mapAccum(() => emptyAccumulator, applyChunk, { onHalt: (acc) => [TurnEvent.TurnComplete({ turn: accumulatorToTurn(acc) })] }));
63
+ }));
64
+ };
65
+ /** Build a `MistralService` value. For Layer-based setup, prefer `layer`. */
66
+ const make = (cfg) => Effect.map(HttpClient.HttpClient.asEffect(), (client) => {
67
+ const streamTurn = (request) => buildStream(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client));
68
+ return {
69
+ streamTurn,
70
+ turn: turnFromStream(streamTurn)
71
+ };
72
+ });
73
+ /**
74
+ * Layer that registers both the provider-specific `Mistral` tag and the
75
+ * generic `LanguageModel` tag, sharing one underlying implementation.
76
+ */
77
+ const layer = (cfg) => {
78
+ const typed = Layer.effect(Mistral, make(cfg));
79
+ const generic = Layer.effect(LanguageModel, Effect.map(make(cfg), (s) => ({
80
+ streamTurn: (request) => s.streamTurn(request),
81
+ turn: (request) => s.turn(request)
82
+ })));
83
+ return Layer.merge(typed, generic);
84
+ };
85
+ //#endregion
86
+ export { Mistral, layer, make, Mistral_exports as t };
87
+
88
+ //# sourceMappingURL=Mistral.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Mistral.mjs","names":[],"sources":["../src/Mistral.ts"],"sourcesContent":["import { Context, Effect, Layer, Option, Redacted, Result, Schema, Stream } from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport {\n type CommonRequest,\n LanguageModel,\n type LanguageModelService,\n turnFromStream,\n} from \"@effect-uai/core/LanguageModel\"\nimport * as SSE from \"@effect-uai/core/SSE\"\nimport { descriptorsOf } from \"@effect-uai/core/Tool\"\nimport { type Turn, TurnEvent } from \"@effect-uai/core/Turn\"\nimport {\n type Accumulator,\n type WireChunk,\n accumulatorToTurn,\n applyChunk,\n decodeChunk,\n emptyAccumulator,\n itemsToMessages,\n responseFormatWire,\n toolChoiceWire,\n toolsWire,\n} from \"./codec.js\"\nimport { httpStatusError } from \"./http.js\"\nimport type { MistralModel } from \"./models.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type MistralRequest = Omit<CommonRequest, \"model\"> & {\n /**\n * Narrows `CommonRequest.model` (`string`) to the typed `MistralModel`\n * literal union for autocomplete.\n */\n readonly model: MistralModel\n /**\n * Prepend a safety system prompt (`safe_prompt` on the wire). Off by default.\n */\n readonly safePrompt?: boolean\n /** Deterministic sampling seed (`random_seed` on the wire). */\n readonly randomSeed?: number\n}\n\nexport type MistralService = {\n /** Stream canonical `TurnEvent`s for one turn. */\n readonly streamTurn: (request: MistralRequest) => Stream.Stream<TurnEvent, AiError.AiError>\n /** Drain a single turn and return the assembled `Turn`. */\n readonly turn: (request: MistralRequest) => Effect.Effect<Turn, AiError.AiError>\n}\n\n/**\n * Provider-typed service tag. Yield this when you want Mistral-specific options\n * (`safePrompt`, `randomSeed`); yield the generic `LanguageModel` tag for\n * provider-portable code. Both are registered by `layer`.\n */\nexport class Mistral extends Context.Service<Mistral, MistralService>()(\n \"@betalyra/effect-uai/providers/mistral/Mistral\",\n) {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n}\n\n// ---------------------------------------------------------------------------\n// Request body\n// ---------------------------------------------------------------------------\n\nconst buildRequestBody = (request: MistralRequest): Record<string, unknown> => {\n const tools = toolsWire(descriptorsOf(request.tools))\n return {\n model: request.model,\n stream: true,\n messages: itemsToMessages(request.history),\n ...(request.temperature !== undefined && { temperature: request.temperature }),\n ...(request.topP !== undefined && { top_p: request.topP }),\n ...(request.maxOutputTokens !== undefined && { max_tokens: request.maxOutputTokens }),\n ...(request.safePrompt !== undefined && { safe_prompt: request.safePrompt }),\n ...(request.randomSeed !== undefined && { random_seed: request.randomSeed }),\n ...(Option.isSome(tools) && { tools: tools.value }),\n ...(request.toolChoice !== undefined && { tool_choice: toolChoiceWire(request.toolChoice) }),\n ...(request.structured !== undefined && {\n response_format: responseFormatWire(request.structured),\n }),\n }\n}\n\n// ---------------------------------------------------------------------------\n// SSE → WireChunk\n// ---------------------------------------------------------------------------\n\nconst parseJsonUnknown = Schema.decodeUnknownEffect(Schema.fromJsonString(Schema.Unknown))\n\n/**\n * Decode one SSE event's `data` payload into a `WireChunk`. Returns `None`\n * for the `[DONE]` sentinel and for any payload that isn't a chunk we model,\n * so a stray keep-alive never aborts the turn.\n */\nconst decodeEvent = (data: string): Effect.Effect<Option.Option<WireChunk>> =>\n data.trim() === \"[DONE]\"\n ? Effect.succeedNone\n : parseJsonUnknown(data).pipe(Effect.flatMap(decodeChunk), Effect.option)\n\n// ---------------------------------------------------------------------------\n// Stream\n// ---------------------------------------------------------------------------\n\nconst buildStream = (cfg: Config) => {\n const baseUrl = cfg.baseUrl ?? \"https://api.mistral.ai\"\n const url = `${baseUrl}/v1/chat/completions`\n return (\n request: MistralRequest,\n ): Stream.Stream<TurnEvent, AiError.AiError, HttpClient.HttpClient> =>\n Stream.unwrap(\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const httpRequest = HttpClientRequest.post(url).pipe(\n HttpClientRequest.setHeader(\"authorization\", `Bearer ${Redacted.value(cfg.apiKey)}`),\n HttpClientRequest.bodyJsonUnsafe(buildRequestBody(request)),\n HttpClientRequest.accept(\"text/event-stream\"),\n )\n const response = yield* client\n .execute(httpRequest)\n .pipe(\n Effect.mapError(\n (cause): AiError.AiError =>\n new AiError.Unavailable({ provider: \"mistral\", raw: cause }),\n ),\n )\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n return Stream.fail(httpStatusError(response.status, text))\n }\n\n return response.stream.pipe(\n Stream.mapError(\n (cause): AiError.AiError =>\n new AiError.Unavailable({ provider: \"mistral\", raw: cause }),\n ),\n SSE.fromBytes,\n Stream.mapEffect((ev) => decodeEvent(ev.data)),\n Stream.filterMap((chunk) =>\n Option.isSome(chunk) ? Result.succeed(chunk.value) : Result.failVoid,\n ),\n Stream.mapAccum((): Accumulator => emptyAccumulator, applyChunk, {\n onHalt: (acc) => [TurnEvent.TurnComplete({ turn: accumulatorToTurn(acc) })],\n }),\n )\n }),\n )\n}\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\n/** Build a `MistralService` value. For Layer-based setup, prefer `layer`. */\nexport const make = (cfg: Config): Effect.Effect<MistralService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient.asEffect(), (client) => {\n const streamTurn: MistralService[\"streamTurn\"] = (request) =>\n buildStream(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client))\n return {\n streamTurn,\n turn: turnFromStream(streamTurn),\n }\n })\n\n/**\n * Layer that registers both the provider-specific `Mistral` tag and the\n * generic `LanguageModel` tag, sharing one underlying implementation.\n */\nexport const layer = (\n cfg: Config,\n): Layer.Layer<Mistral | LanguageModel, never, HttpClient.HttpClient> => {\n const typed = Layer.effect(Mistral, make(cfg))\n const generic = Layer.effect(\n LanguageModel,\n Effect.map(\n make(cfg),\n (s): LanguageModelService => ({\n streamTurn: (request) => s.streamTurn(request as MistralRequest),\n turn: (request) => s.turn(request as MistralRequest),\n }),\n ),\n )\n return Layer.merge(typed, generic)\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { MistralTranscribeRequest, MistralTranscriber, MistralTranscriberService } from "./MistralTranscriber.mjs";
2
+ import { t as Config } from "./realtimeStt-ClXWXbXX.mjs";
3
+ import { Effect, Layer } from "effect";
4
+ import { HttpClient } from "effect/unstable/http";
5
+ import { SttStreaming, Transcriber } from "@effect-uai/core/Transcriber";
6
+
7
+ //#region src/MistralRealtimeTranscriber.d.ts
8
+ declare namespace MistralRealtimeTranscriber_d_exports {
9
+ export { Config, MistralTranscribeRequest, MistralTranscriber, MistralTranscriberService, layer, make };
10
+ }
11
+ declare const make: (cfg: Config) => Effect.Effect<MistralTranscriberService, never, HttpClient.HttpClient>;
12
+ declare const layer: (cfg: Config) => Layer.Layer<MistralTranscriber | Transcriber | SttStreaming, never, HttpClient.HttpClient>;
13
+ //#endregion
14
+ export { type Config, type MistralTranscribeRequest, MistralTranscriber, type MistralTranscriberService, layer, make, MistralRealtimeTranscriber_d_exports as t };
15
+ //# sourceMappingURL=MistralRealtimeTranscriber.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistralRealtimeTranscriber.d.mts","names":[],"sources":["../src/MistralRealtimeTranscriber.ts"],"mappings":";;;;;;;;;;cAiCa,IAAA,GACX,GAAA,EAAK,MAAA,KACJ,MAAA,CAAO,MAAA,CAAO,yBAAA,SAAkC,UAAA,CAAW,UAAA;AAAA,cAOjD,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CAAM,kBAAA,GAAqB,WAAA,GAAc,YAAA,SAAqB,UAAA,CAAW,UAAA"}
@@ -0,0 +1,34 @@
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
+ import { MistralTranscriber, transcribeImpl } from "./MistralTranscriber.mjs";
3
+ import { streamTranscription } from "./realtimeStt.mjs";
4
+ import { Effect, Layer } from "effect";
5
+ import { HttpClient } from "effect/unstable/http";
6
+ import { SttStreaming, Transcriber } from "@effect-uai/core/Transcriber";
7
+ //#region src/MistralRealtimeTranscriber.ts
8
+ /**
9
+ * Realtime variant of `MistralTranscriber`. Wires `streamTranscriptionFrom`
10
+ * to the Voxtral Realtime WebSocket endpoint and registers the `SttStreaming`
11
+ * capability marker, so live-transcription calls compile against this Layer
12
+ * alone (unlike the sync-only `MistralTranscriber` Layer).
13
+ *
14
+ * Pulls in `ws` (optional peer dep) transitively via `./realtimeStt.js`.
15
+ * Node/Bun only — the browser `WebSocket` API can't set the `Authorization`
16
+ * header the WS upgrade requires.
17
+ */
18
+ var MistralRealtimeTranscriber_exports = /* @__PURE__ */ __exportAll({
19
+ MistralTranscriber: () => MistralTranscriber,
20
+ layer: () => layer,
21
+ make: () => make
22
+ });
23
+ const make = (cfg) => Effect.map(HttpClient.HttpClient.asEffect(), (client) => ({
24
+ transcribe: (request) => transcribeImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),
25
+ streamTranscriptionFrom: streamTranscription(cfg)
26
+ }));
27
+ const layer = (cfg) => Layer.mergeAll(Layer.effect(MistralTranscriber, make(cfg)), Layer.effect(Transcriber, Effect.map(make(cfg), (s) => ({
28
+ transcribe: (req) => s.transcribe(req),
29
+ streamTranscriptionFrom: s.streamTranscriptionFrom
30
+ }))), Layer.succeed(SttStreaming, void 0));
31
+ //#endregion
32
+ export { MistralTranscriber, layer, make, MistralRealtimeTranscriber_exports as t };
33
+
34
+ //# sourceMappingURL=MistralRealtimeTranscriber.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistralRealtimeTranscriber.mjs","names":[],"sources":["../src/MistralRealtimeTranscriber.ts"],"sourcesContent":["/**\n * Realtime variant of `MistralTranscriber`. Wires `streamTranscriptionFrom`\n * to the Voxtral Realtime WebSocket endpoint and registers the `SttStreaming`\n * capability marker, so live-transcription calls compile against this Layer\n * alone (unlike the sync-only `MistralTranscriber` Layer).\n *\n * Pulls in `ws` (optional peer dep) transitively via `./realtimeStt.js`.\n * Node/Bun only — the browser `WebSocket` API can't set the `Authorization`\n * header the WS upgrade requires.\n */\nimport { Effect, Layer } from \"effect\"\nimport { HttpClient } from \"effect/unstable/http\"\nimport {\n type CommonTranscribeRequest,\n SttStreaming,\n Transcriber,\n type TranscriberService,\n} from \"@effect-uai/core/Transcriber\"\nimport {\n MistralTranscriber,\n type MistralTranscriberService,\n type MistralTranscribeRequest,\n transcribeImpl,\n} from \"./MistralTranscriber.js\"\nimport { type Config, streamTranscription } from \"./realtimeStt.js\"\n\nexport type { Config } from \"./realtimeStt.js\"\nexport {\n MistralTranscriber,\n type MistralTranscriberService,\n type MistralTranscribeRequest,\n} from \"./MistralTranscriber.js\"\n\nexport const make = (\n cfg: Config,\n): Effect.Effect<MistralTranscriberService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient.asEffect(), (client) => ({\n transcribe: (request) =>\n transcribeImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamTranscriptionFrom: streamTranscription(cfg),\n }))\n\nexport const layer = (\n cfg: Config,\n): Layer.Layer<MistralTranscriber | Transcriber | SttStreaming, never, HttpClient.HttpClient> =>\n Layer.mergeAll(\n Layer.effect(MistralTranscriber, 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 MistralTranscribeRequest),\n streamTranscriptionFrom: s.streamTranscriptionFrom,\n }),\n ),\n ),\n Layer.succeed(SttStreaming, undefined),\n )\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAa,QACX,QAEA,OAAO,IAAI,WAAW,WAAW,UAAU,GAAG,YAAY;CACxD,aAAa,YACX,eAAe,IAAI,CAAC,QAAQ,CAAC,KAAK,OAAO,eAAe,WAAW,YAAY,OAAO,CAAC;CACzF,yBAAyB,oBAAoB,IAAI;CAClD,EAAE;AAEL,MAAa,SACX,QAEA,MAAM,SACJ,MAAM,OAAO,oBAAoB,KAAK,IAAI,CAAC,EAC3C,MAAM,OACJ,aACA,OAAO,IACL,KAAK,IAAI,GACR,OAA2B;CAC1B,aAAa,QACX,EAAE,WAAW,IAAgC;CAC/C,yBAAyB,EAAE;CAC5B,EACF,CACF,EACD,MAAM,QAAQ,cAAc,KAAA,EAAU,CACvC"}
@@ -0,0 +1,43 @@
1
+ import { i as MistralTtsModel } from "./models-DnDmylpj.mjs";
2
+ import { Context, Effect, Layer, Redacted, Stream } from "effect";
3
+ import { HttpClient } from "effect/unstable/http";
4
+ import * as AiError from "@effect-uai/core/AiError";
5
+ import { AudioBlob, AudioChunk } from "@effect-uai/core/Audio";
6
+ import { CommonStreamSynthesizeRequest, CommonSynthesizeRequest, SpeechSynthesizer, SpeechSynthesizerService, TtsIncrementalText } from "@effect-uai/core/SpeechSynthesizer";
7
+
8
+ //#region src/MistralSynthesizer.d.ts
9
+ declare namespace MistralSynthesizer_d_exports {
10
+ export { Config, MistralSynthesizeRequest, MistralSynthesizer, MistralSynthesizerService, layer, make };
11
+ }
12
+ /**
13
+ * Mistral-typed synthesize request. `model` narrows to `MistralTtsModel`;
14
+ * `voiceId` selects a saved Voxtral voice. `refAudio` (base64 of a 2-3s clip)
15
+ * triggers zero-shot voice cloning and takes precedence over `voiceId`.
16
+ */
17
+ type MistralSynthesizeRequest = Omit<CommonSynthesizeRequest, "model"> & {
18
+ readonly model: MistralTtsModel;
19
+ readonly refAudio?: string;
20
+ };
21
+ type MistralSynthesizerService = {
22
+ readonly synthesize: (request: MistralSynthesizeRequest) => Effect.Effect<AudioBlob, AiError.AiError>;
23
+ readonly streamSynthesis: (request: MistralSynthesizeRequest) => Stream.Stream<AudioChunk, AiError.AiError>;
24
+ readonly streamSynthesisFrom: <E, R>(textIn: Stream.Stream<string, E, R>, request: CommonStreamSynthesizeRequest) => Stream.Stream<AudioChunk, AiError.AiError | E, R>;
25
+ readonly synthesizeDialogue: SpeechSynthesizerService["synthesizeDialogue"];
26
+ readonly streamSynthesizeDialogue: SpeechSynthesizerService["streamSynthesizeDialogue"];
27
+ };
28
+ declare const MistralSynthesizer_base: Context.ServiceClass<MistralSynthesizer, "@betalyra/effect-uai/providers/mistral/MistralSynthesizer", MistralSynthesizerService>;
29
+ declare class MistralSynthesizer extends MistralSynthesizer_base {}
30
+ type Config = {
31
+ readonly apiKey: Redacted.Redacted;
32
+ readonly baseUrl?: string;
33
+ };
34
+ declare const make: (cfg: Config) => Effect.Effect<MistralSynthesizerService, never, HttpClient.HttpClient>;
35
+ /**
36
+ * Layer registering `MistralSynthesizer`, the generic `SpeechSynthesizer` tag,
37
+ * and the `TtsIncrementalText` capability marker (so `streamSynthesisFrom`
38
+ * composes — note the text side buffers; see its docs).
39
+ */
40
+ declare const layer: (cfg: Config) => Layer.Layer<MistralSynthesizer | SpeechSynthesizer | TtsIncrementalText, never, HttpClient.HttpClient>;
41
+ //#endregion
42
+ export { Config, MistralSynthesizeRequest, MistralSynthesizer, MistralSynthesizerService, layer, make, MistralSynthesizer_d_exports as t };
43
+ //# sourceMappingURL=MistralSynthesizer.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistralSynthesizer.d.mts","names":[],"sources":["../src/MistralSynthesizer.ts"],"mappings":";;;;;;;;;;;;;;;;KAmCY,wBAAA,GAA2B,IAAA,CAAK,uBAAA;EAAA,SACjC,KAAA,EAAO,eAAA;EAAA,SACP,QAAA;AAAA;AAAA,KAGC,yBAAA;EAAA,SACD,UAAA,GACP,OAAA,EAAS,wBAAA,KACN,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,OAAA,CAAQ,OAAA;EAAA,SAC7B,eAAA,GACP,OAAA,EAAS,wBAAA,KACN,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,OAAA;EAAA,SAC9B,mBAAA,SACP,MAAA,EAAQ,MAAA,CAAO,MAAA,SAAe,CAAA,EAAG,CAAA,GACjC,OAAA,EAAS,6BAAA,KACN,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,OAAA,GAAU,CAAA,EAAG,CAAA;EAAA,SAC3C,kBAAA,EAAoB,wBAAA;EAAA,SACpB,wBAAA,EAA0B,wBAAA;AAAA;AAAA,cACpC,uBAAA;cAEY,kBAAA,SAA2B,uBAAA;AAAA,KAK5B,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;AAAA;AAAA,cAmKE,IAAA,GACX,GAAA,EAAK,MAAA,KACJ,MAAA,CAAO,MAAA,CAAO,yBAAA,SAAkC,UAAA,CAAW,UAAA;;;AA3L9D;;;cA2Na,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CACP,kBAAA,GAAqB,iBAAA,GAAoB,kBAAA,SAEzC,UAAA,CAAW,UAAA"}
@@ -0,0 +1,121 @@
1
+ import { t as __exportAll } from "./chunk-CfYAbeIz.mjs";
2
+ import { httpStatusError, transportFailure } from "./http.mjs";
3
+ import { containerToTtsFormat, realizedTtsFormat } from "./audioCodec.mjs";
4
+ import { Array, Context, Effect, Encoding, Layer, Result, Schema, Stream } from "effect";
5
+ import { HttpClient, HttpClientRequest } from "effect/unstable/http";
6
+ import * as AiError from "@effect-uai/core/AiError";
7
+ import * as Capabilities from "@effect-uai/core/Capabilities";
8
+ import { SpeechSynthesizer, TtsIncrementalText } from "@effect-uai/core/SpeechSynthesizer";
9
+ //#region src/MistralSynthesizer.ts
10
+ var MistralSynthesizer_exports = /* @__PURE__ */ __exportAll({
11
+ MistralSynthesizer: () => MistralSynthesizer,
12
+ layer: () => layer,
13
+ make: () => make
14
+ });
15
+ var MistralSynthesizer = class extends Context.Service()("@betalyra/effect-uai/providers/mistral/MistralSynthesizer") {};
16
+ const defaultFormat = {
17
+ container: "mp3",
18
+ encoding: "mp3",
19
+ sampleRate: 24e3
20
+ };
21
+ const buildBody = (request) => Effect.gen(function* () {
22
+ if (request.pronunciations !== void 0 && request.pronunciations.length > 0) return yield* Effect.fail(new AiError.Unsupported({
23
+ provider: "mistral",
24
+ capability: "pronunciations",
25
+ reason: "Voxtral TTS has no phoneme field. Use a provider with a phoneme path (Inworld, Google) for pronunciation overrides."
26
+ }));
27
+ yield* Capabilities.warnDroppedWhen(request.speed, {
28
+ provider: "mistral",
29
+ capability: "speed",
30
+ field: "speed",
31
+ reason: "Voxtral TTS has no speed control; prosody follows the voice prompt."
32
+ });
33
+ yield* Capabilities.warnDroppedWhen(request.languageCode, {
34
+ provider: "mistral",
35
+ capability: "languageCode",
36
+ field: "languageCode",
37
+ reason: "Voxtral TTS auto-detects language and clones cross-lingually."
38
+ });
39
+ const responseFormat = yield* containerToTtsFormat((request.outputFormat ?? defaultFormat).container);
40
+ return {
41
+ body: {
42
+ model: request.model,
43
+ input: request.text,
44
+ response_format: responseFormat,
45
+ ...request.refAudio !== void 0 ? { ref_audio: request.refAudio } : { voice_id: request.voiceId }
46
+ },
47
+ format: realizedTtsFormat(responseFormat)
48
+ };
49
+ });
50
+ const buildHttpRequest = (cfg, body, accept) => HttpClientRequest.post(`${cfg.baseUrl ?? "https://api.mistral.ai"}/v1/audio/speech`).pipe(HttpClientRequest.bearerToken(cfg.apiKey), HttpClientRequest.accept(accept), HttpClientRequest.bodyJsonUnsafe(body));
51
+ const WireResponse = Schema.Struct({ audio_data: Schema.String });
52
+ const decodeResponse = Schema.decodeUnknownEffect(WireResponse);
53
+ const decodeAudioData = (b64) => Result.match(Encoding.decodeBase64(b64), {
54
+ onSuccess: Effect.succeed,
55
+ onFailure: (cause) => Effect.fail(new AiError.InvalidRequest({
56
+ provider: "mistral",
57
+ param: "audio_data",
58
+ raw: cause
59
+ }))
60
+ });
61
+ const synthesizeImpl = (cfg) => (request) => Effect.gen(function* () {
62
+ const client = yield* HttpClient.HttpClient;
63
+ const { body, format } = yield* buildBody(request);
64
+ const response = yield* client.execute(buildHttpRequest(cfg, body, "application/json")).pipe(Effect.mapError(transportFailure));
65
+ if (response.status >= 400) {
66
+ const text = yield* response.text.pipe(Effect.orElseSucceed(() => ""));
67
+ yield* Effect.logWarning("[voxtral-tts] request failed", {
68
+ status: response.status,
69
+ body: text
70
+ });
71
+ return yield* Effect.fail(httpStatusError(response.status, text));
72
+ }
73
+ const bytes = yield* decodeAudioData((yield* decodeResponse(yield* response.json.pipe(Effect.mapError(transportFailure))).pipe(Effect.mapError(transportFailure))).audio_data);
74
+ yield* Effect.logDebug("[voxtral-tts] ok", {
75
+ bytes: bytes.byteLength,
76
+ voice: request.voiceId
77
+ });
78
+ return {
79
+ format,
80
+ bytes
81
+ };
82
+ });
83
+ const FRAME_BYTES = 8192;
84
+ const sliceIntoChunks = (bytes) => Array.makeBy(Math.max(1, Math.ceil(bytes.byteLength / FRAME_BYTES)), (i) => ({ bytes: bytes.subarray(i * FRAME_BYTES, (i + 1) * FRAME_BYTES) }));
85
+ const streamSynthesisImpl = (cfg) => (request) => Stream.unwrap(Effect.map(synthesizeImpl(cfg)(request), (blob) => Stream.fromIterable(sliceIntoChunks(blob.bytes))));
86
+ const synthesizeDialogueUnsupported = () => Effect.fail(new AiError.Unsupported({
87
+ provider: "mistral",
88
+ capability: "synthesizeDialogue",
89
+ reason: "Voxtral TTS has no multi-speaker dialogue endpoint."
90
+ }));
91
+ const streamSynthesizeDialogueUnsupported = () => Stream.fail(new AiError.Unsupported({
92
+ provider: "mistral",
93
+ capability: "streamSynthesizeDialogue",
94
+ reason: "Voxtral TTS has no multi-speaker dialogue endpoint."
95
+ }));
96
+ const make = (cfg) => Effect.map(HttpClient.HttpClient.asEffect(), (client) => ({
97
+ synthesize: (request) => synthesizeImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),
98
+ streamSynthesis: (request) => streamSynthesisImpl(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client)),
99
+ streamSynthesisFrom: (textIn, request) => Stream.unwrap(Effect.map(Stream.runFold(textIn, () => "", (acc, s) => acc + s), (text) => streamSynthesisImpl(cfg)({
100
+ ...request,
101
+ text
102
+ }).pipe(Stream.provideService(HttpClient.HttpClient, client)))),
103
+ synthesizeDialogue: synthesizeDialogueUnsupported,
104
+ streamSynthesizeDialogue: streamSynthesizeDialogueUnsupported
105
+ }));
106
+ /**
107
+ * Layer registering `MistralSynthesizer`, the generic `SpeechSynthesizer` tag,
108
+ * and the `TtsIncrementalText` capability marker (so `streamSynthesisFrom`
109
+ * composes — note the text side buffers; see its docs).
110
+ */
111
+ const layer = (cfg) => Layer.mergeAll(Layer.effect(MistralSynthesizer, make(cfg)), Layer.effect(SpeechSynthesizer, Effect.map(make(cfg), (s) => ({
112
+ synthesize: (req) => s.synthesize(req),
113
+ streamSynthesis: (req) => s.streamSynthesis(req),
114
+ streamSynthesisFrom: s.streamSynthesisFrom,
115
+ synthesizeDialogue: s.synthesizeDialogue,
116
+ streamSynthesizeDialogue: s.streamSynthesizeDialogue
117
+ }))), Layer.succeed(TtsIncrementalText, void 0));
118
+ //#endregion
119
+ export { MistralSynthesizer, layer, make, MistralSynthesizer_exports as t };
120
+
121
+ //# sourceMappingURL=MistralSynthesizer.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistralSynthesizer.mjs","names":["Arr"],"sources":["../src/MistralSynthesizer.ts"],"sourcesContent":["import {\n Array as Arr,\n Context,\n Effect,\n Encoding,\n Layer,\n Redacted,\n Result,\n Schema,\n Stream,\n} from \"effect\"\nimport { HttpClient, HttpClientRequest } from \"effect/unstable/http\"\nimport * as AiError from \"@effect-uai/core/AiError\"\nimport type { AudioBlob, AudioChunk, AudioFormat } from \"@effect-uai/core/Audio\"\nimport * as Capabilities from \"@effect-uai/core/Capabilities\"\nimport {\n type CommonStreamSynthesizeRequest,\n type CommonSynthesizeRequest,\n SpeechSynthesizer,\n type SpeechSynthesizerService,\n TtsIncrementalText,\n} from \"@effect-uai/core/SpeechSynthesizer\"\nimport { containerToTtsFormat, type MistralTtsFormat, realizedTtsFormat } from \"./audioCodec.js\"\nimport { httpStatusError, transportFailure } from \"./http.js\"\nimport type { MistralTtsModel } from \"./models.js\"\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Mistral-typed synthesize request. `model` narrows to `MistralTtsModel`;\n * `voiceId` selects a saved Voxtral voice. `refAudio` (base64 of a 2-3s clip)\n * triggers zero-shot voice cloning and takes precedence over `voiceId`.\n */\nexport type MistralSynthesizeRequest = Omit<CommonSynthesizeRequest, \"model\"> & {\n readonly model: MistralTtsModel\n readonly refAudio?: string\n}\n\nexport type MistralSynthesizerService = {\n readonly synthesize: (\n request: MistralSynthesizeRequest,\n ) => Effect.Effect<AudioBlob, AiError.AiError>\n readonly streamSynthesis: (\n request: MistralSynthesizeRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError>\n readonly streamSynthesisFrom: <E, R>(\n textIn: Stream.Stream<string, E, R>,\n request: CommonStreamSynthesizeRequest,\n ) => Stream.Stream<AudioChunk, AiError.AiError | E, R>\n readonly synthesizeDialogue: SpeechSynthesizerService[\"synthesizeDialogue\"]\n readonly streamSynthesizeDialogue: SpeechSynthesizerService[\"streamSynthesizeDialogue\"]\n}\n\nexport class MistralSynthesizer extends Context.Service<\n MistralSynthesizer,\n MistralSynthesizerService\n>()(\"@betalyra/effect-uai/providers/mistral/MistralSynthesizer\") {}\n\nexport type Config = {\n readonly apiKey: Redacted.Redacted\n readonly baseUrl?: string\n}\n\n// ---------------------------------------------------------------------------\n// Codec — request → JSON body\n// ---------------------------------------------------------------------------\n\nconst defaultFormat: AudioFormat = { container: \"mp3\", encoding: \"mp3\", sampleRate: 24000 }\n\ntype WireBody = {\n readonly model: string\n readonly input: string\n readonly response_format: MistralTtsFormat\n readonly voice_id?: string\n readonly ref_audio?: string\n}\n\nconst buildBody = (\n request: MistralSynthesizeRequest,\n): Effect.Effect<{ readonly body: WireBody; readonly format: AudioFormat }, AiError.AiError> =>\n Effect.gen(function* () {\n // Voxtral has no phoneme field; pronunciations are load-bearing, so reject\n // rather than silently mispronounce.\n if (request.pronunciations !== undefined && request.pronunciations.length > 0) {\n return yield* Effect.fail(\n new AiError.Unsupported({\n provider: \"mistral\",\n capability: \"pronunciations\",\n reason:\n \"Voxtral TTS has no phoneme field. Use a provider with a phoneme path (Inworld, Google) for pronunciation overrides.\",\n }),\n )\n }\n yield* Capabilities.warnDroppedWhen(request.speed, {\n provider: \"mistral\",\n capability: \"speed\",\n field: \"speed\",\n reason: \"Voxtral TTS has no speed control; prosody follows the voice prompt.\",\n })\n yield* Capabilities.warnDroppedWhen(request.languageCode, {\n provider: \"mistral\",\n capability: \"languageCode\",\n field: \"languageCode\",\n reason: \"Voxtral TTS auto-detects language and clones cross-lingually.\",\n })\n const responseFormat = yield* containerToTtsFormat(\n (request.outputFormat ?? defaultFormat).container,\n )\n return {\n body: {\n model: request.model,\n input: request.text,\n response_format: responseFormat,\n // Cloning clip wins over a saved voice id when both are present.\n ...(request.refAudio !== undefined\n ? { ref_audio: request.refAudio }\n : { voice_id: request.voiceId }),\n },\n format: realizedTtsFormat(responseFormat),\n }\n })\n\n// ---------------------------------------------------------------------------\n// HTTP plumbing\n// ---------------------------------------------------------------------------\n\nconst buildHttpRequest = (cfg: Config, body: WireBody, accept: string) =>\n HttpClientRequest.post(`${cfg.baseUrl ?? \"https://api.mistral.ai\"}/v1/audio/speech`).pipe(\n HttpClientRequest.bearerToken(cfg.apiKey),\n HttpClientRequest.accept(accept),\n HttpClientRequest.bodyJsonUnsafe(body),\n )\n\n// One-shot response: base64 audio. Voxtral's streaming SSE wraps this same\n// payload; since `streamSynthesisFrom` buffers the whole utterance anyway, we\n// drive everything off the simpler one-shot endpoint and slice for pacing.\nconst WireResponse = Schema.Struct({ audio_data: Schema.String })\nconst decodeResponse = Schema.decodeUnknownEffect(WireResponse)\n\nconst decodeAudioData = (b64: string): Effect.Effect<Uint8Array, AiError.AiError> =>\n Result.match(Encoding.decodeBase64(b64), {\n onSuccess: Effect.succeed,\n onFailure: (cause) =>\n Effect.fail(\n new AiError.InvalidRequest({ provider: \"mistral\", param: \"audio_data\", raw: cause }),\n ),\n })\n\nconst synthesizeImpl =\n (cfg: Config) =>\n (\n request: MistralSynthesizeRequest,\n ): Effect.Effect<AudioBlob, AiError.AiError, HttpClient.HttpClient> =>\n Effect.gen(function* () {\n const client = yield* HttpClient.HttpClient\n const { body, format } = yield* buildBody(request)\n const response = yield* client\n .execute(buildHttpRequest(cfg, body, \"application/json\"))\n .pipe(Effect.mapError(transportFailure))\n if (response.status >= 400) {\n const text = yield* response.text.pipe(Effect.orElseSucceed(() => \"\"))\n yield* Effect.logWarning(\"[voxtral-tts] request failed\", {\n status: response.status,\n body: text,\n })\n return yield* Effect.fail(httpStatusError(response.status, text))\n }\n const json = yield* response.json.pipe(Effect.mapError(transportFailure))\n const decoded = yield* decodeResponse(json).pipe(Effect.mapError(transportFailure))\n const bytes = yield* decodeAudioData(decoded.audio_data)\n yield* Effect.logDebug(\"[voxtral-tts] ok\", {\n bytes: bytes.byteLength,\n voice: request.voiceId,\n })\n return { format, bytes }\n })\n\n// ~40 ms frames so the voice loop can pace playback and cut on interrupt.\nconst FRAME_BYTES = 8192\n\nconst sliceIntoChunks = (bytes: Uint8Array): ReadonlyArray<AudioChunk> =>\n Arr.makeBy(Math.max(1, Math.ceil(bytes.byteLength / FRAME_BYTES)), (i) => ({\n bytes: bytes.subarray(i * FRAME_BYTES, (i + 1) * FRAME_BYTES),\n }))\n\nconst streamSynthesisImpl =\n (cfg: Config) =>\n (\n request: MistralSynthesizeRequest,\n ): Stream.Stream<AudioChunk, AiError.AiError, HttpClient.HttpClient> =>\n Stream.unwrap(\n Effect.map(synthesizeImpl(cfg)(request), (blob) =>\n Stream.fromIterable(sliceIntoChunks(blob.bytes)),\n ),\n )\n\n// ---------------------------------------------------------------------------\n// Dialogue — unsupported (Voxtral has no multi-speaker endpoint)\n// ---------------------------------------------------------------------------\n\nconst synthesizeDialogueUnsupported: SpeechSynthesizerService[\"synthesizeDialogue\"] = () =>\n Effect.fail(\n new AiError.Unsupported({\n provider: \"mistral\",\n capability: \"synthesizeDialogue\",\n reason: \"Voxtral TTS has no multi-speaker dialogue endpoint.\",\n }),\n )\n\nconst streamSynthesizeDialogueUnsupported: SpeechSynthesizerService[\"streamSynthesizeDialogue\"] =\n () =>\n Stream.fail(\n new AiError.Unsupported({\n provider: \"mistral\",\n capability: \"streamSynthesizeDialogue\",\n reason: \"Voxtral TTS has no multi-speaker dialogue endpoint.\",\n }),\n )\n\n// ---------------------------------------------------------------------------\n// Constructors\n// ---------------------------------------------------------------------------\n\nexport const make = (\n cfg: Config,\n): Effect.Effect<MistralSynthesizerService, never, HttpClient.HttpClient> =>\n Effect.map(HttpClient.HttpClient.asEffect(), (client) => ({\n synthesize: (request) =>\n synthesizeImpl(cfg)(request).pipe(Effect.provideService(HttpClient.HttpClient, client)),\n streamSynthesis: (request) =>\n streamSynthesisImpl(cfg)(request).pipe(Stream.provideService(HttpClient.HttpClient, client)),\n // Voxtral has no incremental-text-in WS endpoint, so we fold the text\n // stream into one utterance and hand it to the chunked streaming endpoint.\n // Audio still streams out; only the text side buffers (one turn per call).\n streamSynthesisFrom: (textIn, request) =>\n Stream.unwrap(\n Effect.map(\n Stream.runFold(\n textIn,\n () => \"\",\n (acc, s) => acc + s,\n ),\n (text) =>\n streamSynthesisImpl(cfg)({ ...request, text } as MistralSynthesizeRequest).pipe(\n Stream.provideService(HttpClient.HttpClient, client),\n ),\n ),\n ),\n synthesizeDialogue: synthesizeDialogueUnsupported,\n streamSynthesizeDialogue: streamSynthesizeDialogueUnsupported,\n }))\n\n/**\n * Layer registering `MistralSynthesizer`, the generic `SpeechSynthesizer` tag,\n * and the `TtsIncrementalText` capability marker (so `streamSynthesisFrom`\n * composes — note the text side buffers; see its docs).\n */\nexport const layer = (\n cfg: Config,\n): Layer.Layer<\n MistralSynthesizer | SpeechSynthesizer | TtsIncrementalText,\n never,\n HttpClient.HttpClient\n> =>\n Layer.mergeAll(\n Layer.effect(MistralSynthesizer, 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 MistralSynthesizeRequest),\n streamSynthesis: (req: CommonSynthesizeRequest) =>\n s.streamSynthesis(req as MistralSynthesizeRequest),\n streamSynthesisFrom: s.streamSynthesisFrom,\n synthesizeDialogue: s.synthesizeDialogue,\n streamSynthesizeDialogue: s.streamSynthesizeDialogue,\n }),\n ),\n ),\n Layer.succeed(TtsIncrementalText, undefined),\n )\n"],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { r as MistralTranscribeModel } from "./models-DnDmylpj.mjs";
2
+ import { Context, Effect, Layer, Redacted, Stream } from "effect";
3
+ import { HttpClient } from "effect/unstable/http";
4
+ import * as AiError from "@effect-uai/core/AiError";
5
+ import { CommonStreamTranscribeRequest, CommonTranscribeRequest, Transcriber } from "@effect-uai/core/Transcriber";
6
+ import { TranscriptEvent, TranscriptResult } from "@effect-uai/core/Transcript";
7
+
8
+ //#region src/MistralTranscriber.d.ts
9
+ declare namespace MistralTranscriber_d_exports {
10
+ export { Config, MistralTranscribeRequest, MistralTranscriber, MistralTranscriberService, layer, make, transcribeImpl };
11
+ }
12
+ /**
13
+ * Mistral-typed transcribe request. `model` narrows to the typed
14
+ * `MistralTranscribeModel` union; `fileName` overrides the multipart upload's
15
+ * filename. Voxtral's batch endpoint supports diarization, word timestamps,
16
+ * and context biasing.
17
+ */
18
+ type MistralTranscribeRequest = Omit<CommonTranscribeRequest, "model"> & {
19
+ readonly model: MistralTranscribeModel;
20
+ readonly temperature?: number;
21
+ readonly fileName?: string;
22
+ };
23
+ type MistralTranscriberService = {
24
+ readonly transcribe: (request: MistralTranscribeRequest) => Effect.Effect<TranscriptResult, AiError.AiError>;
25
+ readonly streamTranscriptionFrom: <E, R>(audioIn: Stream.Stream<Uint8Array, E, R>, request: CommonStreamTranscribeRequest) => Stream.Stream<TranscriptEvent, AiError.AiError | E, R>;
26
+ };
27
+ declare const MistralTranscriber_base: Context.ServiceClass<MistralTranscriber, "@betalyra/effect-uai/providers/mistral/MistralTranscriber", MistralTranscriberService>;
28
+ declare class MistralTranscriber extends MistralTranscriber_base {}
29
+ type Config = {
30
+ readonly apiKey: Redacted.Redacted;
31
+ readonly baseUrl?: string;
32
+ };
33
+ /** Exported for reuse by `MistralRealtimeTranscriber` (same sync path). */
34
+ declare const transcribeImpl: (cfg: Config) => (request: MistralTranscribeRequest) => Effect.Effect<TranscriptResult, AiError.AiError, HttpClient.HttpClient>;
35
+ declare const make: (cfg: Config) => Effect.Effect<MistralTranscriberService, never, HttpClient.HttpClient>;
36
+ /**
37
+ * Sync-only Layer. Registers `MistralTranscriber` + the generic `Transcriber`
38
+ * tag. Does NOT register `SttStreaming` — for live transcription use
39
+ * `@effect-uai/mistral/MistralRealtimeTranscriber`.
40
+ */
41
+ declare const layer: (cfg: Config) => Layer.Layer<MistralTranscriber | Transcriber, never, HttpClient.HttpClient>;
42
+ //#endregion
43
+ export { Config, MistralTranscribeRequest, MistralTranscriber, MistralTranscriberService, layer, make, MistralTranscriber_d_exports as t, transcribeImpl };
44
+ //# sourceMappingURL=MistralTranscriber.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MistralTranscriber.d.mts","names":[],"sources":["../src/MistralTranscriber.ts"],"mappings":";;;;;;;;;;;;;;;;;KA0BY,wBAAA,GAA2B,IAAA,CAAK,uBAAA;EAAA,SACjC,KAAA,EAAO,sBAAA;EAAA,SACP,WAAA;EAAA,SACA,QAAA;AAAA;AAAA,KAGC,yBAAA;EAAA,SACD,UAAA,GACP,OAAA,EAAS,wBAAA,KACN,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,OAAA,CAAQ,OAAA;EAAA,SACpC,uBAAA,SACP,OAAA,EAAS,MAAA,CAAO,MAAA,CAAO,UAAA,EAAY,CAAA,EAAG,CAAA,GACtC,OAAA,EAAS,6BAAA,KACN,MAAA,CAAO,MAAA,CAAO,eAAA,EAAiB,OAAA,CAAQ,OAAA,GAAU,CAAA,EAAG,CAAA;AAAA;AAAA,cAC1D,uBAAA;cAEY,kBAAA,SAA2B,uBAAA;AAAA,KAK5B,MAAA;EAAA,SACD,MAAA,EAAQ,QAAA,CAAS,QAAA;EAAA,SACjB,OAAA;AAAA;;cA+FE,cAAA,GACV,GAAA,EAAK,MAAA,MAEJ,OAAA,EAAS,wBAAA,KACR,MAAA,CAAO,MAAA,CAAO,gBAAA,EAAkB,OAAA,CAAQ,OAAA,EAAS,UAAA,CAAW,UAAA;AAAA,cA6CpD,IAAA,GACX,GAAA,EAAK,MAAA,KACJ,MAAA,CAAO,MAAA,CAAO,yBAAA,SAAkC,UAAA,CAAW,UAAA;;;;AAnK9D;;cA+Ka,KAAA,GACX,GAAA,EAAK,MAAA,KACJ,KAAA,CAAM,KAAA,CAAM,kBAAA,GAAqB,WAAA,SAAoB,UAAA,CAAW,UAAA"}