@ai-sdk/assemblyai 2.0.40 → 2.0.42

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # @ai-sdk/assemblyai
2
2
 
3
+ ## 2.0.42
4
+
5
+ ### Patch Changes
6
+
7
+ - 59f764a: feat(assemblyai): support universal-3-5-pro and expand the transcription provider
8
+
9
+ - Add current speech models `universal-3-5-pro`, `universal-3-pro`, and
10
+ `universal-2`, routed via AssemblyAI's `speech_models` parameter (the
11
+ deprecated singular `speech_model` is used only for the legacy `best` model).
12
+ Using `universal-3-pro`/`universal-2` emits an informational warning
13
+ suggesting `universal-3-5-pro`.
14
+ - Deprecate the legacy `best` model (still works, warns) and remove `nano`,
15
+ which AssemblyAI no longer accepts.
16
+ - Surface speaker diarization and audio-intelligence results: `doGenerate` now
17
+ returns the full raw response on `response.body` and populates
18
+ `providerMetadata.assemblyai` with `utterances`, `entities`,
19
+ `sentimentAnalysisResults`, `contentSafetyLabels`, `iabCategoriesResult`, and
20
+ `autoHighlightsResult`.
21
+ - Add provider options for newer request parameters: `prompt`, `keytermsPrompt`,
22
+ `temperature`, `removeAudioTags`, `domain`, `speakerOptions`,
23
+ `languageDetectionOptions`, `redactPiiAudioOptions`,
24
+ `redactPiiReturnUnredacted`, and `redactStaticEntities`. Deprecate
25
+ `wordBoost`/`boostParam` in favor of `keytermsPrompt` (AssemblyAI rejects
26
+ `word_boost` on the newer models).
27
+ - Fix transcription segment timings, which were reported in milliseconds instead
28
+ of seconds.
29
+
30
+ ## 2.0.41
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies [ea1e95b]
35
+ - @ai-sdk/provider-utils@4.0.35
36
+
3
37
  ## 2.0.40
4
38
 
5
39
  ### Patch Changes
package/README.md CHANGED
@@ -36,7 +36,7 @@ import { assemblyai } from '@ai-sdk/assemblyai';
36
36
  import { experimental_transcribe as transcribe } from 'ai';
37
37
 
38
38
  const { text } = await transcribe({
39
- model: assemblyai.transcription('best'),
39
+ model: assemblyai.transcription('universal-3-5-pro'),
40
40
  audio: new URL(
41
41
  'https://github.com/vercel/ai/raw/refs/heads/main/examples/ai-functions/data/galileo.mp3',
42
42
  ),
package/dist/index.d.mts CHANGED
@@ -13,7 +13,15 @@ type AssemblyAIConfig = {
13
13
  generateId?: () => string;
14
14
  };
15
15
 
16
- type AssemblyAITranscriptionModelId = 'best' | 'nano';
16
+ /**
17
+ * Legacy AssemblyAI speech model, sent via the deprecated singular
18
+ * `speech_model` request parameter.
19
+ *
20
+ * @deprecated Use `universal-3-5-pro` instead.
21
+ * @see https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model
22
+ */
23
+ type AssemblyAIDeprecatedTranscriptionModelId = 'best';
24
+ type AssemblyAITranscriptionModelId = 'universal-2' | 'universal-3-pro' | 'universal-3-5-pro' | AssemblyAIDeprecatedTranscriptionModelId | (string & {});
17
25
 
18
26
  declare const assemblyaiTranscriptionModelOptionsSchema: z.ZodObject<{
19
27
  audioEndAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -28,27 +36,53 @@ declare const assemblyaiTranscriptionModelOptionsSchema: z.ZodObject<{
28
36
  to: z.ZodString;
29
37
  }, z.core.$strip>>>>;
30
38
  disfluencies: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
39
+ domain: z.ZodOptional<z.ZodNullable<z.ZodString>>;
31
40
  entityDetection: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
32
41
  filterProfanity: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
33
42
  formatText: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
34
43
  iabCategories: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
44
+ keytermsPrompt: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
35
45
  languageCode: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<"en">, z.ZodString]>>>;
36
46
  languageConfidenceThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
37
47
  languageDetection: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
48
+ languageDetectionOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
49
+ expectedLanguages: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
50
+ fallbackLanguage: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ codeSwitching: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
52
+ codeSwitchingConfidenceThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
53
+ }, z.core.$strip>>>;
38
54
  multichannel: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
55
+ prompt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
39
56
  punctuate: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
40
57
  redactPii: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
41
58
  redactPiiAudio: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
59
+ redactPiiAudioOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
60
+ returnRedactedNoSpeechAudio: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
61
+ overrideAudioRedactionMethod: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
62
+ silence: "silence";
63
+ }>>>;
64
+ }, z.core.$strip>>>;
42
65
  redactPiiAudioQuality: z.ZodOptional<z.ZodNullable<z.ZodString>>;
