@mistralai/mistralai 1.13.0 → 1.14.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 (184) hide show
  1. package/README.md +5 -1
  2. package/examples/src/async_audio_transcription_diarize.ts +17 -0
  3. package/examples/src/realtime_microphone.ts +163 -0
  4. package/examples/src/realtime_transcription.ts +225 -0
  5. package/extra/realtime/connection.d.ts +43 -0
  6. package/extra/realtime/connection.d.ts.map +1 -0
  7. package/extra/realtime/connection.js +293 -0
  8. package/extra/realtime/connection.js.map +1 -0
  9. package/extra/realtime/errors.d.ts +18 -0
  10. package/extra/realtime/errors.d.ts.map +1 -0
  11. package/extra/realtime/errors.js +21 -0
  12. package/extra/realtime/errors.js.map +1 -0
  13. package/extra/realtime/index.d.ts +15 -0
  14. package/extra/realtime/index.d.ts.map +1 -0
  15. package/extra/realtime/index.js +10 -0
  16. package/extra/realtime/index.js.map +1 -0
  17. package/extra/realtime/transcription.d.ts +17 -0
  18. package/extra/realtime/transcription.d.ts.map +1 -0
  19. package/extra/realtime/transcription.js +197 -0
  20. package/extra/realtime/transcription.js.map +1 -0
  21. package/funcs/audioTranscriptionsComplete.js +6 -0
  22. package/funcs/audioTranscriptionsComplete.js.map +1 -1
  23. package/funcs/audioTranscriptionsStream.js +6 -0
  24. package/funcs/audioTranscriptionsStream.js.map +1 -1
  25. package/funcs/betaAgentsCreateVersionAlias.d.ts +19 -0
  26. package/funcs/betaAgentsCreateVersionAlias.d.ts.map +1 -0
  27. package/funcs/betaAgentsCreateVersionAlias.js +130 -0
  28. package/funcs/betaAgentsCreateVersionAlias.js.map +1 -0
  29. package/funcs/betaAgentsGet.d.ts +1 -1
  30. package/funcs/betaAgentsGet.js +1 -1
  31. package/funcs/betaAgentsGetVersion.js +1 -1
  32. package/funcs/betaAgentsGetVersion.js.map +1 -1
  33. package/funcs/betaAgentsListVersionAliases.d.ts +19 -0
  34. package/funcs/betaAgentsListVersionAliases.d.ts.map +1 -0
  35. package/funcs/betaAgentsListVersionAliases.js +126 -0
  36. package/funcs/betaAgentsListVersionAliases.js.map +1 -0
  37. package/funcs/filesList.js +1 -0
  38. package/funcs/filesList.js.map +1 -1
  39. package/jsr.json +1 -1
  40. package/lib/config.d.ts +2 -2
  41. package/lib/config.js +2 -2
  42. package/models/components/agentaliasresponse.d.ts +13 -0
  43. package/models/components/agentaliasresponse.d.ts.map +1 -0
  44. package/models/components/agentaliasresponse.js +59 -0
  45. package/models/components/agentaliasresponse.js.map +1 -0
  46. package/models/components/agentconversation.d.ts +5 -1
  47. package/models/components/agentconversation.d.ts.map +1 -1
  48. package/models/components/agentconversation.js +8 -2
  49. package/models/components/agentconversation.js.map +1 -1
  50. package/models/components/audiotranscriptionrequest.d.ts +4 -0
  51. package/models/components/audiotranscriptionrequest.d.ts.map +1 -1
  52. package/models/components/audiotranscriptionrequest.js +3 -0
  53. package/models/components/audiotranscriptionrequest.js.map +1 -1
  54. package/models/components/audiotranscriptionrequeststream.d.ts +4 -0
  55. package/models/components/audiotranscriptionrequeststream.d.ts.map +1 -1
  56. package/models/components/audiotranscriptionrequeststream.js +3 -0
  57. package/models/components/audiotranscriptionrequeststream.js.map +1 -1
  58. package/models/components/conversationrequest.d.ts +8 -2
  59. package/models/components/conversationrequest.d.ts.map +1 -1
  60. package/models/components/conversationrequest.js +8 -2
  61. package/models/components/conversationrequest.js.map +1 -1
  62. package/models/components/conversationrestartrequest.d.ts +11 -2
  63. package/models/components/conversationrestartrequest.d.ts.map +1 -1
  64. package/models/components/conversationrestartrequest.js +8 -2
  65. package/models/components/conversationrestartrequest.js.map +1 -1
  66. package/models/components/conversationrestartstreamrequest.d.ts +11 -2
  67. package/models/components/conversationrestartstreamrequest.d.ts.map +1 -1
  68. package/models/components/conversationrestartstreamrequest.js +8 -2
  69. package/models/components/conversationrestartstreamrequest.js.map +1 -1
  70. package/models/components/conversationstreamrequest.d.ts +8 -2
  71. package/models/components/conversationstreamrequest.d.ts.map +1 -1
  72. package/models/components/conversationstreamrequest.js +8 -2
  73. package/models/components/conversationstreamrequest.js.map +1 -1
  74. package/models/components/index.d.ts +6 -0
  75. package/models/components/index.d.ts.map +1 -1
  76. package/models/components/index.js +6 -0
  77. package/models/components/index.js.map +1 -1
  78. package/models/components/mistralpromptmode.d.ts +14 -0
  79. package/models/components/mistralpromptmode.d.ts.map +1 -1
  80. package/models/components/mistralpromptmode.js +7 -0
  81. package/models/components/mistralpromptmode.js.map +1 -1
  82. package/models/components/modelcapabilities.d.ts +1 -0
  83. package/models/components/modelcapabilities.d.ts.map +1 -1
  84. package/models/components/modelcapabilities.js +2 -0
  85. package/models/components/modelcapabilities.js.map +1 -1
  86. package/models/components/realtimetranscriptionerror.d.ts +20 -0
  87. package/models/components/realtimetranscriptionerror.d.ts.map +1 -0
  88. package/models/components/realtimetranscriptionerror.js +61 -0
  89. package/models/components/realtimetranscriptionerror.js.map +1 -0
  90. package/models/components/realtimetranscriptionerrordetail.d.ts +45 -0
  91. package/models/components/realtimetranscriptionerrordetail.d.ts.map +1 -0
  92. package/models/components/realtimetranscriptionerrordetail.js +72 -0
  93. package/models/components/realtimetranscriptionerrordetail.js.map +1 -0
  94. package/models/components/realtimetranscriptionsession.d.ts +22 -0
  95. package/models/components/realtimetranscriptionsession.d.ts.map +1 -0
  96. package/models/components/realtimetranscriptionsession.js +74 -0
  97. package/models/components/realtimetranscriptionsession.js.map +1 -0
  98. package/models/components/realtimetranscriptionsessioncreated.d.ts +20 -0
  99. package/models/components/realtimetranscriptionsessioncreated.d.ts.map +1 -0
  100. package/models/components/realtimetranscriptionsessioncreated.js +61 -0
  101. package/models/components/realtimetranscriptionsessioncreated.js.map +1 -0
  102. package/models/components/realtimetranscriptionsessionupdated.d.ts +20 -0
  103. package/models/components/realtimetranscriptionsessionupdated.d.ts.map +1 -0
  104. package/models/components/realtimetranscriptionsessionupdated.js +61 -0
  105. package/models/components/realtimetranscriptionsessionupdated.js.map +1 -0
  106. package/models/components/timestampgranularity.d.ts +1 -0
  107. package/models/components/timestampgranularity.d.ts.map +1 -1
  108. package/models/components/timestampgranularity.js +1 -0
  109. package/models/components/timestampgranularity.js.map +1 -1
  110. package/models/components/transcriptionsegmentchunk.d.ts +4 -0
  111. package/models/components/transcriptionsegmentchunk.d.ts.map +1 -1
  112. package/models/components/transcriptionsegmentchunk.js +10 -1
  113. package/models/components/transcriptionsegmentchunk.js.map +1 -1
  114. package/models/components/transcriptionstreamsegmentdelta.d.ts +1 -0
  115. package/models/components/transcriptionstreamsegmentdelta.d.ts.map +1 -1
  116. package/models/components/transcriptionstreamsegmentdelta.js +7 -1
  117. package/models/components/transcriptionstreamsegmentdelta.js.map +1 -1
  118. package/models/operations/agentsapiv1agentscreateorupdatealias.d.ts +16 -0
  119. package/models/operations/agentsapiv1agentscreateorupdatealias.d.ts.map +1 -0
  120. package/models/operations/agentsapiv1agentscreateorupdatealias.js +56 -0
  121. package/models/operations/agentsapiv1agentscreateorupdatealias.js.map +1 -0
  122. package/models/operations/agentsapiv1agentsget.d.ts +8 -2
  123. package/models/operations/agentsapiv1agentsget.d.ts.map +1 -1
  124. package/models/operations/agentsapiv1agentsget.js +8 -2
  125. package/models/operations/agentsapiv1agentsget.js.map +1 -1
  126. package/models/operations/agentsapiv1agentsgetversion.d.ts +2 -2
  127. package/models/operations/agentsapiv1agentsgetversion.js +1 -1
  128. package/models/operations/agentsapiv1agentsgetversion.js.map +1 -1
  129. package/models/operations/agentsapiv1agentslistversionaliases.d.ts +12 -0
  130. package/models/operations/agentsapiv1agentslistversionaliases.d.ts.map +1 -0
  131. package/models/operations/agentsapiv1agentslistversionaliases.js +54 -0
  132. package/models/operations/agentsapiv1agentslistversionaliases.js.map +1 -0
  133. package/models/operations/filesapirouteslistfiles.d.ts +2 -0
  134. package/models/operations/filesapirouteslistfiles.d.ts.map +1 -1
  135. package/models/operations/filesapirouteslistfiles.js +1 -0
  136. package/models/operations/filesapirouteslistfiles.js.map +1 -1
  137. package/models/operations/index.d.ts +2 -0
  138. package/models/operations/index.d.ts.map +1 -1
  139. package/models/operations/index.js +2 -0
  140. package/models/operations/index.js.map +1 -1
  141. package/package.json +4 -1
  142. package/sdk/mistralagents.d.ts +15 -1
  143. package/sdk/mistralagents.d.ts.map +1 -1
  144. package/sdk/mistralagents.js +21 -1
  145. package/sdk/mistralagents.js.map +1 -1
  146. package/src/extra/realtime/connection.ts +451 -0
  147. package/src/extra/realtime/errors.ts +32 -0
  148. package/src/extra/realtime/index.ts +32 -0
  149. package/src/extra/realtime/transcription.ts +288 -0
  150. package/src/funcs/audioTranscriptionsComplete.ts +6 -0
  151. package/src/funcs/audioTranscriptionsStream.ts +6 -0
  152. package/src/funcs/betaAgentsCreateVersionAlias.ts +184 -0
  153. package/src/funcs/betaAgentsGet.ts +1 -1
  154. package/src/funcs/betaAgentsGetVersion.ts +1 -1
  155. package/src/funcs/betaAgentsListVersionAliases.ts +179 -0
  156. package/src/funcs/filesList.ts +1 -0
  157. package/src/lib/config.ts +2 -2
  158. package/src/models/components/agentaliasresponse.ts +43 -0
  159. package/src/models/components/agentconversation.ts +21 -2
  160. package/src/models/components/audiotranscriptionrequest.ts +7 -0
  161. package/src/models/components/audiotranscriptionrequeststream.ts +7 -0
  162. package/src/models/components/conversationrequest.ts +19 -3
  163. package/src/models/components/conversationrestartrequest.ts +29 -3
  164. package/src/models/components/conversationrestartstreamrequest.ts +32 -3
  165. package/src/models/components/conversationstreamrequest.ts +25 -3
  166. package/src/models/components/index.ts +6 -0
  167. package/src/models/components/mistralpromptmode.ts +14 -0
  168. package/src/models/components/modelcapabilities.ts +3 -0
  169. package/src/models/components/realtimetranscriptionerror.ts +61 -0
  170. package/src/models/components/realtimetranscriptionerrordetail.ts +94 -0
  171. package/src/models/components/realtimetranscriptionsession.ts +78 -0
  172. package/src/models/components/realtimetranscriptionsessioncreated.ts +64 -0
  173. package/src/models/components/realtimetranscriptionsessionupdated.ts +64 -0
  174. package/src/models/components/timestampgranularity.ts +1 -0
  175. package/src/models/components/transcriptionsegmentchunk.ts +14 -1
  176. package/src/models/components/transcriptionstreamsegmentdelta.ts +8 -1
  177. package/src/models/operations/agentsapiv1agentscreateorupdatealias.ts +46 -0
  178. package/src/models/operations/agentsapiv1agentsget.ts +19 -3
  179. package/src/models/operations/agentsapiv1agentsgetversion.ts +3 -3
  180. package/src/models/operations/agentsapiv1agentslistversionaliases.ts +40 -0
  181. package/src/models/operations/filesapirouteslistfiles.ts +3 -0
  182. package/src/models/operations/index.ts +2 -0
  183. package/src/sdk/mistralagents.ts +37 -1
  184. package/tests/extra/realtime.test.ts +381 -0
