@ai-sdk/xai 4.0.4 → 4.0.6
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 +18 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +307 -3
- package/dist/index.js.map +1 -1
- package/docs/01-xai.mdx +30 -3
- package/package.json +4 -4
- package/src/xai-provider.ts +8 -0
- package/src/xai-transcription-model-options.ts +27 -0
- package/src/xai-transcription-model.ts +381 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ai-sdk/xai
|
|
2
2
|
|
|
3
|
+
## 4.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5c5c0f5: Add experimental streaming transcription support for transcription models, including OpenAI `gpt-realtime-whisper` and xAI WebSocket STT.
|
|
8
|
+
- Updated dependencies [5c5c0f5]
|
|
9
|
+
- @ai-sdk/provider@4.0.2
|
|
10
|
+
- @ai-sdk/provider-utils@5.0.5
|
|
11
|
+
- @ai-sdk/openai-compatible@3.0.5
|
|
12
|
+
|
|
13
|
+
## 4.0.5
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies [c6f5e62]
|
|
18
|
+
- @ai-sdk/provider-utils@5.0.4
|
|
19
|
+
- @ai-sdk/openai-compatible@3.0.4
|
|
20
|
+
|
|
3
21
|
## 4.0.4
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod/v4';
|
|
2
2
|
import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
3
|
-
import { InferSchema, FetchFunction } from '@ai-sdk/provider-utils';
|
|
3
|
+
import { InferSchema, FetchFunction, WebSocketConstructor } from '@ai-sdk/provider-utils';
|
|
4
4
|
import { ProviderV4, LanguageModelV4, ImageModelV4, Experimental_VideoModelV4, Experimental_RealtimeFactoryV4, SpeechModelV4, TranscriptionModelV4, FilesV4, Experimental_RealtimeModelV4, Experimental_RealtimeModelV4ClientSecretOptions, Experimental_RealtimeModelV4ClientSecretResult, Experimental_RealtimeModelV4ServerEvent, Experimental_RealtimeModelV4ClientEvent, Experimental_RealtimeModelV4SessionConfig } from '@ai-sdk/provider';
|
|
5
5
|
|
|
6
6
|
type XaiChatModelId = 'grok-4.20-non-reasoning' | 'grok-4.20-reasoning' | 'grok-4.3' | 'grok-latest' | (string & {});
|
|
@@ -197,6 +197,12 @@ declare const xaiTranscriptionModelOptionsSchema: _ai_sdk_provider_utils.LazySch
|
|
|
197
197
|
diarize?: boolean | null | undefined;
|
|
198
198
|
keyterm?: string | string[] | null | undefined;
|
|
199
199
|
fillerWords?: boolean | null | undefined;
|
|
200
|
+
streaming?: {
|
|
201
|
+
interimResults?: boolean | undefined;
|
|
202
|
+
endpointing?: number | undefined;
|
|
203
|
+
smartTurn?: number | undefined;
|
|
204
|
+
smartTurnTimeout?: number | undefined;
|
|
205
|
+
} | undefined;
|
|
200
206
|
}>;
|
|
201
207
|
type XaiTranscriptionModelOptions = InferSchema<typeof xaiTranscriptionModelOptionsSchema>;
|
|
202
208
|
|
|
@@ -488,6 +494,11 @@ interface XaiProviderSettings {
|
|
|
488
494
|
* or to provide a custom fetch implementation for e.g. testing.
|
|
489
495
|
*/
|
|
490
496
|
fetch?: FetchFunction;
|
|
497
|
+
/**
|
|
498
|
+
* Custom WebSocket implementation. Required in runtimes whose native
|
|
499
|
+
* WebSocket constructor does not support headers for xAI streaming STT.
|
|
500
|
+
*/
|
|
501
|
+
webSocket?: WebSocketConstructor;
|
|
491
502
|
}
|
|
492
503
|
declare function createXai(options?: XaiProviderSettings): XaiProvider;
|
|
493
504
|
declare const xai: XaiProvider;
|
package/dist/index.js
CHANGED
|
@@ -3393,7 +3393,7 @@ var xaiTools = {
|
|
|
3393
3393
|
};
|
|
3394
3394
|
|
|
3395
3395
|
// src/version.ts
|
|
3396
|
-
var VERSION = true ? "4.0.
|
|
3396
|
+
var VERSION = true ? "4.0.6" : "0.0.0-test";
|
|
3397
3397
|
|
|
3398
3398
|
// src/files/xai-files.ts
|
|
3399
3399
|
import {
|
|
@@ -4058,14 +4058,21 @@ var XaiSpeechModel = class _XaiSpeechModel {
|
|
|
4058
4058
|
};
|
|
4059
4059
|
|
|
4060
4060
|
// src/xai-transcription-model.ts
|
|
4061
|
+
import {
|
|
4062
|
+
InvalidArgumentError
|
|
4063
|
+
} from "@ai-sdk/provider";
|
|
4061
4064
|
import {
|
|
4062
4065
|
combineHeaders as combineHeaders7,
|
|
4063
4066
|
convertBase64ToUint8Array,
|
|
4064
4067
|
createJsonResponseHandler as createJsonResponseHandler6,
|
|
4068
|
+
getWebSocketConstructor,
|
|
4065
4069
|
mediaTypeToExtension,
|
|
4066
4070
|
parseProviderOptions as parseProviderOptions7,
|
|
4067
4071
|
postFormDataToApi as postFormDataToApi2,
|
|
4072
|
+
readWebSocketMessageText,
|
|
4073
|
+
safeParseJSON as safeParseJSON2,
|
|
4068
4074
|
serializeModelOptions as serializeModelOptions5,
|
|
4075
|
+
toWebSocketUrl,
|
|
4069
4076
|
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE5,
|
|
4070
4077
|
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE5
|
|
4071
4078
|
} from "@ai-sdk/provider-utils";
|
|
@@ -4122,7 +4129,28 @@ var xaiTranscriptionModelOptionsSchema = lazySchema9(
|
|
|
4122
4129
|
/**
|
|
4123
4130
|
* Include filler words such as "uh" and "um" in the transcript.
|
|
4124
4131
|
*/
|
|
4125
|
-
fillerWords: z20.boolean().nullish()
|
|
4132
|
+
fillerWords: z20.boolean().nullish(),
|
|
4133
|
+
/**
|
|
4134
|
+
* Options for streaming speech-to-text over WebSocket.
|
|
4135
|
+
*/
|
|
4136
|
+
streaming: z20.object({
|
|
4137
|
+
/**
|
|
4138
|
+
* Emit interim transcript results while speech is being processed.
|
|
4139
|
+
*/
|
|
4140
|
+
interimResults: z20.boolean().optional(),
|
|
4141
|
+
/**
|
|
4142
|
+
* Silence duration in milliseconds before an utterance-final event.
|
|
4143
|
+
*/
|
|
4144
|
+
endpointing: z20.number().int().min(0).max(5e3).optional(),
|
|
4145
|
+
/**
|
|
4146
|
+
* End-of-turn detection threshold. When set, enables Smart Turn.
|
|
4147
|
+
*/
|
|
4148
|
+
smartTurn: z20.number().min(0).max(1).optional(),
|
|
4149
|
+
/**
|
|
4150
|
+
* Maximum silence duration in milliseconds before forcing speech_final.
|
|
4151
|
+
*/
|
|
4152
|
+
smartTurnTimeout: z20.number().int().min(1).max(5e3).optional()
|
|
4153
|
+
}).optional()
|
|
4126
4154
|
})
|
|
4127
4155
|
)
|
|
4128
4156
|
);
|
|
@@ -4225,7 +4253,282 @@ var XaiTranscriptionModel = class _XaiTranscriptionModel {
|
|
|
4225
4253
|
}
|
|
4226
4254
|
};
|
|
4227
4255
|
}
|
|
4256
|
+
async doStream(options) {
|
|
4257
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
4258
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
4259
|
+
const warnings = [];
|
|
4260
|
+
const xaiOptions = await parseProviderOptions7({
|
|
4261
|
+
provider: "xai",
|
|
4262
|
+
providerOptions: options.providerOptions,
|
|
4263
|
+
schema: xaiTranscriptionModelOptionsSchema
|
|
4264
|
+
});
|
|
4265
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.multichannel) === true && xaiOptions.channels == null) {
|
|
4266
|
+
throw new InvalidArgumentError({
|
|
4267
|
+
argument: "providerOptions",
|
|
4268
|
+
message: "providerOptions.xai.channels is required when providerOptions.xai.multichannel is true"
|
|
4269
|
+
});
|
|
4270
|
+
}
|
|
4271
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.format) != null) {
|
|
4272
|
+
warnings.push({
|
|
4273
|
+
type: "unsupported",
|
|
4274
|
+
feature: "providerOptions.xai.format",
|
|
4275
|
+
details: "xAI streaming transcription does not support format."
|
|
4276
|
+
});
|
|
4277
|
+
}
|
|
4278
|
+
if ((xaiOptions == null ? void 0 : xaiOptions.audioFormat) == null && !isKnownInputAudioFormat(options.inputAudioFormat.type)) {
|
|
4279
|
+
warnings.push({
|
|
4280
|
+
type: "other",
|
|
4281
|
+
message: `Unrecognized inputAudioFormat.type "${options.inputAudioFormat.type}"; falling back to raw PCM encoding. Use audio/pcm, audio/pcmu, or audio/pcma, or set providerOptions.xai.audioFormat explicitly.`
|
|
4282
|
+
});
|
|
4283
|
+
}
|
|
4284
|
+
const url = buildXaiStreamingTranscriptionUrl({
|
|
4285
|
+
baseURL: (_d = this.config.baseURL) != null ? _d : "https://api.x.ai/v1",
|
|
4286
|
+
inputAudioFormat: options.inputAudioFormat,
|
|
4287
|
+
providerOptions: xaiOptions
|
|
4288
|
+
});
|
|
4289
|
+
const headers = combineHeaders7((_f = (_e = this.config).headers) == null ? void 0 : _f.call(_e), options.headers);
|
|
4290
|
+
return {
|
|
4291
|
+
request: { body: url.toString() },
|
|
4292
|
+
response: {
|
|
4293
|
+
timestamp: currentDate,
|
|
4294
|
+
modelId: this.modelId
|
|
4295
|
+
},
|
|
4296
|
+
stream: createXaiStreamingTranscriptionStream({
|
|
4297
|
+
webSocket: this.config.webSocket,
|
|
4298
|
+
url,
|
|
4299
|
+
headers,
|
|
4300
|
+
warnings,
|
|
4301
|
+
language: (_g = xaiOptions == null ? void 0 : xaiOptions.language) != null ? _g : void 0,
|
|
4302
|
+
expectedDoneCount: (xaiOptions == null ? void 0 : xaiOptions.multichannel) === true ? xaiOptions.channels : 1,
|
|
4303
|
+
audio: options.audio,
|
|
4304
|
+
abortSignal: options.abortSignal,
|
|
4305
|
+
includeRawChunks: options.includeRawChunks
|
|
4306
|
+
})
|
|
4307
|
+
};
|
|
4308
|
+
}
|
|
4228
4309
|
};
|
|
4310
|
+
function createXaiStreamingTranscriptionStream({
|
|
4311
|
+
webSocket,
|
|
4312
|
+
url,
|
|
4313
|
+
headers,
|
|
4314
|
+
warnings,
|
|
4315
|
+
language,
|
|
4316
|
+
expectedDoneCount,
|
|
4317
|
+
audio,
|
|
4318
|
+
abortSignal,
|
|
4319
|
+
includeRawChunks
|
|
4320
|
+
}) {
|
|
4321
|
+
let finished = false;
|
|
4322
|
+
let cleanup = () => {
|
|
4323
|
+
};
|
|
4324
|
+
return new ReadableStream({
|
|
4325
|
+
start: (controller) => {
|
|
4326
|
+
const WebSocketConstructor = getWebSocketConstructor(webSocket);
|
|
4327
|
+
const ws = new WebSocketConstructor(url, void 0, { headers });
|
|
4328
|
+
const doneTexts = /* @__PURE__ */ new Map();
|
|
4329
|
+
let doneDuration;
|
|
4330
|
+
let audioReader;
|
|
4331
|
+
cleanup = (closeCode) => {
|
|
4332
|
+
abortSignal == null ? void 0 : abortSignal.removeEventListener("abort", abort);
|
|
4333
|
+
void (audioReader == null ? void 0 : audioReader.cancel().catch(() => {
|
|
4334
|
+
}));
|
|
4335
|
+
try {
|
|
4336
|
+
ws.close(closeCode);
|
|
4337
|
+
} catch (e) {
|
|
4338
|
+
}
|
|
4339
|
+
};
|
|
4340
|
+
const finishWithError = (error) => {
|
|
4341
|
+
if (finished) return;
|
|
4342
|
+
finished = true;
|
|
4343
|
+
cleanup();
|
|
4344
|
+
controller.error(error);
|
|
4345
|
+
};
|
|
4346
|
+
const maybeFinish = () => {
|
|
4347
|
+
if (finished || doneTexts.size < expectedDoneCount) return;
|
|
4348
|
+
finished = true;
|
|
4349
|
+
const text = [...doneTexts.entries()].sort(([a], [b]) => a - b).map(([, value]) => value).join("\n");
|
|
4350
|
+
controller.enqueue({
|
|
4351
|
+
type: "finish",
|
|
4352
|
+
text,
|
|
4353
|
+
segments: [],
|
|
4354
|
+
language,
|
|
4355
|
+
durationInSeconds: doneDuration
|
|
4356
|
+
});
|
|
4357
|
+
controller.close();
|
|
4358
|
+
cleanup(1e3);
|
|
4359
|
+
};
|
|
4360
|
+
const abort = () => {
|
|
4361
|
+
var _a;
|
|
4362
|
+
finishWithError((_a = abortSignal == null ? void 0 : abortSignal.reason) != null ? _a : new Error("Aborted"));
|
|
4363
|
+
};
|
|
4364
|
+
if (abortSignal == null ? void 0 : abortSignal.aborted) {
|
|
4365
|
+
abort();
|
|
4366
|
+
return;
|
|
4367
|
+
}
|
|
4368
|
+
abortSignal == null ? void 0 : abortSignal.addEventListener("abort", abort, { once: true });
|
|
4369
|
+
const sendAudio = async () => {
|
|
4370
|
+
audioReader = audio.getReader();
|
|
4371
|
+
try {
|
|
4372
|
+
while (true) {
|
|
4373
|
+
const { done, value } = await audioReader.read();
|
|
4374
|
+
if (done || finished) break;
|
|
4375
|
+
ws.send(
|
|
4376
|
+
value instanceof Uint8Array ? value : convertBase64ToUint8Array(value)
|
|
4377
|
+
);
|
|
4378
|
+
}
|
|
4379
|
+
} finally {
|
|
4380
|
+
audioReader.releaseLock();
|
|
4381
|
+
}
|
|
4382
|
+
if (!finished) {
|
|
4383
|
+
ws.send(JSON.stringify({ type: "audio.done" }));
|
|
4384
|
+
}
|
|
4385
|
+
};
|
|
4386
|
+
ws.onmessage = (event) => {
|
|
4387
|
+
void readWebSocketMessageText(event.data).then(async (text) => {
|
|
4388
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4389
|
+
const parsed = await safeParseJSON2({ text });
|
|
4390
|
+
if (!parsed.success) return;
|
|
4391
|
+
const raw = parsed.value;
|
|
4392
|
+
if (includeRawChunks) {
|
|
4393
|
+
controller.enqueue({ type: "raw", rawValue: raw });
|
|
4394
|
+
}
|
|
4395
|
+
switch (raw.type) {
|
|
4396
|
+
case "transcript.created": {
|
|
4397
|
+
controller.enqueue({ type: "stream-start", warnings });
|
|
4398
|
+
void sendAudio().catch(finishWithError);
|
|
4399
|
+
break;
|
|
4400
|
+
}
|
|
4401
|
+
case "transcript.partial": {
|
|
4402
|
+
const id = channelId(raw.channel_index);
|
|
4403
|
+
const timing = timingFromXaiEvent(raw);
|
|
4404
|
+
if (raw.is_final) {
|
|
4405
|
+
controller.enqueue({
|
|
4406
|
+
type: "transcript-final",
|
|
4407
|
+
id,
|
|
4408
|
+
text: (_a = raw.text) != null ? _a : "",
|
|
4409
|
+
...timing,
|
|
4410
|
+
channelIndex: raw.channel_index
|
|
4411
|
+
});
|
|
4412
|
+
} else {
|
|
4413
|
+
controller.enqueue({
|
|
4414
|
+
type: "transcript-partial",
|
|
4415
|
+
id,
|
|
4416
|
+
text: (_b = raw.text) != null ? _b : "",
|
|
4417
|
+
startSecond: raw.start,
|
|
4418
|
+
durationInSeconds: raw.duration,
|
|
4419
|
+
channelIndex: raw.channel_index
|
|
4420
|
+
});
|
|
4421
|
+
}
|
|
4422
|
+
break;
|
|
4423
|
+
}
|
|
4424
|
+
case "transcript.done": {
|
|
4425
|
+
const channelIndex = (_c = raw.channel_index) != null ? _c : 0;
|
|
4426
|
+
doneTexts.set(channelIndex, (_d = raw.text) != null ? _d : "");
|
|
4427
|
+
doneDuration = (_e = raw.duration) != null ? _e : doneDuration;
|
|
4428
|
+
maybeFinish();
|
|
4429
|
+
break;
|
|
4430
|
+
}
|
|
4431
|
+
case "error": {
|
|
4432
|
+
finishWithError(new Error((_f = raw.message) != null ? _f : "xAI STT error"));
|
|
4433
|
+
break;
|
|
4434
|
+
}
|
|
4435
|
+
}
|
|
4436
|
+
}).catch(finishWithError);
|
|
4437
|
+
};
|
|
4438
|
+
ws.onerror = () => {
|
|
4439
|
+
finishWithError(
|
|
4440
|
+
new Error(
|
|
4441
|
+
"xAI streaming transcription error." + (webSocket == null ? " Note: the native WebSocket implementation in browsers, Node.js, Deno, and Bun cannot send the Authorization header required by xAI. Pass a header-capable WebSocket implementation (e.g. the 'ws' package) via createXai({ webSocket })." : "")
|
|
4442
|
+
)
|
|
4443
|
+
);
|
|
4444
|
+
};
|
|
4445
|
+
ws.onclose = () => {
|
|
4446
|
+
if (finished) return;
|
|
4447
|
+
finished = true;
|
|
4448
|
+
cleanup();
|
|
4449
|
+
controller.close();
|
|
4450
|
+
};
|
|
4451
|
+
},
|
|
4452
|
+
cancel: () => {
|
|
4453
|
+
if (finished) return;
|
|
4454
|
+
finished = true;
|
|
4455
|
+
cleanup();
|
|
4456
|
+
}
|
|
4457
|
+
});
|
|
4458
|
+
}
|
|
4459
|
+
function buildXaiStreamingTranscriptionUrl({
|
|
4460
|
+
baseURL,
|
|
4461
|
+
inputAudioFormat,
|
|
4462
|
+
providerOptions
|
|
4463
|
+
}) {
|
|
4464
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4465
|
+
const url = toWebSocketUrl(`${baseURL}/stt`);
|
|
4466
|
+
appendSearchParam(
|
|
4467
|
+
url,
|
|
4468
|
+
"sample_rate",
|
|
4469
|
+
(_a = providerOptions == null ? void 0 : providerOptions.sampleRate) != null ? _a : inputAudioFormat.rate
|
|
4470
|
+
);
|
|
4471
|
+
appendSearchParam(
|
|
4472
|
+
url,
|
|
4473
|
+
"encoding",
|
|
4474
|
+
(_b = providerOptions == null ? void 0 : providerOptions.audioFormat) != null ? _b : encodingFromInputAudioFormat(inputAudioFormat.type)
|
|
4475
|
+
);
|
|
4476
|
+
appendSearchParam(url, "language", providerOptions == null ? void 0 : providerOptions.language);
|
|
4477
|
+
appendSearchParam(url, "diarize", providerOptions == null ? void 0 : providerOptions.diarize);
|
|
4478
|
+
appendSearchParam(url, "filler_words", providerOptions == null ? void 0 : providerOptions.fillerWords);
|
|
4479
|
+
appendSearchParam(url, "multichannel", providerOptions == null ? void 0 : providerOptions.multichannel);
|
|
4480
|
+
appendSearchParam(url, "channels", providerOptions == null ? void 0 : providerOptions.channels);
|
|
4481
|
+
appendSearchParam(
|
|
4482
|
+
url,
|
|
4483
|
+
"interim_results",
|
|
4484
|
+
(_c = providerOptions == null ? void 0 : providerOptions.streaming) == null ? void 0 : _c.interimResults
|
|
4485
|
+
);
|
|
4486
|
+
appendSearchParam(
|
|
4487
|
+
url,
|
|
4488
|
+
"endpointing",
|
|
4489
|
+
(_d = providerOptions == null ? void 0 : providerOptions.streaming) == null ? void 0 : _d.endpointing
|
|
4490
|
+
);
|
|
4491
|
+
appendSearchParam(url, "smart_turn", (_e = providerOptions == null ? void 0 : providerOptions.streaming) == null ? void 0 : _e.smartTurn);
|
|
4492
|
+
appendSearchParam(
|
|
4493
|
+
url,
|
|
4494
|
+
"smart_turn_timeout",
|
|
4495
|
+
(_f = providerOptions == null ? void 0 : providerOptions.streaming) == null ? void 0 : _f.smartTurnTimeout
|
|
4496
|
+
);
|
|
4497
|
+
if ((providerOptions == null ? void 0 : providerOptions.keyterm) != null) {
|
|
4498
|
+
const keyterms = Array.isArray(providerOptions.keyterm) ? providerOptions.keyterm : [providerOptions.keyterm];
|
|
4499
|
+
for (const keyterm of keyterms) {
|
|
4500
|
+
url.searchParams.append("keyterm", keyterm);
|
|
4501
|
+
}
|
|
4502
|
+
}
|
|
4503
|
+
return url;
|
|
4504
|
+
}
|
|
4505
|
+
function appendSearchParam(url, key, value) {
|
|
4506
|
+
if (value != null) {
|
|
4507
|
+
url.searchParams.set(key, String(value));
|
|
4508
|
+
}
|
|
4509
|
+
}
|
|
4510
|
+
function isKnownInputAudioFormat(type) {
|
|
4511
|
+
return type === "audio/pcm" || type === "audio/pcmu" || type === "audio/pcma";
|
|
4512
|
+
}
|
|
4513
|
+
function encodingFromInputAudioFormat(type) {
|
|
4514
|
+
switch (type) {
|
|
4515
|
+
case "audio/pcmu":
|
|
4516
|
+
return "mulaw";
|
|
4517
|
+
case "audio/pcma":
|
|
4518
|
+
return "alaw";
|
|
4519
|
+
default:
|
|
4520
|
+
return "pcm";
|
|
4521
|
+
}
|
|
4522
|
+
}
|
|
4523
|
+
function channelId(channelIndex) {
|
|
4524
|
+
return channelIndex == null ? void 0 : `channel-${channelIndex}`;
|
|
4525
|
+
}
|
|
4526
|
+
function timingFromXaiEvent(event) {
|
|
4527
|
+
return {
|
|
4528
|
+
...event.start != null ? { startSecond: event.start } : {},
|
|
4529
|
+
...event.start != null && event.duration != null ? { endSecond: event.start + event.duration } : {}
|
|
4530
|
+
};
|
|
4531
|
+
}
|
|
4229
4532
|
var xaiTranscriptionResponseSchema = z21.object({
|
|
4230
4533
|
text: z21.string(),
|
|
4231
4534
|
language: z21.string().nullish(),
|
|
@@ -4311,7 +4614,8 @@ function createXai(options = {}) {
|
|
|
4311
4614
|
provider: "xai.transcription",
|
|
4312
4615
|
baseURL,
|
|
4313
4616
|
headers: getHeaders,
|
|
4314
|
-
fetch: options.fetch
|
|
4617
|
+
fetch: options.fetch,
|
|
4618
|
+
webSocket: options.webSocket
|
|
4315
4619
|
});
|
|
4316
4620
|
};
|
|
4317
4621
|
const experimentalRealtimeFactory = Object.assign(
|