43
66
  redactPiiPolicies: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
67
+ redactPiiReturnUnredacted: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
44
68
  redactPiiSub: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ redactStaticEntities: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>>;
70
+ removeAudioTags: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
71
+ all: "all";
72
+ speaker: "speaker";
73
+ }>>>;
45
74
  sentimentAnalysis: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
46
75
  speakerLabels: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
76
+ speakerOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
77
+ minSpeakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
78
+ maxSpeakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
79
+ }, z.core.$strip>>>;
47
80
  speakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
48
81
  speechThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
49
82
  summarization: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
50
83
  summaryModel: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
84
  summaryType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
85
+ temperature: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
52
86
  webhookAuthHeaderName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
87
  webhookAuthHeaderValue: z.ZodOptional<z.ZodNullable<z.ZodString>>;
54
88
  webhookUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -82,7 +116,7 @@ declare class AssemblyAITranscriptionModel implements TranscriptionModelV3 {
82
116
  }
83
117
 
84
118
  interface AssemblyAIProvider extends ProviderV3 {
85
- (modelId: 'best', settings?: {}): {
119
+ (modelId: AssemblyAITranscriptionModelId, settings?: {}): {
86
120
  transcription: AssemblyAITranscriptionModel;
87
121
  };
88
122
  /**
package/dist/index.d.ts CHANGED
@@ -13,7 +13,15 @@ type AssemblyAIConfig = {
13
13
  generateId?: () => string;
14
14
  };
15
15
 
16
- type AssemblyAITranscriptionModelId = 'best' | 'nano';
16
+ /**
17
+ * Legacy AssemblyAI speech model, sent via the deprecated singular
18
+ * `speech_model` request parameter.
19
+ *
20
+ * @deprecated Use `universal-3-5-pro` instead.
21
+ * @see https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model
22
+ */
23
+ type AssemblyAIDeprecatedTranscriptionModelId = 'best';
24
+ type AssemblyAITranscriptionModelId = 'universal-2' | 'universal-3-pro' | 'universal-3-5-pro' | AssemblyAIDeprecatedTranscriptionModelId | (string & {});
17
25
 
18
26
  declare const assemblyaiTranscriptionModelOptionsSchema: z.ZodObject<{
19
27
  audioEndAt: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
@@ -28,27 +36,53 @@ declare const assemblyaiTranscriptionModelOptionsSchema: z.ZodObject<{
28
36
  to: z.ZodString;
29
37
  }, z.core.$strip>>>>;
30
38
  disfluencies: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
39
+ domain: z.ZodOptional<z.ZodNullable<z.ZodString>>;
31
40
  entityDetection: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
32
41
  filterProfanity: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
33
42
  formatText: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
34
43
  iabCategories: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
44
+ keytermsPrompt: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
35
45
  languageCode: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodLiteral<"en">, z.ZodString]>>>;
36
46
  languageConfidenceThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
37
47
  languageDetection: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
48
+ languageDetectionOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
49
+ expectedLanguages: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
50
+ fallbackLanguage: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
+ codeSwitching: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
52
+ codeSwitchingConfidenceThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
53
+ }, z.core.$strip>>>;
38
54
  multichannel: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
55
+ prompt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
39
56
  punctuate: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
40
57
  redactPii: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
41
58
  redactPiiAudio: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
59
+ redactPiiAudioOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
60
+ returnRedactedNoSpeechAudio: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
61
+ overrideAudioRedactionMethod: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
62
+ silence: "silence";
63
+ }>>>;
64
+ }, z.core.$strip>>>;
42
65
  redactPiiAudioQuality: z.ZodOptional<z.ZodNullable<z.ZodString>>;