package/README.md CHANGED
@@ -240,6 +240,8 @@ We have dedicated SDKs for the following providers:
240
240
  * [updateVersion](docs/sdks/mistralagents/README.md#updateversion) - Update an agent version.
241
241
  * [listVersions](docs/sdks/mistralagents/README.md#listversions) - List all versions of an agent.
242
242
  * [getVersion](docs/sdks/mistralagents/README.md#getversion) - Retrieve a specific version of an agent.
243
+ * [createVersionAlias](docs/sdks/mistralagents/README.md#createversionalias) - Create or update an agent version alias.
244
+ * [listVersionAliases](docs/sdks/mistralagents/README.md#listversionaliases) - List all aliases for an agent.
243
245
 
244
246
  ### [Beta.Conversations](docs/sdks/conversations/README.md)
245
247
 
@@ -552,7 +554,7 @@ run();
552
554
 
553
555
 
554
556
  **Inherit from [`MistralError`](./src/models/errors/mistralerror.ts)**:
555
- * [`HTTPValidationError`](./src/models/errors/httpvalidationerror.ts): Validation Error. Status code `422`. Applicable to 50 of 72 methods.*
557
+ * [`HTTPValidationError`](./src/models/errors/httpvalidationerror.ts): Validation Error. Status code `422`. Applicable to 52 of 74 methods.*
556
558
  * [`ResponseValidationError`](./src/models/errors/responsevalidationerror.ts): Type mismatch between the data returned from the server and the structure expected by the SDK. See `error.rawValue` for the raw value and `error.pretty()` for a nicely formatted multi-line string.
557
559
 
558
560
  </details>
@@ -723,10 +725,12 @@ To read more about standalone functions, check [FUNCTIONS.md](./FUNCTIONS.md).
723
725
  - [`batchJobsGet`](docs/sdks/mistraljobs/README.md#get) - Get Batch Job
724
726
  - [`batchJobsList`](docs/sdks/mistraljobs/README.md#list) - Get Batch Jobs
725
727
  - [`betaAgentsCreate`](docs/sdks/mistralagents/README.md#create) - Create a agent that can be used within a conversation.
728
+ - [`betaAgentsCreateVersionAlias`](docs/sdks/mistralagents/README.md#createversionalias) - Create or update an agent version alias.
726
729
  - [`betaAgentsDelete`](docs/sdks/mistralagents/README.md#delete) - Delete an agent entity.
727
730
  - [`betaAgentsGet`](docs/sdks/mistralagents/README.md#get) - Retrieve an agent entity.
728
731
  - [`betaAgentsGetVersion`](docs/sdks/mistralagents/README.md#getversion) - Retrieve a specific version of an agent.
729
732
  - [`betaAgentsList`](docs/sdks/mistralagents/README.md#list) - List agent entities.
733
+ - [`betaAgentsListVersionAliases`](docs/sdks/mistralagents/README.md#listversionaliases) - List all aliases for an agent.
730
734
  - [`betaAgentsListVersions`](docs/sdks/mistralagents/README.md#listversions) - List all versions of an agent.
731
735
  - [`betaAgentsUpdate`](docs/sdks/mistralagents/README.md#update) - Update an agent entity.
732
736
  - [`betaAgentsUpdateVersion`](docs/sdks/mistralagents/README.md#updateversion) - Update an agent version.
@@ -0,0 +1,17 @@
1
+ import { Mistral } from "@mistralai/mistralai";
2
+
3
+ const apiKey = process.env["MISTRAL_API_KEY"];
4
+ if (!apiKey) {
5
+ throw new Error("missing MISTRAL_API_KEY environment variable");
6
+ }
7
+
8
+ const mistral = new Mistral({ apiKey: apiKey });
9
+
10
+ const response = await mistral.audio.transcriptions.complete({
11
+ model: "voxtral-mini-2602",
12
+ fileUrl: "https://docs.mistral.ai/audio/bcn_weather.mp3",
13
+ diarize: true,
14
+ timestampGranularities: ["segment"],
15
+ });
16
+
17
+ process.stdout.write(JSON.stringify(response));
@@ -0,0 +1,163 @@
1
+ import { spawn, type ChildProcess } from "node:child_process";
2
+ import yargs from "yargs/yargs";
3
+ import { hideBin } from "yargs/helpers";
4
+
5
+ import {
6
+ AudioEncoding,
7
+ RealtimeTranscription,
8
+ } from "@mistralai/mistralai/extra/realtime";
9
+
10
+ type Args = {
11
+ model: string;
12
+ encoding: string;
13
+ sampleRate: number;
14
+ apiKey?: string;
15
+ baseUrl: string;
16
+ };
17
+
18
+ function parseArgs(): Args {
19
+ const argv = yargs(hideBin(process.argv))
20
+ .usage("Usage: $0 [options]")
21
+ .option("model", {
22
+ type: "string",
23
+ default: "voxtral-mini-transcribe-realtime-2602",
24
+ describe: "Model ID",
25
+ })
26
+ .option("encoding", {
27
+ type: "string",
28
+ default: AudioEncoding.PcmS16le,
29
+ describe: "Audio encoding",
30
+ })
31
+ .option("sample-rate", {
32
+ type: "number",
33
+ default: 16000,
34
+ describe: "Sample rate in Hz",
35
+ })
36
+ .option("api-key", {
37
+ type: "string",
38
+ default: process.env["MISTRAL_API_KEY"],
39
+ describe: "Mistral API key",
40
+ })
41
+ .option("base-url", {
42
+ type: "string",
43
+ default: process.env["MISTRAL_BASE_URL"] ?? "wss://api.mistral.ai",
44
+ describe: "API base URL",
45
+ })
46
+ .help()
47
+ .parseSync();
48
+
49
+ return {
50
+ model: argv.model,
51
+ encoding: argv.encoding,
52
+ sampleRate: argv.sampleRate,
53
+ apiKey: argv.apiKey,
54
+ baseUrl: argv.baseUrl,
55
+ };
56
+ }
57
+
58
+ async function* captureAudio(
59
+ sampleRate: number,
60
+ ): AsyncGenerator<Uint8Array, void, unknown> {
61
+ const recorder: ChildProcess = spawn(
62
+ "rec",
63
+ [
64
+ "-q",
65
+ "-t", "raw",
66
+ "-b", "16",
67
+ "-e", "signed-integer",
68
+ "-r", String(sampleRate),
69
+ "-c", "1",
70
+ "-",
71
+ ],
72
+ { stdio: ["ignore", "pipe", "ignore"] },
73
+ );
74
+
75
+ recorder.on("error", (err) => {
76
+ const error = err as NodeJS.ErrnoException;
77
+ if (error.code === "ENOENT") {
78
+ console.error(
79
+ "\nError: 'rec' not found. Install SoX: brew install sox (macOS) or apt install sox (Linux)",
80
+ );
81
+ process.exit(1);
82
+ }
83
+ throw err;
84
+ });
85
+
86
+ try {
87
+ if (!recorder.stdout) {
88
+ throw new Error("Failed to create audio capture stream");
89
+ }
90
+ for await (const chunk of recorder.stdout) {
91
+ yield new Uint8Array(chunk as Buffer);
92
+ }
93
+ } finally {
94
+ if (!recorder.killed) {
95
+ recorder.kill("SIGTERM");
96
+ }
97
+ }
98
+ }
99
+
100
+ function clearLine(): void {
101
+ process.stdout.write("\x1b[2K\r");
102
+ }
103
+
104
+ async function main(): Promise<void> {
105
+ const args = parseArgs();
106
+
107
+ const apiKey = args.apiKey ?? process.env["MISTRAL_API_KEY"];
108
+ if (!apiKey) {
109
+ console.error(
110
+ "Missing MISTRAL_API_KEY. Set the environment variable or pass --api-key.",
111
+ );
112
+ process.exit(1);
113
+ }
114
+
115
+ const client = new RealtimeTranscription({
116
+ apiKey: apiKey,
117
+ serverURL: args.baseUrl,
118
+ });
119
+
120
+ console.log("Listening... (Ctrl+C to stop)\n");
121
+
122
+ const audioStream = captureAudio(args.sampleRate);
123
+
124
+ process.on("SIGINT", () => {
125
+ clearLine();
126
+ console.log("\nStopped.");
127
+ process.exit(0);
128
+ });
129
+
130
+ try {
131
+ for await (const event of client.transcribeStream(
132
+ audioStream,
133
+ args.model,
134
+ {
135
+ audioFormat: {
136
+ encoding: args.encoding,
137
+ sampleRate: args.sampleRate,
138
+ },
139
+ },
140
+ )) {
141
+ if (event.type === "transcription.text.delta") {
142
+ process.stdout.write(event.text);
143
+ continue;
144
+ }
145
+ if (event.type === "transcription.done") {
146
+ process.stdout.write("\n");
147
+ break;
148
+ }
149
+ if (event.type === "error") {
150
+ const errorMessage = typeof event.error.message === "string"
151
+ ? event.error.message
152
+ : JSON.stringify(event.error.message);
153
+ console.error(`\nTranscription error: ${errorMessage}`);
154
+ process.exitCode = 1;
155
+ break;
156
+ }
157
+ }
158
+ } finally {
159
+ await audioStream.return?.();
160
+ }
161
+ }
162
+
163
+ await main();
@@ -0,0 +1,225 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { createReadStream, promises as fs } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { extname, join, resolve } from "node:path";
6
+ import yargs from "yargs/yargs";
7
+ import { hideBin } from "yargs/helpers";
8
+
9
+ import {
10
+ AudioEncoding,
11
+ RealtimeTranscription,
12
+ } from "@mistralai/mistralai/extra/realtime";
13
+
14
+ type KnownAudioEncoding = (typeof AudioEncoding)[keyof typeof AudioEncoding];
15
+
16
+ const DEFAULT_ENCODING: KnownAudioEncoding = AudioEncoding.PcmS16le;
17
+ const DEFAULT_SAMPLE_RATE = 16000;
18
+
19
+ const FFMPEG_FORMAT_BY_ENCODING: Record<KnownAudioEncoding, string> = {
20
+ [AudioEncoding.PcmS16le]: "s16le",
21
+ [AudioEncoding.PcmS32le]: "s32le",
22
+ [AudioEncoding.PcmF32le]: "f32le",
23
+ [AudioEncoding.PcmF16le]: "f16le",
24
+ [AudioEncoding.PcmMulaw]: "mulaw",
25
+ [AudioEncoding.PcmAlaw]: "alaw",
26
+ };
27
+
28
+ type Args = {
29
+ file?: string;
30
+ model: string;
31
+ apiKey?: string;
32
+ baseUrl: string;
33
+ noConvert: boolean;
34
+ };
35
+
36
+ function parseArgs(): Args {
37
+ const argv = yargs(hideBin(process.argv))
38
+ .usage("Usage: $0 <file> [options]")
39
+ .option("model", {
40
+ type: "string",
41
+ default: "voxtral-mini-transcribe-realtime-2602",
42
+ describe: "Model ID",
43
+ })
44
+ .option("api-key", {
45
+ type: "string",
46
+ default: process.env["MISTRAL_API_KEY"],
47
+ describe: "Mistral API key",
48
+ })
49
+ .option("base-url", {
50
+ type: "string",
51
+ default: process.env["MISTRAL_BASE_URL"] ?? "https://api.mistral.ai",
52
+ describe: "API base URL",
53
+ })
54
+ .option("no-convert", {
55
+ type: "boolean",
56
+ default: false,
57
+ describe: "Skip ffmpeg conversion (input must be raw PCM)",
58
+ })
59
+ .help()
60
+ .parseSync();
61
+
62
+ const fileArg = argv._[0];
63
+ const file = typeof fileArg === "string" ? fileArg : undefined;
64
+
65
+ return {
66
+ file,
67
+ model: argv.model,
68
+ apiKey: argv.apiKey,
69
+ baseUrl: argv.baseUrl,
70
+ noConvert: argv.noConvert,
71
+ };
72
+ }
73
+
74
+ async function runFfmpeg(args: string[]): Promise<void> {
75
+ await new Promise<void>((resolve, reject) => {
76
+ const child = spawn("ffmpeg", args, {
77
+ stdio: ["ignore", "ignore", "pipe"],
78
+ });
79
+
80
+ let stderr = "";
81
+ child.stderr.setEncoding("utf8");
82
+ child.stderr.on("data", (chunk) => {
83
+ stderr += chunk;
84
+ });
85
+
86
+ child.on("error", (err) => {
87
+ const error = err as NodeJS.ErrnoException;
88
+ if (error.code === "ENOENT") {
89
+ reject(new Error(
90
+ "ffmpeg not found. Install ffmpeg or use --no-convert with raw PCM input.",
91
+ ));
92
+ return;
93
+ }
94
+ reject(err);
95
+ });
96
+
97
+ child.on("close", (code) => {
98
+ if (code === 0) {
99
+ resolve();
100
+ return;
101
+ }
102
+ const details = stderr.trim();
103
+ reject(new Error(
104
+ `ffmpeg conversion failed${details ? `: ${details}` : ""}`,
105
+ ));
106
+ });
107
+ });
108
+ }
109
+
110
+ async function convertAudioToPcm(
111
+ inputPath: string,
112
+ encoding: KnownAudioEncoding,
113
+ sampleRate: number,
114
+ ): Promise<string> {
115
+ const tempPath = join(
116
+ tmpdir(),
117
+ `mistral-realtime-${randomUUID()}.pcm`,
118
+ );
119
+
120
+ const ffmpegFormat = FFMPEG_FORMAT_BY_ENCODING[encoding];
121
+ const args = [
122
+ "-y",
123
+ "-i",
124
+ inputPath,
125
+ "-f",
126
+ ffmpegFormat,
127
+ "-ar",
128
+ String(sampleRate),
129
+ "-ac",
130
+ "1",
131
+ tempPath,
132
+ ];
133
+
134
+ try {
135
+ await runFfmpeg(args);
136
+ } catch (err) {
137
+ await fs.unlink(tempPath).catch(() => undefined);
138
+ throw err;
139
+ }
140
+
141
+ return tempPath;
142
+ }
143
+
144
+ async function* streamAudioFile(
145
+ filePath: string,
146
+ chunkSize: number = 4096,
147
+ ): AsyncIterable<Uint8Array> {
148
+ for await (const chunk of createReadStream(filePath, { highWaterMark: chunkSize })) {
149
+ yield chunk as Uint8Array;
150
+ }
151
+ }
152
+
153
+ async function main(): Promise<void> {
154
+ const args = parseArgs();
155
+ if (!args.file) {
156
+ console.error(
157
+ "Missing audio file. Provide a file path after the script name.",
158
+ );
159
+ return;
160
+ }
161
+
162
+ const apiKey = args.apiKey ?? process.env["MISTRAL_API_KEY"];
163
+ if (!apiKey) {
164
+ throw new Error(
165
+ "Missing MISTRAL_API_KEY. Set the environment variable or pass --api-key.",
166
+ );
167
+ }
168
+
169
+ const inputPath = resolve(args.file);
170
+
171
+ let audioPath = inputPath;
172
+ let tempPath: string | undefined;
173
+
174
+ const extension = extname(inputPath).toLowerCase();
175
+ const isRawPcm = extension === ".pcm" || extension === ".raw";
176
+ if (!args.noConvert && !isRawPcm) {
177
+ tempPath = await convertAudioToPcm(
178
+ inputPath,
179
+ DEFAULT_ENCODING,
180
+ DEFAULT_SAMPLE_RATE,
181
+ );
182
+ audioPath = tempPath;
183
+ }
184
+
185
+ const client = new RealtimeTranscription({
186
+ apiKey: apiKey,
187
+ serverURL: args.baseUrl,
188
+ });
189
+
190
+ try {
191
+ for await (const event of client.transcribeStream(
192
+ streamAudioFile(audioPath),
193
+ args.model,
194
+ {
195
+ audioFormat: {
196
+ encoding: DEFAULT_ENCODING,
197
+ sampleRate: DEFAULT_SAMPLE_RATE,
198
+ },
199
+ },
200
+ )) {
201
+ if (event.type === "transcription.text.delta") {
202
+ process.stdout.write(event.text);
203
+ continue;
204
+ }
205
+ if (event.type === "transcription.done") {
206
+ process.stdout.write("\n");
207
+ break;
208
+ }
209
+ if (event.type === "error") {
210
+ const errorMessage = typeof event.error.message === "string"
211
+ ? event.error.message
212
+ : JSON.stringify(event.error.message);
213
+ console.error(`Transcription error: ${errorMessage}`);
214
+ process.exitCode = 1;
215
+ break;
216
+ }
217
+ }
218
+ } finally {
219
+ if (tempPath) {
220
+ await fs.unlink(tempPath).catch(() => undefined);
221
+ }
222
+ }
223
+ }
224
+
225
+ await main();
@@ -0,0 +1,43 @@
1
+ import WebSocket from "ws";
2
+ import { TranscriptionStreamDone } from "../../models/components/transcriptionstreamdone.js";
3
+ import { TranscriptionStreamLanguage } from "../../models/components/transcriptionstreamlanguage.js";
4
+ import { TranscriptionStreamSegmentDelta } from "../../models/components/transcriptionstreamsegmentdelta.js";
5
+ import { TranscriptionStreamTextDelta } from "../../models/components/transcriptionstreamtextdelta.js";
6
+ import { type AudioFormat } from "../../models/components/audioformat.js";
7
+ import { type RealtimeTranscriptionError } from "../../models/components/realtimetranscriptionerror.js";
8
+ import type { RealtimeTranscriptionSession } from "../../models/components/realtimetranscriptionsession.js";
9
+ import { type RealtimeTranscriptionSessionCreated } from "../../models/components/realtimetranscriptionsessioncreated.js";
10
+ import { type RealtimeTranscriptionSessionUpdated } from "../../models/components/realtimetranscriptionsessionupdated.js";
11
+ export type KnownRealtimeEvent = RealtimeTranscriptionSessionCreated | RealtimeTranscriptionSessionUpdated | RealtimeTranscriptionError | TranscriptionStreamLanguage | TranscriptionStreamSegmentDelta | TranscriptionStreamTextDelta | TranscriptionStreamDone;
12
+ export type UnknownRealtimeEvent = {
13
+ type: string;
14
+ raw: unknown;
15
+ error?: Error | undefined;
16
+ };
17
+ export type RealtimeEvent = KnownRealtimeEvent | UnknownRealtimeEvent;
18
+ /** @internal */
19
+ export declare function isUnknownRealtimeEvent(event: RealtimeEvent): event is UnknownRealtimeEvent;
20
+ /** @internal */
21
+ export declare function parseRealtimeEventFromData(data: unknown): RealtimeEvent;
22
+ /** WebSocket connection for realtime transcription. */
23
+ export declare class RealtimeConnection implements AsyncIterable<RealtimeEvent> {
24
+ private readonly websocket;
25
+ private closed;
26
+ private currentAudioFormat;
27
+ private currentSession;
28
+ private initialEvents;
29
+ constructor(websocket: WebSocket, session: RealtimeTranscriptionSession, initialEvents?: RealtimeEvent[]);
30
+ get requestId(): string;
31
+ get session(): RealtimeTranscriptionSession;
32
+ get audioFormat(): AudioFormat;
33
+ get isClosed(): boolean;
34
+ [Symbol.asyncIterator](): AsyncIterator<RealtimeEvent>;
35
+ events(): AsyncGenerator<RealtimeEvent>;
36
+ sendAudio(audioBytes: Uint8Array | ArrayBuffer): Promise<void>;
37
+ updateSession(audioFormat: AudioFormat): Promise<void>;
38
+ endAudio(): Promise<void>;
39
+ close(code?: number, reason?: string): Promise<void>;
40
+ private sendJson;
41
+ private applySessionEvent;
42
+ }
43
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/extra/realtime/connection.ts"],"names":[],"mappings":"AACA,OAAO,SAAS,MAAM,IAAI,CAAC;AAC3B,OAAO,EACL,uBAAuB,EAExB,MAAM,oDAAoD,CAAC;AAC5D,OAAO,EACL,2BAA2B,EAE5B,MAAM,wDAAwD,CAAC;AAChE,OAAO,EACL,+BAA+B,EAEhC,MAAM,4DAA4D,CAAC;AACpE,OAAO,EACL,4BAA4B,EAE7B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,0BAA0B,EAChC,MAAM,uDAAuD,CAAC;AAC/D,OAAO,KAAK,EACV,4BAA4B,EAC7B,MAAM,yDAAyD,CAAC;AACjE,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,gEAAgE,CAAC;AACxE,OAAO,EAEL,KAAK,mCAAmC,EACzC,MAAM,gEAAgE,CAAC;AAKxE,MAAM,MAAM,kBAAkB,GAC1B,mCAAmC,GACnC,mCAAmC,GACnC,0BAA0B,GAC1B,2BAA2B,GAC3B,+BAA+B,GAC/B,4BAA4B,GAC5B,uBAAuB,CAAC;AAE5B,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;AAEtE,gBAAgB;AAChB,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,aAAa,GACnB,KAAK,IAAI,oBAAoB,CAE/B;AAED,gBAAgB;AAChB,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAkBvE;AAED,uDAAuD;AACvD,qBAAa,kBAAmB,YAAW,aAAa,CAAC,aAAa,CAAC;IACrE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAAkB;gBAGrC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,4BAA4B,EACrC,aAAa,GAAE,aAAa,EAAO;IAQrC,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,OAAO,IAAI,4BAA4B,CAE1C;IAED,IAAI,WAAW,IAAI,WAAW,CAE7B;IAED,IAAI,QAAQ,IAAI,OAAO,CAMtB;IAED,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,aAAa,CAAC,aAAa,CAAC;IAI/C,MAAM,IAAI,cAAc,CAAC,aAAa,CAAC;IAkFxC,SAAS,CAAC,UAAU,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9D,aAAa,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzB,KAAK,CAAC,IAAI,GAAE,MAAa,EAAE,MAAM,GAAE,MAAW,GAAG,OAAO,CAAC,IAAI,CAAC;YAqBtD,QAAQ;IAatB,OAAO,CAAC,iBAAiB;CAU1B"}