@ai-sdk/openai 4.0.21 → 4.0.22
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 +9 -0
- package/dist/index.d.ts +58 -3
- package/dist/index.js +349 -22
- package/dist/index.js.map +1 -1
- package/docs/03-openai.mdx +44 -0
- package/package.json +2 -2
- package/src/index.ts +5 -0
- package/src/openai-provider.ts +27 -0
- package/src/translation/openai-translation-model-options.ts +16 -0
- package/src/translation/openai-translation-model.ts +397 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 4.0.22
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- c49380c: feat: add experimental streaming speech translation models (`openai.translation('gpt-realtime-translate')` over the OpenAI Realtime translations WebSocket and `google.translation('gemini-3.5-live-translate-preview')` over the Gemini Live API). `connectToWebSocket` in `@ai-sdk/provider-utils` now passes close code and reason to `onClose` (additive, optional parameter).
|
|
8
|
+
- Updated dependencies [0c464d9]
|
|
9
|
+
- Updated dependencies [c49380c]
|
|
10
|
+
- @ai-sdk/provider-utils@5.0.14
|
|
11
|
+
|
|
3
12
|
## 4.0.21
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as _ai_sdk_provider from '@ai-sdk/provider';
|
|
2
|
-
import { JSONValue, ProviderV4, LanguageModelV4, EmbeddingModelV4, ImageModelV4, TranscriptionModelV4, SpeechModelV4, Experimental_RealtimeFactoryV4, FilesV4, SkillsV4, Experimental_RealtimeModelV4, Experimental_RealtimeModelV4ClientSecretOptions, Experimental_RealtimeModelV4ClientSecretResult, Experimental_RealtimeModelV4ServerEvent, Experimental_RealtimeModelV4ClientEvent, Experimental_RealtimeModelV4SessionConfig, JSONObject } from '@ai-sdk/provider';
|
|
2
|
+
import { JSONValue, ProviderV4, LanguageModelV4, EmbeddingModelV4, ImageModelV4, TranscriptionModelV4, Experimental_SpeechTranslationModelV4, SpeechModelV4, Experimental_RealtimeFactoryV4, FilesV4, SkillsV4, Experimental_RealtimeModelV4, Experimental_RealtimeModelV4ClientSecretOptions, Experimental_RealtimeModelV4ClientSecretResult, Experimental_RealtimeModelV4ServerEvent, Experimental_RealtimeModelV4ClientEvent, Experimental_RealtimeModelV4SessionConfig, JSONObject, Experimental_SpeechTranslationModelV4StreamOptions } from '@ai-sdk/provider';
|
|
3
3
|
import * as _ai_sdk_provider_utils from '@ai-sdk/provider-utils';
|
|
4
|
-
import { InferSchema, FetchFunction, WebSocketConstructor } from '@ai-sdk/provider-utils';
|
|
4
|
+
import { InferSchema, FetchFunction, WebSocketConstructor, WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@ai-sdk/provider-utils';
|
|
5
5
|
import { z } from 'zod/v4';
|
|
6
6
|
|
|
7
7
|
type OpenAIChatModelId = 'o1' | 'o1-2024-12-17' | 'o3-mini' | 'o3-mini-2025-01-31' | 'o3' | 'o3-2025-04-16' | 'o4-mini' | 'o4-mini-2025-04-16' | 'gpt-4.1' | 'gpt-4.1-2025-04-14' | 'gpt-4.1-mini' | 'gpt-4.1-mini-2025-04-14' | 'gpt-4.1-nano' | 'gpt-4.1-nano-2025-04-14' | 'gpt-4o' | 'gpt-4o-2024-05-13' | 'gpt-4o-2024-08-06' | 'gpt-4o-2024-11-20' | 'gpt-4o-audio-preview' | 'gpt-4o-audio-preview-2024-12-17' | 'gpt-4o-audio-preview-2025-06-03' | 'gpt-4o-mini' | 'gpt-4o-mini-2024-07-18' | 'gpt-4o-mini-audio-preview' | 'gpt-4o-mini-audio-preview-2024-12-17' | 'gpt-4o-search-preview' | 'gpt-4o-search-preview-2025-03-11' | 'gpt-4o-mini-search-preview' | 'gpt-4o-mini-search-preview-2025-03-11' | 'gpt-3.5-turbo-0125' | 'gpt-3.5-turbo' | 'gpt-3.5-turbo-1106' | 'gpt-3.5-turbo-16k' | 'gpt-5' | 'gpt-5-2025-08-07' | 'gpt-5-mini' | 'gpt-5-mini-2025-08-07' | 'gpt-5-nano' | 'gpt-5-nano-2025-08-07' | 'gpt-5-chat-latest' | 'gpt-5.1' | 'gpt-5.1-2025-11-13' | 'gpt-5.1-chat-latest' | 'gpt-5.2' | 'gpt-5.2-2025-12-11' | 'gpt-5.2-chat-latest' | 'gpt-5.2-pro' | 'gpt-5.2-pro-2025-12-11' | 'gpt-5.3-chat-latest' | 'gpt-5.4' | 'gpt-5.4-2026-03-05' | 'gpt-5.4-mini' | 'gpt-5.4-mini-2026-03-17' | 'gpt-5.4-nano' | 'gpt-5.4-nano-2026-03-17' | 'gpt-5.4-pro' | 'gpt-5.4-pro-2026-03-05' | 'gpt-5.5' | 'gpt-5.5-2026-04-23' | 'gpt-5.6' | 'gpt-5.6-luna' | 'gpt-5.6-sol' | 'gpt-5.6-terra' | (string & {});
|
|
@@ -1388,6 +1388,10 @@ declare const openAITranscriptionModelOptions: _ai_sdk_provider_utils.LazySchema
|
|
|
1388
1388
|
}>;
|
|
1389
1389
|
type OpenAITranscriptionModelOptions = InferSchema<typeof openAITranscriptionModelOptions>;
|
|
1390
1390
|
|
|
1391
|
+
type OpenAITranslationModelId = 'gpt-realtime-translate' | (string & {});
|
|
1392
|
+
declare const openAITranslationModelOptions: _ai_sdk_provider_utils.LazySchema<Record<string, never>>;
|
|
1393
|
+
type OpenAITranslationModelOptions = InferSchema<typeof openAITranslationModelOptions>;
|
|
1394
|
+
|
|
1391
1395
|
interface OpenAIProvider extends ProviderV4 {
|
|
1392
1396
|
(modelId: OpenAIResponsesModelId): LanguageModelV4;
|
|
1393
1397
|
/**
|
|
@@ -1434,6 +1438,14 @@ interface OpenAIProvider extends ProviderV4 {
|
|
|
1434
1438
|
* Creates a model for transcription.
|
|
1435
1439
|
*/
|
|
1436
1440
|
transcription(modelId: OpenAITranscriptionModelId): TranscriptionModelV4;
|
|
1441
|
+
/**
|
|
1442
|
+
* Creates an experimental model for streaming speech translation.
|
|
1443
|
+
*/
|
|
1444
|
+
translation(modelId: OpenAITranslationModelId): Experimental_SpeechTranslationModelV4;
|
|
1445
|
+
/**
|
|
1446
|
+
* Creates an experimental model for streaming speech translation.
|
|
1447
|
+
*/
|
|
1448
|
+
speechTranslationModel(modelId: OpenAITranslationModelId): Experimental_SpeechTranslationModelV4;
|
|
1437
1449
|
/**
|
|
1438
1450
|
* Creates a model for speech generation.
|
|
1439
1451
|
*/
|
|
@@ -1536,6 +1548,49 @@ type OpenAIToolOptions = {
|
|
|
1536
1548
|
};
|
|
1537
1549
|
};
|
|
1538
1550
|
|
|
1551
|
+
type OpenAIConfig = {
|
|
1552
|
+
provider: string;
|
|
1553
|
+
url: (options: {
|
|
1554
|
+
modelId: string;
|
|
1555
|
+
path: string;
|
|
1556
|
+
}) => string;
|
|
1557
|
+
headers?: () => Record<string, string | undefined>;
|
|
1558
|
+
fetch?: FetchFunction;
|
|
1559
|
+
webSocket?: WebSocketConstructor;
|
|
1560
|
+
generateId?: () => string;
|
|
1561
|
+
/**
|
|
1562
|
+
* This is soft-deprecated. Use provider references (e.g. `{ openai: 'file-abc123' }`)
|
|
1563
|
+
* in file part data instead. File ID prefixes used to identify file IDs
|
|
1564
|
+
* in Responses API. When undefined, all string file data is treated as
|
|
1565
|
+
* base64 content.
|
|
1566
|
+
*
|
|
1567
|
+
* TODO: remove in v8
|
|
1568
|
+
*/
|
|
1569
|
+
fileIdPrefixes?: readonly string[];
|
|
1570
|
+
};
|
|
1571
|
+
|
|
1572
|
+
interface OpenAITranslationModelConfig extends OpenAIConfig {
|
|
1573
|
+
_internal?: {
|
|
1574
|
+
currentDate?: () => Date;
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
declare class OpenAITranslationModel implements Experimental_SpeechTranslationModelV4 {
|
|
1578
|
+
readonly modelId: OpenAITranslationModelId;
|
|
1579
|
+
private readonly config;
|
|
1580
|
+
readonly specificationVersion = "v4";
|
|
1581
|
+
static [WORKFLOW_SERIALIZE](model: OpenAITranslationModel): {
|
|
1582
|
+
modelId: string;
|
|
1583
|
+
config: _ai_sdk_provider.JSONObject;
|
|
1584
|
+
};
|
|
1585
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
1586
|
+
modelId: OpenAITranslationModelId;
|
|
1587
|
+
config: OpenAITranslationModelConfig;
|
|
1588
|
+
}): OpenAITranslationModel;
|
|
1589
|
+
get provider(): string;
|
|
1590
|
+
constructor(modelId: OpenAITranslationModelId, config: OpenAITranslationModelConfig);
|
|
1591
|
+
doStream(options: Experimental_SpeechTranslationModelV4StreamOptions): Promise<Awaited<ReturnType<Experimental_SpeechTranslationModelV4['doStream']>>>;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1539
1594
|
declare const openaiFilesOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
|
|
1540
1595
|
purpose?: string | undefined;
|
|
1541
1596
|
expiresAfter?: number | undefined;
|
|
@@ -1652,4 +1707,4 @@ type OpenaiResponsesSourceDocumentProviderMetadata = {
|
|
|
1652
1707
|
|
|
1653
1708
|
declare const VERSION: string;
|
|
1654
1709
|
|
|
1655
|
-
export { OpenAIRealtimeModel as Experimental_OpenAIRealtimeModel, type OpenAIRealtimeModelConfig as Experimental_OpenAIRealtimeModelConfig, type OpenAILanguageModelChatOptions as OpenAIChatLanguageModelOptions, type OpenAIComputerAction, type OpenAIComputerSafetyCheck, type OpenAIEmbeddingModelOptions, type OpenAIFilesOptions, type OpenAIImageModelEditOptions, type OpenAIImageModelGenerationOptions, type OpenAIImageModelOptions, type OpenAILanguageModelChatOptions, type OpenAILanguageModelCompletionOptions, type OpenAILanguageModelResponsesOptions, type OpenAIProvider, type OpenAIProviderSettings, type OpenAILanguageModelResponsesOptions as OpenAIResponsesProviderOptions, type OpenAISpeechModelOptions, type OpenAIToolOptions, type OpenAITranscriptionModelOptions, type OpenaiResponsesCompactionProviderMetadata, type OpenaiResponsesProviderMetadata, type OpenaiResponsesReasoningProviderMetadata, type OpenaiResponsesSourceDocumentProviderMetadata, type OpenaiResponsesTextProviderMetadata, VERSION, createOpenAI, openai };
|
|
1710
|
+
export { OpenAIRealtimeModel as Experimental_OpenAIRealtimeModel, type OpenAIRealtimeModelConfig as Experimental_OpenAIRealtimeModelConfig, OpenAITranslationModel as Experimental_OpenAITranslationModel, type OpenAITranslationModelId as Experimental_OpenAITranslationModelId, type OpenAITranslationModelOptions as Experimental_OpenAITranslationModelOptions, type OpenAILanguageModelChatOptions as OpenAIChatLanguageModelOptions, type OpenAIComputerAction, type OpenAIComputerSafetyCheck, type OpenAIEmbeddingModelOptions, type OpenAIFilesOptions, type OpenAIImageModelEditOptions, type OpenAIImageModelGenerationOptions, type OpenAIImageModelOptions, type OpenAILanguageModelChatOptions, type OpenAILanguageModelCompletionOptions, type OpenAILanguageModelResponsesOptions, type OpenAIProvider, type OpenAIProviderSettings, type OpenAILanguageModelResponsesOptions as OpenAIResponsesProviderOptions, type OpenAISpeechModelOptions, type OpenAIToolOptions, type OpenAITranscriptionModelOptions, type OpenaiResponsesCompactionProviderMetadata, type OpenaiResponsesProviderMetadata, type OpenaiResponsesReasoningProviderMetadata, type OpenaiResponsesSourceDocumentProviderMetadata, type OpenaiResponsesTextProviderMetadata, VERSION, createOpenAI, openai };
|
package/dist/index.js
CHANGED
|
@@ -9014,37 +9014,354 @@ function getOpenAIRealtimeConnection(headers) {
|
|
|
9014
9014
|
};
|
|
9015
9015
|
}
|
|
9016
9016
|
|
|
9017
|
-
// src/
|
|
9017
|
+
// src/translation/openai-translation-model.ts
|
|
9018
|
+
import {
|
|
9019
|
+
InvalidArgumentError
|
|
9020
|
+
} from "@ai-sdk/provider";
|
|
9018
9021
|
import {
|
|
9019
9022
|
combineHeaders as combineHeaders9,
|
|
9023
|
+
connectToWebSocket as connectToWebSocket2,
|
|
9024
|
+
convertToBase64 as convertToBase644,
|
|
9025
|
+
parseProviderOptions as parseProviderOptions10,
|
|
9026
|
+
safeParseJSON as safeParseJSON2,
|
|
9027
|
+
serializeModelOptions as serializeModelOptions8,
|
|
9028
|
+
toWebSocketUrl as toWebSocketUrl2,
|
|
9029
|
+
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE8,
|
|
9030
|
+
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE8,
|
|
9031
|
+
waitForWebSocketBufferDrain as waitForWebSocketBufferDrain2
|
|
9032
|
+
} from "@ai-sdk/provider-utils";
|
|
9033
|
+
|
|
9034
|
+
// src/translation/openai-translation-model-options.ts
|
|
9035
|
+
import {
|
|
9036
|
+
lazySchema as lazySchema29,
|
|
9037
|
+
zodSchema as zodSchema29
|
|
9038
|
+
} from "@ai-sdk/provider-utils";
|
|
9039
|
+
import { z as z31 } from "zod/v4";
|
|
9040
|
+
var openAITranslationModelOptions = lazySchema29(
|
|
9041
|
+
() => zodSchema29(z31.object({}))
|
|
9042
|
+
);
|
|
9043
|
+
|
|
9044
|
+
// src/translation/openai-translation-model.ts
|
|
9045
|
+
var OpenAITranslationModel = class _OpenAITranslationModel {
|
|
9046
|
+
constructor(modelId, config) {
|
|
9047
|
+
this.modelId = modelId;
|
|
9048
|
+
this.config = config;
|
|
9049
|
+
this.specificationVersion = "v4";
|
|
9050
|
+
}
|
|
9051
|
+
static [WORKFLOW_SERIALIZE8](model) {
|
|
9052
|
+
return serializeModelOptions8({
|
|
9053
|
+
modelId: model.modelId,
|
|
9054
|
+
config: model.config
|
|
9055
|
+
});
|
|
9056
|
+
}
|
|
9057
|
+
static [WORKFLOW_DESERIALIZE8](options) {
|
|
9058
|
+
return new _OpenAITranslationModel(options.modelId, options.config);
|
|
9059
|
+
}
|
|
9060
|
+
get provider() {
|
|
9061
|
+
return this.config.provider;
|
|
9062
|
+
}
|
|
9063
|
+
async doStream(options) {
|
|
9064
|
+
var _a, _b, _c, _d, _e;
|
|
9065
|
+
if (options.targetLanguage == null) {
|
|
9066
|
+
throw new InvalidArgumentError({
|
|
9067
|
+
argument: "targetLanguage",
|
|
9068
|
+
message: `targetLanguage is required for translation model '${this.modelId}'.`
|
|
9069
|
+
});
|
|
9070
|
+
}
|
|
9071
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
9072
|
+
await parseProviderOptions10({
|
|
9073
|
+
provider: "openai",
|
|
9074
|
+
providerOptions: options.providerOptions,
|
|
9075
|
+
schema: openAITranslationModelOptions
|
|
9076
|
+
});
|
|
9077
|
+
const warnings = [];
|
|
9078
|
+
validateOpenAITranslationInputAudioFormat(options.inputAudioFormat);
|
|
9079
|
+
if (options.sourceLanguage != null) {
|
|
9080
|
+
warnings.push({
|
|
9081
|
+
type: "unsupported",
|
|
9082
|
+
feature: "sourceLanguage",
|
|
9083
|
+
details: "The OpenAI Realtime translation API auto-detects the source language and does not accept a source language."
|
|
9084
|
+
});
|
|
9085
|
+
}
|
|
9086
|
+
if (options.outputAudioFormat != null) {
|
|
9087
|
+
warnings.push({
|
|
9088
|
+
type: "unsupported",
|
|
9089
|
+
feature: "outputAudioFormat",
|
|
9090
|
+
details: "The OpenAI Realtime translation API always outputs 24kHz 16-bit PCM audio and does not accept an output audio format."
|
|
9091
|
+
});
|
|
9092
|
+
}
|
|
9093
|
+
const headers = combineHeaders9((_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d), options.headers);
|
|
9094
|
+
const sessionUpdate = buildOpenAIRealtimeTranslationSession({
|
|
9095
|
+
targetLanguage: options.targetLanguage
|
|
9096
|
+
});
|
|
9097
|
+
return {
|
|
9098
|
+
request: { body: sessionUpdate },
|
|
9099
|
+
response: {
|
|
9100
|
+
timestamp: currentDate,
|
|
9101
|
+
modelId: this.modelId
|
|
9102
|
+
},
|
|
9103
|
+
stream: createOpenAIRealtimeTranslationStream({
|
|
9104
|
+
webSocket: this.config.webSocket,
|
|
9105
|
+
url: toWebSocketUrl2(
|
|
9106
|
+
this.config.url({
|
|
9107
|
+
path: `/realtime/translations?model=${encodeURIComponent(this.modelId)}`,
|
|
9108
|
+
modelId: this.modelId
|
|
9109
|
+
})
|
|
9110
|
+
),
|
|
9111
|
+
headers,
|
|
9112
|
+
sessionUpdate,
|
|
9113
|
+
warnings,
|
|
9114
|
+
audio: options.audio,
|
|
9115
|
+
abortSignal: options.abortSignal,
|
|
9116
|
+
includeRawChunks: options.includeRawChunks
|
|
9117
|
+
})
|
|
9118
|
+
};
|
|
9119
|
+
}
|
|
9120
|
+
};
|
|
9121
|
+
function createOpenAIRealtimeTranslationStream({
|
|
9122
|
+
webSocket,
|
|
9123
|
+
url,
|
|
9124
|
+
headers,
|
|
9125
|
+
sessionUpdate,
|
|
9126
|
+
warnings,
|
|
9127
|
+
audio,
|
|
9128
|
+
abortSignal,
|
|
9129
|
+
includeRawChunks
|
|
9130
|
+
}) {
|
|
9131
|
+
let finished = false;
|
|
9132
|
+
let cleanup = () => {
|
|
9133
|
+
};
|
|
9134
|
+
return new ReadableStream({
|
|
9135
|
+
start: (controller) => {
|
|
9136
|
+
const realtimeConnection = getOpenAIRealtimeConnection2(headers);
|
|
9137
|
+
let audioReader;
|
|
9138
|
+
let connection;
|
|
9139
|
+
let sourceText = "";
|
|
9140
|
+
let translationText = "";
|
|
9141
|
+
cleanup = (closeCode) => {
|
|
9142
|
+
if (audioReader != null) {
|
|
9143
|
+
void audioReader.cancel().catch(() => {
|
|
9144
|
+
});
|
|
9145
|
+
} else {
|
|
9146
|
+
void audio.cancel().catch(() => {
|
|
9147
|
+
});
|
|
9148
|
+
}
|
|
9149
|
+
connection == null ? void 0 : connection.close(closeCode);
|
|
9150
|
+
};
|
|
9151
|
+
const finishWithError = (error) => {
|
|
9152
|
+
if (finished) return;
|
|
9153
|
+
finished = true;
|
|
9154
|
+
cleanup();
|
|
9155
|
+
controller.error(error);
|
|
9156
|
+
};
|
|
9157
|
+
const finish = () => {
|
|
9158
|
+
if (finished) return;
|
|
9159
|
+
finished = true;
|
|
9160
|
+
if (sourceText !== "") {
|
|
9161
|
+
controller.enqueue({
|
|
9162
|
+
type: "source-transcript-final",
|
|
9163
|
+
text: sourceText
|
|
9164
|
+
});
|
|
9165
|
+
}
|
|
9166
|
+
if (translationText !== "") {
|
|
9167
|
+
controller.enqueue({
|
|
9168
|
+
type: "output-text-final",
|
|
9169
|
+
text: translationText
|
|
9170
|
+
});
|
|
9171
|
+
}
|
|
9172
|
+
controller.enqueue({
|
|
9173
|
+
type: "finish",
|
|
9174
|
+
sourceText,
|
|
9175
|
+
outputText: translationText,
|
|
9176
|
+
usage: void 0
|
|
9177
|
+
});
|
|
9178
|
+
controller.close();
|
|
9179
|
+
cleanup(1e3);
|
|
9180
|
+
};
|
|
9181
|
+
const sendAudio = async (socket) => {
|
|
9182
|
+
audioReader = audio.getReader();
|
|
9183
|
+
try {
|
|
9184
|
+
while (true) {
|
|
9185
|
+
const { done, value } = await audioReader.read();
|
|
9186
|
+
if (done || finished) break;
|
|
9187
|
+
socket.send(
|
|
9188
|
+
JSON.stringify({
|
|
9189
|
+
type: "session.input_audio_buffer.append",
|
|
9190
|
+
audio: convertToBase644(value)
|
|
9191
|
+
})
|
|
9192
|
+
);
|
|
9193
|
+
await waitForWebSocketBufferDrain2(socket);
|
|
9194
|
+
}
|
|
9195
|
+
} finally {
|
|
9196
|
+
audioReader.releaseLock();
|
|
9197
|
+
audioReader = void 0;
|
|
9198
|
+
}
|
|
9199
|
+
if (!finished) {
|
|
9200
|
+
socket.send(JSON.stringify({ type: "session.close" }));
|
|
9201
|
+
}
|
|
9202
|
+
};
|
|
9203
|
+
connection = connectToWebSocket2({
|
|
9204
|
+
url,
|
|
9205
|
+
protocols: realtimeConnection.protocols,
|
|
9206
|
+
headers: realtimeConnection.headers,
|
|
9207
|
+
webSocket,
|
|
9208
|
+
abortSignal,
|
|
9209
|
+
onAbort: finishWithError,
|
|
9210
|
+
onProcessingError: finishWithError,
|
|
9211
|
+
onOpen: (socket) => {
|
|
9212
|
+
controller.enqueue({ type: "stream-start", warnings });
|
|
9213
|
+
socket.send(JSON.stringify(sessionUpdate));
|
|
9214
|
+
void sendAudio(socket).catch(finishWithError);
|
|
9215
|
+
},
|
|
9216
|
+
onMessageText: async (text) => {
|
|
9217
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9218
|
+
if (finished) return;
|
|
9219
|
+
const parsed = await safeParseJSON2({ text });
|
|
9220
|
+
if (!parsed.success) return;
|
|
9221
|
+
const raw = parsed.value;
|
|
9222
|
+
if (includeRawChunks) {
|
|
9223
|
+
controller.enqueue({ type: "raw", rawValue: raw });
|
|
9224
|
+
}
|
|
9225
|
+
switch (raw.type) {
|
|
9226
|
+
case "session.output_audio.delta": {
|
|
9227
|
+
if (raw.delta) {
|
|
9228
|
+
controller.enqueue({
|
|
9229
|
+
type: "audio",
|
|
9230
|
+
audio: raw.delta
|
|
9231
|
+
});
|
|
9232
|
+
}
|
|
9233
|
+
break;
|
|
9234
|
+
}
|
|
9235
|
+
case "session.output_transcript.delta": {
|
|
9236
|
+
translationText += (_a = raw.delta) != null ? _a : "";
|
|
9237
|
+
controller.enqueue({
|
|
9238
|
+
type: "output-text-delta",
|
|
9239
|
+
delta: (_b = raw.delta) != null ? _b : ""
|
|
9240
|
+
});
|
|
9241
|
+
break;
|
|
9242
|
+
}
|
|
9243
|
+
case "session.input_transcript.delta": {
|
|
9244
|
+
sourceText += (_c = raw.delta) != null ? _c : "";
|
|
9245
|
+
controller.enqueue({
|
|
9246
|
+
type: "source-transcript-delta",
|
|
9247
|
+
delta: (_d = raw.delta) != null ? _d : ""
|
|
9248
|
+
});
|
|
9249
|
+
break;
|
|
9250
|
+
}
|
|
9251
|
+
case "session.closed": {
|
|
9252
|
+
finish();
|
|
9253
|
+
break;
|
|
9254
|
+
}
|
|
9255
|
+
case "error": {
|
|
9256
|
+
controller.enqueue({
|
|
9257
|
+
type: "error",
|
|
9258
|
+
error: new Error((_f = (_e = raw.error) == null ? void 0 : _e.message) != null ? _f : "OpenAI realtime error")
|
|
9259
|
+
});
|
|
9260
|
+
break;
|
|
9261
|
+
}
|
|
9262
|
+
}
|
|
9263
|
+
},
|
|
9264
|
+
onSocketError: () => {
|
|
9265
|
+
finishWithError(new Error("OpenAI realtime translation error"));
|
|
9266
|
+
},
|
|
9267
|
+
onClose: ({ code, reason }) => {
|
|
9268
|
+
if (finished) return;
|
|
9269
|
+
finishWithError(
|
|
9270
|
+
new Error(
|
|
9271
|
+
`OpenAI realtime translation WebSocket closed unexpectedly before finishing (code ${code != null ? code : "unknown"}${reason ? `, reason: ${reason}` : ""}).`
|
|
9272
|
+
)
|
|
9273
|
+
);
|
|
9274
|
+
}
|
|
9275
|
+
});
|
|
9276
|
+
},
|
|
9277
|
+
cancel: () => {
|
|
9278
|
+
if (finished) return;
|
|
9279
|
+
finished = true;
|
|
9280
|
+
cleanup();
|
|
9281
|
+
}
|
|
9282
|
+
});
|
|
9283
|
+
}
|
|
9284
|
+
function buildOpenAIRealtimeTranslationSession({
|
|
9285
|
+
targetLanguage
|
|
9286
|
+
}) {
|
|
9287
|
+
return {
|
|
9288
|
+
type: "session.update",
|
|
9289
|
+
session: {
|
|
9290
|
+
audio: {
|
|
9291
|
+
input: {
|
|
9292
|
+
transcription: {
|
|
9293
|
+
model: "gpt-realtime-whisper"
|
|
9294
|
+
},
|
|
9295
|
+
noise_reduction: null
|
|
9296
|
+
},
|
|
9297
|
+
output: {
|
|
9298
|
+
language: targetLanguage
|
|
9299
|
+
}
|
|
9300
|
+
}
|
|
9301
|
+
}
|
|
9302
|
+
};
|
|
9303
|
+
}
|
|
9304
|
+
function validateOpenAITranslationInputAudioFormat(inputAudioFormat) {
|
|
9305
|
+
if (inputAudioFormat.type !== "audio/pcm" || inputAudioFormat.rate != null && inputAudioFormat.rate !== 24e3) {
|
|
9306
|
+
throw new InvalidArgumentError({
|
|
9307
|
+
argument: "inputAudioFormat",
|
|
9308
|
+
message: "The OpenAI Realtime translation API only supports 24kHz 16-bit PCM input audio."
|
|
9309
|
+
});
|
|
9310
|
+
}
|
|
9311
|
+
}
|
|
9312
|
+
function getOpenAIRealtimeConnection2(headers) {
|
|
9313
|
+
var _a;
|
|
9314
|
+
let authorization;
|
|
9315
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
9316
|
+
if (key.toLowerCase() === "authorization" && value != null) {
|
|
9317
|
+
authorization = value;
|
|
9318
|
+
}
|
|
9319
|
+
}
|
|
9320
|
+
const token = (_a = authorization == null ? void 0 : authorization.match(/^bearer\s+(.+)$/i)) == null ? void 0 : _a[1];
|
|
9321
|
+
if (token == null) {
|
|
9322
|
+
return { protocols: ["realtime"], headers };
|
|
9323
|
+
}
|
|
9324
|
+
return {
|
|
9325
|
+
protocols: ["realtime", `openai-insecure-api-key.${token}`],
|
|
9326
|
+
headers: Object.fromEntries(
|
|
9327
|
+
Object.entries(headers).filter(
|
|
9328
|
+
([key]) => key.toLowerCase() !== "authorization"
|
|
9329
|
+
)
|
|
9330
|
+
)
|
|
9331
|
+
};
|
|
9332
|
+
}
|
|
9333
|
+
|
|
9334
|
+
// src/skills/openai-skills.ts
|
|
9335
|
+
import {
|
|
9336
|
+
combineHeaders as combineHeaders10,
|
|
9020
9337
|
convertInlineFileDataToUint8Array as convertInlineFileDataToUint8Array2,
|
|
9021
9338
|
createJsonResponseHandler as createJsonResponseHandler8,
|
|
9022
9339
|
postFormDataToApi as postFormDataToApi4
|
|
9023
9340
|
} from "@ai-sdk/provider-utils";
|
|
9024
9341
|
|
|
9025
9342
|
// src/skills/openai-skills-api.ts
|
|
9026
|
-
import { lazySchema as
|
|
9027
|
-
import { z as
|
|
9028
|
-
var openaiSkillResponseSchema =
|
|
9029
|
-
() =>
|
|
9030
|
-
|
|
9031
|
-
id:
|
|
9032
|
-
name:
|
|
9033
|
-
description:
|
|
9034
|
-
default_version:
|
|
9035
|
-
latest_version:
|
|
9036
|
-
created_at:
|
|
9037
|
-
updated_at:
|
|
9343
|
+
import { lazySchema as lazySchema30, zodSchema as zodSchema30 } from "@ai-sdk/provider-utils";
|
|
9344
|
+
import { z as z32 } from "zod/v4";
|
|
9345
|
+
var openaiSkillResponseSchema = lazySchema30(
|
|
9346
|
+
() => zodSchema30(
|
|
9347
|
+
z32.object({
|
|
9348
|
+
id: z32.string(),
|
|
9349
|
+
name: z32.string().nullish(),
|
|
9350
|
+
description: z32.string().nullish(),
|
|
9351
|
+
default_version: z32.string().nullish(),
|
|
9352
|
+
latest_version: z32.string().nullish(),
|
|
9353
|
+
created_at: z32.number(),
|
|
9354
|
+
updated_at: z32.number().nullish()
|
|
9038
9355
|
})
|
|
9039
9356
|
)
|
|
9040
9357
|
);
|
|
9041
|
-
var openaiSkillVersionResponseSchema =
|
|
9042
|
-
() =>
|
|
9043
|
-
|
|
9044
|
-
id:
|
|
9045
|
-
version:
|
|
9046
|
-
name:
|
|
9047
|
-
description:
|
|
9358
|
+
var openaiSkillVersionResponseSchema = lazySchema30(
|
|
9359
|
+
() => zodSchema30(
|
|
9360
|
+
z32.object({
|
|
9361
|
+
id: z32.string(),
|
|
9362
|
+
version: z32.string().nullish(),
|
|
9363
|
+
name: z32.string().nullish(),
|
|
9364
|
+
description: z32.string().nullish()
|
|
9048
9365
|
})
|
|
9049
9366
|
)
|
|
9050
9367
|
);
|
|
@@ -9073,7 +9390,7 @@ var OpenAISkills = class {
|
|
|
9073
9390
|
}
|
|
9074
9391
|
const { value: response } = await postFormDataToApi4({
|
|
9075
9392
|
url: this.config.url({ path: "/skills" }),
|
|
9076
|
-
headers:
|
|
9393
|
+
headers: combineHeaders10(this.config.headers()),
|
|
9077
9394
|
formData,
|
|
9078
9395
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
9079
9396
|
successfulResponseHandler: createJsonResponseHandler8(
|
|
@@ -9099,7 +9416,7 @@ var OpenAISkills = class {
|
|
|
9099
9416
|
};
|
|
9100
9417
|
|
|
9101
9418
|
// src/version.ts
|
|
9102
|
-
var VERSION = true ? "4.0.
|
|
9419
|
+
var VERSION = true ? "4.0.22" : "0.0.0-test";
|
|
9103
9420
|
|
|
9104
9421
|
// src/openai-provider.ts
|
|
9105
9422
|
function createOpenAI(options = {}) {
|
|
@@ -9157,6 +9474,13 @@ function createOpenAI(options = {}) {
|
|
|
9157
9474
|
fetch: options.fetch,
|
|
9158
9475
|
webSocket: options.webSocket
|
|
9159
9476
|
});
|
|
9477
|
+
const createTranslationModel = (modelId) => new OpenAITranslationModel(modelId, {
|
|
9478
|
+
provider: `${providerName}.translation`,
|
|
9479
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
9480
|
+
headers: getHeaders,
|
|
9481
|
+
fetch: options.fetch,
|
|
9482
|
+
webSocket: options.webSocket
|
|
9483
|
+
});
|
|
9160
9484
|
const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
|
|
9161
9485
|
provider: `${providerName}.speech`,
|
|
9162
9486
|
url: ({ path }) => `${baseURL}${path}`,
|
|
@@ -9232,6 +9556,8 @@ function createOpenAI(options = {}) {
|
|
|
9232
9556
|
provider.imageModel = createImageModel;
|
|
9233
9557
|
provider.transcription = createTranscriptionModel;
|
|
9234
9558
|
provider.transcriptionModel = createTranscriptionModel;
|
|
9559
|
+
provider.translation = createTranslationModel;
|
|
9560
|
+
provider.speechTranslationModel = createTranslationModel;
|
|
9235
9561
|
provider.speech = createSpeechModel;
|
|
9236
9562
|
provider.speechModel = createSpeechModel;
|
|
9237
9563
|
provider.files = createFiles;
|
|
@@ -9243,6 +9569,7 @@ function createOpenAI(options = {}) {
|
|
|
9243
9569
|
var openai = createOpenAI();
|
|
9244
9570
|
export {
|
|
9245
9571
|
OpenAIRealtimeModel as Experimental_OpenAIRealtimeModel,
|
|
9572
|
+
OpenAITranslationModel as Experimental_OpenAITranslationModel,
|
|
9246
9573
|
VERSION,
|
|
9247
9574
|
createOpenAI,
|
|
9248
9575
|
openai
|