43
66
  redactPiiPolicies: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
67
+ redactPiiReturnUnredacted: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
44
68
  redactPiiSub: z.ZodOptional<z.ZodNullable<z.ZodString>>;
69
+ redactStaticEntities: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodString>>>>;
70
+ removeAudioTags: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
71
+ all: "all";
72
+ speaker: "speaker";
73
+ }>>>;
45
74
  sentimentAnalysis: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
46
75
  speakerLabels: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
76
+ speakerOptions: z.ZodOptional<z.ZodNullable<z.ZodObject<{
77
+ minSpeakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
78
+ maxSpeakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
79
+ }, z.core.$strip>>>;
47
80
  speakersExpected: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
48
81
  speechThreshold: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
49
82
  summarization: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
50
83
  summaryModel: z.ZodOptional<z.ZodNullable<z.ZodString>>;
51
84
  summaryType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
85
+ temperature: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
52
86
  webhookAuthHeaderName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
53
87
  webhookAuthHeaderValue: z.ZodOptional<z.ZodNullable<z.ZodString>>;
54
88
  webhookUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -82,7 +116,7 @@ declare class AssemblyAITranscriptionModel implements TranscriptionModelV3 {
82
116
  }
83
117
 
84
118
  interface AssemblyAIProvider extends ProviderV3 {
85
- (modelId: 'best', settings?: {}): {
119
+ (modelId: AssemblyAITranscriptionModelId, settings?: {}): {
86
120
  transcription: AssemblyAITranscriptionModel;
87
121
  };
88
122
  /**
package/dist/index.js CHANGED
@@ -67,8 +67,12 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
67
67
  */
68
68
  autoHighlights: import_v42.z.boolean().nullish(),
69
69
  /**
70
- * Boost parameter for the transcription.
70
+ * Boost parameter for word boost (used with `wordBoost`).
71
71
  * Allowed values: 'low', 'default', 'high'.
72
+ *
73
+ * @deprecated Only applies to the deprecated `wordBoost` option. Use
74
+ * `keytermsPrompt` instead, which works with the recommended `universal-*`
75
+ * models.
72
76
  */
73
77
  boostParam: import_v42.z.string().nullish(),
74
78
  /**
@@ -92,6 +96,11 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
92
96
  * Whether to include filler words (um, uh, etc.) in the transcription.
93
97
  */
94
98
  disfluencies: import_v42.z.boolean().nullish(),
99
+ /**
100
+ * Enable a domain-specific model to improve accuracy for specialized
101
+ * terminology. Currently supports `'medical-v1'` (Medical Mode).
102
+ */
103
+ domain: import_v42.z.string().nullish(),
95
104
  /**
96
105
  * Whether to enable entity detection.
97
106
  */
@@ -108,6 +117,13 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
108
117
  * Whether to enable IAB categories detection.
109
118
  */
110
119
  iabCategories: import_v42.z.boolean().nullish(),
120
+ /**
121
+ * Domain-specific keyterms to boost recognition for (max 6 words per phrase).
122
+ * Replaces `wordBoost` for newer models: supported by `universal-3-pro` /
123
+ * `universal-3-5-pro` and `slam-1` (and `universal-2` when metaphone is
124
+ * enabled for the account).
125
+ */
126
+ keytermsPrompt: import_v42.z.array(import_v42.z.string()).nullish(),
111
127
  /**
112
128
  * Language code for the transcription.
113
129
  */
@@ -120,10 +136,28 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
120
136
  * Whether to enable language detection.
121
137
  */
122
138
  languageDetection: import_v42.z.boolean().nullish(),
139
+ /**
140
+ * Options for automatic language detection.
141
+ */
142
+ languageDetectionOptions: import_v42.z.object({
143
+ /** List of languages expected in the audio file. */
144
+ expectedLanguages: import_v42.z.array(import_v42.z.string()).nullish(),
145
+ /** Fallback language if the detected language is not expected. */
146
+ fallbackLanguage: import_v42.z.string().nullish(),
147
+ /** Whether code switching should be detected. */
148
+ codeSwitching: import_v42.z.boolean().nullish(),
149
+ /** Confidence threshold for code switching detection (0-1). */
150
+ codeSwitchingConfidenceThreshold: import_v42.z.number().min(0).max(1).nullish()
151
+ }).nullish(),
123
152
  /**
124
153
  * Whether to process audio as multichannel.
125
154
  */
126
155
  multichannel: import_v42.z.boolean().nullish(),
156
+ /**
157
+ * Provide natural-language context (up to 1,500 words) to steer the model.
158
+ * Only supported by `universal-3-pro` / `universal-3-5-pro` and `slam-1`.
159
+ */
160
+ prompt: import_v42.z.string().nullish(),
127
161
  /**
128
162
  * Whether to add punctuation to the transcription.
129
163
  */
@@ -136,6 +170,15 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
136
170
  * Whether to redact PII in the audio file.
137
171
  */
138
172
  redactPiiAudio: import_v42.z.boolean().nullish(),
173
+ /**
174
+ * Options for PII-redacted audio files. Requires `redactPiiAudio`.
175
+ */
176
+ redactPiiAudioOptions: import_v42.z.object({
177
+ /** Return redacted audio even for files without detected speech. */
178
+ returnRedactedNoSpeechAudio: import_v42.z.boolean().nullish(),
179
+ /** Redaction method; set to `'silence'` to replace PII with silence. */
180
+ overrideAudioRedactionMethod: import_v42.z.enum(["silence"]).nullish()
181
+ }).nullish(),
139
182
  /**
140
183
  * Audio format for PII redaction.
141
184
  */
@@ -144,10 +187,26 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
144
187
  * List of PII types to redact.
145
188
  */
146
189
  redactPiiPolicies: import_v42.z.array(import_v42.z.string()).nullish(),
190
+ /**
191
+ * Return the original unredacted transcript alongside the redacted one.
192
+ * Requires `redactPii`.
193
+ */
194
+ redactPiiReturnUnredacted: import_v42.z.boolean().nullish(),
147
195
  /**
148
196
  * Substitution method for redacted PII.
149
197
  */
150
198
  redactPiiSub: import_v42.z.string().nullish(),
199
+ /**
200
+ * Map of user-defined labels to exact terms to redact, e.g.
201
+ * `{ INTERNAL_TOOL: ['Bearclaw'] }`. Applied on top of standard PII redaction
202
+ * using `redactPiiSub`. Requires `redactPii`.
203
+ */
204
+ redactStaticEntities: import_v42.z.record(import_v42.z.string(), import_v42.z.array(import_v42.z.string())).nullish(),
205
+ /**
206
+ * Remove inline annotations from rich transcripts. `'all'` removes all inline
207
+ * annotations; `'speaker'` removes only speaker cues. Universal-3 Pro models.
208
+ */
209
+ removeAudioTags: import_v42.z.enum(["all", "speaker"]).nullish(),
151
210
  /**
152
211
  * Whether to enable sentiment analysis.
153
212
  */
@@ -156,6 +215,15 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
156
215
  * Whether to identify different speakers in the audio.
157
216
  */
158
217
  speakerLabels: import_v42.z.boolean().nullish(),
218
+ /**
219
+ * Options for speaker diarization, e.g. a range of possible speakers.
220
+ */
221
+ speakerOptions: import_v42.z.object({
222
+ /** Minimum number of speakers expected in the audio file. */
223
+ minSpeakersExpected: import_v42.z.number().int().nullish(),
224
+ /** Maximum number of speakers expected in the audio file. */
225
+ maxSpeakersExpected: import_v42.z.number().int().nullish()
226
+ }).nullish(),
159
227
  /**
160
228
  * Number of speakers expected in the audio.
161
229
  */
@@ -176,6 +244,10 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
176
244
  * Type of summary to generate.
177
245
  */
178
246
  summaryType: import_v42.z.string().nullish(),
247
+ /**
248
+ * Sampling temperature (0-1) controlling randomness. Universal-3 Pro models.
249
+ */
250
+ temperature: import_v42.z.number().min(0).max(1).nullish(),
179
251
  /**
180
252
  * Name of the authentication header for webhook requests.
181
253
  */
@@ -190,6 +262,10 @@ var assemblyaiTranscriptionModelOptionsSchema = import_v42.z.object({
190
262
  webhookUrl: import_v42.z.string().nullish(),
191
263
  /**
192
264
  * List of words to boost recognition for.
265
+ *
266
+ * @deprecated `wordBoost` is rejected by `universal-3-pro` /
267
+ * `universal-3-5-pro` and `slam-1` (it only works on `universal-2`/`best`).
268
+ * Use `keytermsPrompt` instead.
193
269
  */
194
270
  wordBoost: import_v42.z.array(import_v42.z.string()).nullish()
195
271
  });
@@ -206,16 +282,30 @@ var AssemblyAITranscriptionModel = class {
206
282
  async getArgs({
207
283
  providerOptions
208
284
  }) {
209
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H;
285
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W;
210
286
  const warnings = [];
211
287
  const assemblyaiOptions = await (0, import_provider_utils2.parseProviderOptions)({
212
288
  provider: "assemblyai",
213
289
  providerOptions,
214
290
  schema: assemblyaiTranscriptionModelOptionsSchema
215
291
  });
216
- const body = {
217
- speech_model: this.modelId
218
- };
292
+ const body = {};
293
+ if (this.modelId === "best") {
294
+ body.speech_model = this.modelId;
295
+ warnings.push({
296
+ type: "other",
297
+ message: "The 'best' model is a legacy AssemblyAI model. Use 'universal-3-5-pro' instead. See documentation: https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model"
298
+ });
299
+ } else {
300
+ body.speech_models = [this.modelId];
301
+ if (this.modelId === "universal-3-pro" || this.modelId === "universal-2") {
302
+ const docsUrl = "https://www.assemblyai.com/docs/pre-recorded-audio/select-the-speech-model";
303
+ warnings.push({
304
+ type: "other",
305
+ message: this.modelId === "universal-3-pro" ? `'universal-3-5-pro' is AssemblyAI's latest flagship model and is set to replace 'universal-3-pro'. See ${docsUrl}` : `'universal-3-5-pro' is AssemblyAI's latest flagship model. See ${docsUrl}`
306
+ });
307
+ }
308
+ }
219
309
  if (assemblyaiOptions) {
220
310
  body.audio_end_at = (_a = assemblyaiOptions.audioEndAt) != null ? _a : void 0;
221
311
  body.audio_start_from = (_b = assemblyaiOptions.audioStartFrom) != null ? _b : void 0;
@@ -251,6 +341,64 @@ var AssemblyAITranscriptionModel = class {
251
341
  body.webhook_auth_header_value = (_F = assemblyaiOptions.webhookAuthHeaderValue) != null ? _F : void 0;
252
342
  body.webhook_url = (_G = assemblyaiOptions.webhookUrl) != null ? _G : void 0;
253
343
  body.word_boost = (_H = assemblyaiOptions.wordBoost) != null ? _H : void 0;
344
+ body.keyterms_prompt = (_I = assemblyaiOptions.keytermsPrompt) != null ? _I : void 0;
345
+ body.prompt = (_J = assemblyaiOptions.prompt) != null ? _J : void 0;
346
+ body.temperature = (_K = assemblyaiOptions.temperature) != null ? _K : void 0;
347
+ body.remove_audio_tags = (_L = assemblyaiOptions.removeAudioTags) != null ? _L : void 0;
348
+ body.domain = (_M = assemblyaiOptions.domain) != null ? _M : void 0;
349
+ body.redact_pii_return_unredacted = (_N = assemblyaiOptions.redactPiiReturnUnredacted) != null ? _N : void 0;
350
+ body.redact_static_entities = (_O = assemblyaiOptions.redactStaticEntities) != null ? _O : void 0;
351
+ if (assemblyaiOptions.speakerOptions) {
352
+ body.speaker_options = {
353
+ min_speakers_expected: (_P = assemblyaiOptions.speakerOptions.minSpeakersExpected) != null ? _P : void 0,
354
+ max_speakers_expected: (_Q = assemblyaiOptions.speakerOptions.maxSpeakersExpected) != null ? _Q : void 0
355
+ };
356
+ }
357
+ if (assemblyaiOptions.languageDetectionOptions) {
358
+ body.language_detection_options = {
359
+ expected_languages: (_R = assemblyaiOptions.languageDetectionOptions.expectedLanguages) != null ? _R : void 0,
360
+ fallback_language: (_S = assemblyaiOptions.languageDetectionOptions.fallbackLanguage) != null ? _S : void 0,
361
+ code_switching: (_T = assemblyaiOptions.languageDetectionOptions.codeSwitching) != null ? _T : void 0,
362
+ code_switching_confidence_threshold: (_U = assemblyaiOptions.languageDetectionOptions.codeSwitchingConfidenceThreshold) != null ? _U : void 0
363
+ };
364
+ }
365
+ if (assemblyaiOptions.redactPiiAudioOptions) {
366
+ body.redact_pii_audio_options = {
367
+ return_redacted_no_speech_audio: (_V = assemblyaiOptions.redactPiiAudioOptions.returnRedactedNoSpeechAudio) != null ? _V : void 0,
368
+ override_audio_redaction_method: (_W = assemblyaiOptions.redactPiiAudioOptions.overrideAudioRedactionMethod) != null ? _W : void 0
369
+ };
370
+ }
371
+ const deprecatedBoostOptions = [];
372
+ if (assemblyaiOptions.wordBoost != null) {
373
+ deprecatedBoostOptions.push("wordBoost");
374
+ }
375
+ if (assemblyaiOptions.boostParam != null) {
376
+ deprecatedBoostOptions.push("boostParam");
377
+ }
378
+ if (deprecatedBoostOptions.length > 0) {
379
+ warnings.push({
380
+ type: "other",
381
+ message: `${deprecatedBoostOptions.join(", ")} ${deprecatedBoostOptions.length > 1 ? "are" : "is"} deprecated and rejected by 'universal-3-pro' / 'universal-3-5-pro' and 'slam-1'. Use 'keytermsPrompt' instead.`
382
+ });
383
+ }
384
+ if ((assemblyaiOptions.redactPiiReturnUnredacted != null || assemblyaiOptions.redactStaticEntities != null) && !assemblyaiOptions.redactPii) {
385
+ warnings.push({
386
+ type: "other",
387
+ message: "'redactPiiReturnUnredacted' and 'redactStaticEntities' require 'redactPii' to be enabled; AssemblyAI rejects the request otherwise."
388
+ });
389
+ }
390
+ if (assemblyaiOptions.redactPiiAudioOptions != null && !assemblyaiOptions.redactPiiAudio) {
391
+ warnings.push({
392
+ type: "other",
393
+ message: "'redactPiiAudioOptions' only applies when 'redactPiiAudio' is enabled; it is otherwise ignored."
394
+ });
395
+ }
396
+ if (assemblyaiOptions.languageCode != null && assemblyaiOptions.languageDetection) {
397
+ warnings.push({
398
+ type: "other",
399
+ message: "'languageDetection' cannot be combined with an explicit 'languageCode'; AssemblyAI rejects requests that set both."
400
+ });
401
+ }
254
402
  }
255
403
  return {
256
404
  body,
@@ -263,13 +411,14 @@ var AssemblyAITranscriptionModel = class {
263
411
  * @see https://www.assemblyai.com/docs/getting-started/transcribe-an-audio-file#step-33
264
412
  */
265
413
  async waitForCompletion(transcriptId, headers, abortSignal) {
266
- var _a, _b;
414
+ var _a, _b, _c;
267
415
  const pollingInterval = (_a = this.config.pollingInterval) != null ? _a : this.POLLING_INTERVAL_MS;
416
+ const fetchImpl = (_b = this.config.fetch) != null ? _b : globalThis.fetch;
268
417
  while (true) {
269
418
  if (abortSignal == null ? void 0 : abortSignal.aborted) {
270
419
  throw new Error("Transcription request was aborted");
271
420
  }
272
- const response = await fetch(
421
+ const response = await fetchImpl(
273
422
  this.config.url({
274
423
  path: `/v2/transcript/${transcriptId}`,
275
424
  modelId: this.modelId
@@ -293,25 +442,25 @@ var AssemblyAITranscriptionModel = class {
293
442
  requestBodyValues: {}
294
443
  });
295
444
  }
296
- const transcript = assemblyaiTranscriptionResponseSchema.parse(
297
- await response.json()
298
- );
445
+ const rawTranscript = await response.json();
446
+ const transcript = assemblyaiTranscriptionResponseSchema.parse(rawTranscript);
299
447
  if (transcript.status === "completed") {
300
448
  return {
301
449
  transcript,
450
+ rawTranscript,
302
451
  responseHeaders: (0, import_provider_utils2.extractResponseHeaders)(response)
303
452
  };
304
453
  }
305
454
  if (transcript.status === "error") {
306
455
  throw new Error(
307
- `Transcription failed: ${(_b = transcript.error) != null ? _b : "Unknown error"}`
456
+ `Transcription failed: ${(_c = transcript.error) != null ? _c : "Unknown error"}`
308
457
  );
309
458
  }
310
459
  await new Promise((resolve) => setTimeout(resolve, pollingInterval));
311
460
  }
312
461
  }
313
462
  async doGenerate(options) {
314
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
463
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
315
464
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
316
465
  const { value: uploadResponse } = await (0, import_provider_utils2.postToApi)({
317
466
  url: this.config.url({
@@ -351,28 +500,56 @@ var AssemblyAITranscriptionModel = class {
351
500
  abortSignal: options.abortSignal,
352
501
  fetch: this.config.fetch
353
502
  });
354
- const { transcript, responseHeaders } = await this.waitForCompletion(
503
+ const { transcript, rawTranscript, responseHeaders } = await this.waitForCompletion(
355
504
  submitResponse.id,
356
505
  options.headers,
357
506
  options.abortSignal
358
507
  );
508
+ const raw = rawTranscript != null ? rawTranscript : {};
509
+ const assemblyaiMetadata = {};
510
+ if (transcript.utterances != null) {
511
+ assemblyaiMetadata.utterances = raw.utterances;
512
+ }
513
+ if (transcript.sentiment_analysis_results != null) {
514
+ assemblyaiMetadata.sentimentAnalysisResults = raw.sentiment_analysis_results;
515
+ }
516
+ if (transcript.entities != null) {
517
+ assemblyaiMetadata.entities = raw.entities;
518
+ }
519
+ if (transcript.content_safety_labels != null) {
520
+ assemblyaiMetadata.contentSafetyLabels = raw.content_safety_labels;
521
+ }
522
+ if (transcript.iab_categories_result != null) {
523
+ assemblyaiMetadata.iabCategoriesResult = raw.iab_categories_result;
524
+ }
525
+ if (transcript.auto_highlights_result != null) {
526
+ assemblyaiMetadata.autoHighlightsResult = raw.auto_highlights_result;
527
+ }
528
+ const lastWordEndMs = (_e = (_d = transcript.words) == null ? void 0 : _d.at(-1)) == null ? void 0 : _e.end;
359
529
  return {
360
- text: (_d = transcript.text) != null ? _d : "",
361
- segments: (_f = (_e = transcript.words) == null ? void 0 : _e.map((word) => ({
530
+ text: (_f = transcript.text) != null ? _f : "",
531
+ // AssemblyAI returns word timings in milliseconds; the AI SDK reports
532
+ // segment timings in seconds.
533
+ segments: (_h = (_g = transcript.words) == null ? void 0 : _g.map((word) => ({
362
534
  text: word.text,
363
- startSecond: word.start,
364
- endSecond: word.end
365
- }))) != null ? _f : [],
366
- language: (_g = transcript.language_code) != null ? _g : void 0,
367
- durationInSeconds: (_k = (_j = transcript.audio_duration) != null ? _j : (_i = (_h = transcript.words) == null ? void 0 : _h.at(-1)) == null ? void 0 : _i.end) != null ? _k : void 0,
535
+ startSecond: word.start / 1e3,
536
+ endSecond: word.end / 1e3
537
+ }))) != null ? _h : [],
538
+ language: (_i = transcript.language_code) != null ? _i : void 0,
539
+ durationInSeconds: (_j = transcript.audio_duration) != null ? _j : lastWordEndMs != null ? lastWordEndMs / 1e3 : void 0,
368
540
  warnings,
541
+ ...Object.keys(assemblyaiMetadata).length > 0 && {
542
+ providerMetadata: {
543
+ assemblyai: assemblyaiMetadata
544
+ }
545
+ },
369
546
  response: {
370
547
  timestamp: currentDate,
371
548
  modelId: this.modelId,
372
549
  headers: responseHeaders,
373
550
  // Headers from final GET request
374
- body: transcript
375
- // Raw response from final GET request
551
+ body: rawTranscript
552
+ // Full raw response from final GET request
376
553
  }
377
554
  };
378
555
  }
@@ -384,24 +561,64 @@ var assemblyaiSubmitResponseSchema = import_v42.z.object({
384
561
  id: import_v42.z.string(),
385
562
  status: import_v42.z.enum(["queued", "processing", "completed", "error"])
386
563
  });
564
+ var assemblyaiWordSchema = import_v42.z.object({
565
+ start: import_v42.z.number(),
566
+ end: import_v42.z.number(),
567
+ text: import_v42.z.string(),
568
+ confidence: import_v42.z.number().nullish(),
569
+ // Speaker label (e.g. 'A', 'B') when speaker diarization is enabled, else null.
570
+ speaker: import_v42.z.string().nullish(),
571
+ channel: import_v42.z.string().nullish()
572
+ });
387
573
  var assemblyaiTranscriptionResponseSchema = import_v42.z.object({
388
574
  id: import_v42.z.string(),
389
575
  status: import_v42.z.enum(["queued", "processing", "completed", "error"]),
390
576
  text: import_v42.z.string().nullish(),
391
577
  language_code: import_v42.z.string().nullish(),
392
- words: import_v42.z.array(
578
+ speech_model_used: import_v42.z.string().nullish(),
579
+ words: import_v42.z.array(assemblyaiWordSchema).nullish(),
580
+ // Speaker-diarized utterances (present when `speaker_labels` is enabled).
581
+ utterances: import_v42.z.array(
393
582
  import_v42.z.object({
394
583
  start: import_v42.z.number(),
395
584
  end: import_v42.z.number(),
396
- text: import_v42.z.string()
585
+ text: import_v42.z.string(),
586
+ confidence: import_v42.z.number().nullish(),
587
+ speaker: import_v42.z.string().nullish(),
588
+ channel: import_v42.z.string().nullish(),
589
+ words: import_v42.z.array(assemblyaiWordSchema).nullish()
590
+ })
591
+ ).nullish(),
592
+ // Audio-intelligence results, present only when the matching feature is
593
+ // enabled. Kept intentionally permissive (the full structures are also
594
+ // available on the raw `response.body`).
595
+ sentiment_analysis_results: import_v42.z.array(
596
+ import_v42.z.object({
597
+ text: import_v42.z.string(),
598
+ start: import_v42.z.number().nullish(),
599
+ end: import_v42.z.number().nullish(),
600
+ sentiment: import_v42.z.string(),
601
+ confidence: import_v42.z.number().nullish(),
602
+ speaker: import_v42.z.string().nullish()
603
+ })
604
+ ).nullish(),
605
+ entities: import_v42.z.array(
606
+ import_v42.z.object({
607
+ entity_type: import_v42.z.string(),
608
+ text: import_v42.z.string(),
609
+ start: import_v42.z.number().nullish(),
610
+ end: import_v42.z.number().nullish()
397
611
  })
398
612
  ).nullish(),
613
+ content_safety_labels: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).nullish(),
614
+ iab_categories_result: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).nullish(),
615
+ auto_highlights_result: import_v42.z.record(import_v42.z.string(), import_v42.z.any()).nullish(),
399
616
  audio_duration: import_v42.z.number().nullish(),
400
617
  error: import_v42.z.string().nullish()
401
618
  });
402
619
 
403
620
  // src/version.ts
404
- var VERSION = true ? "2.0.40" : "0.0.0-test";
621
+ var VERSION = true ? "2.0.42" : "0.0.0-test";
405
622
 
406
623
  // src/assemblyai-provider.ts
407
624
  function createAssemblyAI(options = {}) {