@ai-sdk/openai 4.0.21 → 4.0.23
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 +15 -0
- package/dist/index.d.ts +65 -3
- package/dist/index.js +357 -24
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +8 -0
- package/dist/internal/index.js +8 -2
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +49 -1
- package/package.json +2 -2
- package/src/index.ts +5 -0
- package/src/openai-provider.ts +27 -0
- package/src/responses/openai-responses-api.ts +6 -1
- package/src/responses/openai-responses-prepare-tools.ts +4 -1
- package/src/tool/web-search.ts +12 -1
- 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,20 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 4.0.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 96a237d: Add blocked domain filters to the OpenAI and Azure Responses API web search tools.
|
|
8
|
+
|
|
9
|
+
## 4.0.22
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 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).
|
|
14
|
+
- Updated dependencies [0c464d9]
|
|
15
|
+
- Updated dependencies [c49380c]
|
|
16
|
+
- @ai-sdk/provider-utils@5.0.14
|
|
17
|
+
|
|
3
18
|
## 4.0.21
|
|
4
19
|
|
|
5
20
|
### 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 & {});
|
|
@@ -144,8 +144,15 @@ declare const webSearchToolFactory: _ai_sdk_provider_utils.ProviderExecutedToolF
|
|
|
144
144
|
* Allowed domains for the search.
|
|
145
145
|
* If not provided, all domains are allowed.
|
|
146
146
|
* Subdomains of the provided domains are allowed as well.
|
|
147
|
+
* Omit the HTTP or HTTPS prefix. Maximum 100 domains.
|
|
147
148
|
*/
|
|
148
149
|
allowedDomains?: string[];
|
|
150
|
+
/**
|
|
151
|
+
* Blocked domains for the search.
|
|
152
|
+
* Subdomains of the provided domains are blocked as well.
|
|
153
|
+
* Omit the HTTP or HTTPS prefix. Maximum 100 domains.
|
|
154
|
+
*/
|
|
155
|
+
blockedDomains?: string[];
|
|
149
156
|
};
|
|
150
157
|
/**
|
|
151
158
|
* Search context size to use for the web search.
|
|
@@ -1388,6 +1395,10 @@ declare const openAITranscriptionModelOptions: _ai_sdk_provider_utils.LazySchema
|
|
|
1388
1395
|
}>;
|
|
1389
1396
|
type OpenAITranscriptionModelOptions = InferSchema<typeof openAITranscriptionModelOptions>;
|
|
1390
1397
|
|
|
1398
|
+
type OpenAITranslationModelId = 'gpt-realtime-translate' | (string & {});
|
|
1399
|
+
declare const openAITranslationModelOptions: _ai_sdk_provider_utils.LazySchema<Record<string, never>>;
|
|
1400
|
+
type OpenAITranslationModelOptions = InferSchema<typeof openAITranslationModelOptions>;
|
|
1401
|
+
|
|
1391
1402
|
interface OpenAIProvider extends ProviderV4 {
|
|
1392
1403
|
(modelId: OpenAIResponsesModelId): LanguageModelV4;
|
|
1393
1404
|
/**
|
|
@@ -1434,6 +1445,14 @@ interface OpenAIProvider extends ProviderV4 {
|
|
|
1434
1445
|
* Creates a model for transcription.
|
|
1435
1446
|
*/
|
|
1436
1447
|
transcription(modelId: OpenAITranscriptionModelId): TranscriptionModelV4;
|
|
1448
|
+
/**
|
|
1449
|
+
* Creates an experimental model for streaming speech translation.
|
|
1450
|
+
*/
|
|
1451
|
+
translation(modelId: OpenAITranslationModelId): Experimental_SpeechTranslationModelV4;
|
|
1452
|
+
/**
|
|
1453
|
+
* Creates an experimental model for streaming speech translation.
|
|
1454
|
+
*/
|
|
1455
|
+
speechTranslationModel(modelId: OpenAITranslationModelId): Experimental_SpeechTranslationModelV4;
|
|
1437
1456
|
/**
|
|
1438
1457
|
* Creates a model for speech generation.
|
|
1439
1458
|
*/
|
|
@@ -1536,6 +1555,49 @@ type OpenAIToolOptions = {
|
|
|
1536
1555
|
};
|
|
1537
1556
|
};
|
|
1538
1557
|
|
|
1558
|
+
type OpenAIConfig = {
|
|
1559
|
+
provider: string;
|
|
1560
|
+
url: (options: {
|
|
1561
|
+
modelId: string;
|
|
1562
|
+
path: string;
|
|
1563
|
+
}) => string;
|
|
1564
|
+
headers?: () => Record<string, string | undefined>;
|
|
1565
|
+
fetch?: FetchFunction;
|
|
1566
|
+
webSocket?: WebSocketConstructor;
|
|
1567
|
+
generateId?: () => string;
|
|
1568
|
+
/**
|
|
1569
|
+
* This is soft-deprecated. Use provider references (e.g. `{ openai: 'file-abc123' }`)
|
|
1570
|
+
* in file part data instead. File ID prefixes used to identify file IDs
|
|
1571
|
+
* in Responses API. When undefined, all string file data is treated as
|
|
1572
|
+
* base64 content.
|
|
1573
|
+
*
|
|
1574
|
+
* TODO: remove in v8
|
|
1575
|
+
*/
|
|
1576
|
+
fileIdPrefixes?: readonly string[];
|
|
1577
|
+
};
|
|
1578
|
+
|
|
1579
|
+
interface OpenAITranslationModelConfig extends OpenAIConfig {
|
|
1580
|
+
_internal?: {
|
|
1581
|
+
currentDate?: () => Date;
|
|
1582
|
+
};
|
|
1583
|
+
}
|
|
1584
|
+
declare class OpenAITranslationModel implements Experimental_SpeechTranslationModelV4 {
|
|
1585
|
+
readonly modelId: OpenAITranslationModelId;
|
|
1586
|
+
private readonly config;
|
|
1587
|
+
readonly specificationVersion = "v4";
|
|
1588
|
+
static [WORKFLOW_SERIALIZE](model: OpenAITranslationModel): {
|
|
1589
|
+
modelId: string;
|
|
1590
|
+
config: _ai_sdk_provider.JSONObject;
|
|
1591
|
+
};
|
|
1592
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
1593
|
+
modelId: OpenAITranslationModelId;
|
|
1594
|
+
config: OpenAITranslationModelConfig;
|
|
1595
|
+
}): OpenAITranslationModel;
|
|
1596
|
+
get provider(): string;
|
|
1597
|
+
constructor(modelId: OpenAITranslationModelId, config: OpenAITranslationModelConfig);
|
|
1598
|
+
doStream(options: Experimental_SpeechTranslationModelV4StreamOptions): Promise<Awaited<ReturnType<Experimental_SpeechTranslationModelV4['doStream']>>>;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1539
1601
|
declare const openaiFilesOptionsSchema: _ai_sdk_provider_utils.LazySchema<{
|
|
1540
1602
|
purpose?: string | undefined;
|
|
1541
1603
|
expiresAfter?: number | undefined;
|
|
@@ -1652,4 +1714,4 @@ type OpenaiResponsesSourceDocumentProviderMetadata = {
|
|
|
1652
1714
|
|
|
1653
1715
|
declare const VERSION: string;
|
|
1654
1716
|
|
|
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 };
|
|
1717
|
+
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
|
@@ -2942,7 +2942,10 @@ var webSearchArgsSchema = lazySchema20(
|
|
|
2942
2942
|
() => zodSchema20(
|
|
2943
2943
|
z21.object({
|
|
2944
2944
|
externalWebAccess: z21.boolean().optional(),
|
|
2945
|
-
filters: z21.object({
|
|
2945
|
+
filters: z21.object({
|
|
2946
|
+
allowedDomains: z21.array(z21.string()).optional(),
|
|
2947
|
+
blockedDomains: z21.array(z21.string()).optional()
|
|
2948
|
+
}).optional(),
|
|
2946
2949
|
searchContextSize: z21.enum(["low", "medium", "high"]).optional(),
|
|
2947
2950
|
userLocation: z21.object({
|
|
2948
2951
|
type: z21.literal("approximate"),
|
|
@@ -6065,7 +6068,10 @@ async function prepareResponsesTools({
|
|
|
6065
6068
|
});
|
|
6066
6069
|
openaiTools2.push({
|
|
6067
6070
|
type: "web_search",
|
|
6068
|
-
filters: args.filters != null ? {
|
|
6071
|
+
filters: args.filters != null ? {
|
|
6072
|
+
allowed_domains: args.filters.allowedDomains,
|
|
6073
|
+
blocked_domains: args.filters.blockedDomains
|
|
6074
|
+
} : void 0,
|
|
6069
6075
|
external_web_access: args.externalWebAccess,
|
|
6070
6076
|
search_context_size: args.searchContextSize,
|
|
6071
6077
|
user_location: args.userLocation
|
|
@@ -9014,37 +9020,354 @@ function getOpenAIRealtimeConnection(headers) {
|
|
|
9014
9020
|
};
|
|
9015
9021
|
}
|
|
9016
9022
|
|
|
9017
|
-
// src/
|
|
9023
|
+
// src/translation/openai-translation-model.ts
|
|
9024
|
+
import {
|
|
9025
|
+
InvalidArgumentError
|
|
9026
|
+
} from "@ai-sdk/provider";
|
|
9018
9027
|
import {
|
|
9019
9028
|
combineHeaders as combineHeaders9,
|
|
9029
|
+
connectToWebSocket as connectToWebSocket2,
|
|
9030
|
+
convertToBase64 as convertToBase644,
|
|
9031
|
+
parseProviderOptions as parseProviderOptions10,
|
|
9032
|
+
safeParseJSON as safeParseJSON2,
|
|
9033
|
+
serializeModelOptions as serializeModelOptions8,
|
|
9034
|
+
toWebSocketUrl as toWebSocketUrl2,
|
|
9035
|
+
WORKFLOW_DESERIALIZE as WORKFLOW_DESERIALIZE8,
|
|
9036
|
+
WORKFLOW_SERIALIZE as WORKFLOW_SERIALIZE8,
|
|
9037
|
+
waitForWebSocketBufferDrain as waitForWebSocketBufferDrain2
|
|
9038
|
+
} from "@ai-sdk/provider-utils";
|
|
9039
|
+
|
|
9040
|
+
// src/translation/openai-translation-model-options.ts
|
|
9041
|
+
import {
|
|
9042
|
+
lazySchema as lazySchema29,
|
|
9043
|
+
zodSchema as zodSchema29
|
|
9044
|
+
} from "@ai-sdk/provider-utils";
|
|
9045
|
+
import { z as z31 } from "zod/v4";
|
|
9046
|
+
var openAITranslationModelOptions = lazySchema29(
|
|
9047
|
+
() => zodSchema29(z31.object({}))
|
|
9048
|
+
);
|
|
9049
|
+
|
|
9050
|
+
// src/translation/openai-translation-model.ts
|
|
9051
|
+
var OpenAITranslationModel = class _OpenAITranslationModel {
|
|
9052
|
+
constructor(modelId, config) {
|
|
9053
|
+
this.modelId = modelId;
|
|
9054
|
+
this.config = config;
|
|
9055
|
+
this.specificationVersion = "v4";
|
|
9056
|
+
}
|
|
9057
|
+
static [WORKFLOW_SERIALIZE8](model) {
|
|
9058
|
+
return serializeModelOptions8({
|
|
9059
|
+
modelId: model.modelId,
|
|
9060
|
+
config: model.config
|
|
9061
|
+
});
|
|
9062
|
+
}
|
|
9063
|
+
static [WORKFLOW_DESERIALIZE8](options) {
|
|
9064
|
+
return new _OpenAITranslationModel(options.modelId, options.config);
|
|
9065
|
+
}
|
|
9066
|
+
get provider() {
|
|
9067
|
+
return this.config.provider;
|
|
9068
|
+
}
|
|
9069
|
+
async doStream(options) {
|
|
9070
|
+
var _a, _b, _c, _d, _e;
|
|
9071
|
+
if (options.targetLanguage == null) {
|
|
9072
|
+
throw new InvalidArgumentError({
|
|
9073
|
+
argument: "targetLanguage",
|
|
9074
|
+
message: `targetLanguage is required for translation model '${this.modelId}'.`
|
|
9075
|
+
});
|
|
9076
|
+
}
|
|
9077
|
+
const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
|
|
9078
|
+
await parseProviderOptions10({
|
|
9079
|
+
provider: "openai",
|
|
9080
|
+
providerOptions: options.providerOptions,
|
|
9081
|
+
schema: openAITranslationModelOptions
|
|
9082
|
+
});
|
|
9083
|
+
const warnings = [];
|
|
9084
|
+
validateOpenAITranslationInputAudioFormat(options.inputAudioFormat);
|
|
9085
|
+
if (options.sourceLanguage != null) {
|
|
9086
|
+
warnings.push({
|
|
9087
|
+
type: "unsupported",
|
|
9088
|
+
feature: "sourceLanguage",
|
|
9089
|
+
details: "The OpenAI Realtime translation API auto-detects the source language and does not accept a source language."
|
|
9090
|
+
});
|
|
9091
|
+
}
|
|
9092
|
+
if (options.outputAudioFormat != null) {
|
|
9093
|
+
warnings.push({
|
|
9094
|
+
type: "unsupported",
|
|
9095
|
+
feature: "outputAudioFormat",
|
|
9096
|
+
details: "The OpenAI Realtime translation API always outputs 24kHz 16-bit PCM audio and does not accept an output audio format."
|
|
9097
|
+
});
|
|
9098
|
+
}
|
|
9099
|
+
const headers = combineHeaders9((_e = (_d = this.config).headers) == null ? void 0 : _e.call(_d), options.headers);
|
|
9100
|
+
const sessionUpdate = buildOpenAIRealtimeTranslationSession({
|
|
9101
|
+
targetLanguage: options.targetLanguage
|
|
9102
|
+
});
|
|
9103
|
+
return {
|
|
9104
|
+
request: { body: sessionUpdate },
|
|
9105
|
+
response: {
|
|
9106
|
+
timestamp: currentDate,
|
|
9107
|
+
modelId: this.modelId
|
|
9108
|
+
},
|
|
9109
|
+
stream: createOpenAIRealtimeTranslationStream({
|
|
9110
|
+
webSocket: this.config.webSocket,
|
|
9111
|
+
url: toWebSocketUrl2(
|
|
9112
|
+
this.config.url({
|
|
9113
|
+
path: `/realtime/translations?model=${encodeURIComponent(this.modelId)}`,
|
|
9114
|
+
modelId: this.modelId
|
|
9115
|
+
})
|
|
9116
|
+
),
|
|
9117
|
+
headers,
|
|
9118
|
+
sessionUpdate,
|
|
9119
|
+
warnings,
|
|
9120
|
+
audio: options.audio,
|
|
9121
|
+
abortSignal: options.abortSignal,
|
|
9122
|
+
includeRawChunks: options.includeRawChunks
|
|
9123
|
+
})
|
|
9124
|
+
};
|
|
9125
|
+
}
|
|
9126
|
+
};
|
|
9127
|
+
function createOpenAIRealtimeTranslationStream({
|
|
9128
|
+
webSocket,
|
|
9129
|
+
url,
|
|
9130
|
+
headers,
|
|
9131
|
+
sessionUpdate,
|
|
9132
|
+
warnings,
|
|
9133
|
+
audio,
|
|
9134
|
+
abortSignal,
|
|
9135
|
+
includeRawChunks
|
|
9136
|
+
}) {
|
|
9137
|
+
let finished = false;
|
|
9138
|
+
let cleanup = () => {
|
|
9139
|
+
};
|
|
9140
|
+
return new ReadableStream({
|
|
9141
|
+
start: (controller) => {
|
|
9142
|
+
const realtimeConnection = getOpenAIRealtimeConnection2(headers);
|
|
9143
|
+
let audioReader;
|
|
9144
|
+
let connection;
|
|
9145
|
+
let sourceText = "";
|
|
9146
|
+
let translationText = "";
|
|
9147
|
+
cleanup = (closeCode) => {
|
|
9148
|
+
if (audioReader != null) {
|
|
9149
|
+
void audioReader.cancel().catch(() => {
|
|
9150
|
+
});
|
|
9151
|
+
} else {
|
|
9152
|
+
void audio.cancel().catch(() => {
|
|
9153
|
+
});
|
|
9154
|
+
}
|
|
9155
|
+
connection == null ? void 0 : connection.close(closeCode);
|
|
9156
|
+
};
|
|
9157
|
+
const finishWithError = (error) => {
|
|
9158
|
+
if (finished) return;
|
|
9159
|
+
finished = true;
|
|
9160
|
+
cleanup();
|
|
9161
|
+
controller.error(error);
|
|
9162
|
+
};
|
|
9163
|
+
const finish = () => {
|
|
9164
|
+
if (finished) return;
|
|
9165
|
+
finished = true;
|
|
9166
|
+
if (sourceText !== "") {
|
|
9167
|
+
controller.enqueue({
|
|
9168
|
+
type: "source-transcript-final",
|
|
9169
|
+
text: sourceText
|
|
9170
|
+
});
|
|
9171
|
+
}
|
|
9172
|
+
if (translationText !== "") {
|
|
9173
|
+
controller.enqueue({
|
|
9174
|
+
type: "output-text-final",
|
|
9175
|
+
text: translationText
|
|
9176
|
+
});
|
|
9177
|
+
}
|
|
9178
|
+
controller.enqueue({
|
|
9179
|
+
type: "finish",
|
|
9180
|
+
sourceText,
|
|
9181
|
+
outputText: translationText,
|
|
9182
|
+
usage: void 0
|
|
9183
|
+
});
|
|
9184
|
+
controller.close();
|
|
9185
|
+
cleanup(1e3);
|
|
9186
|
+
};
|
|
9187
|
+
const sendAudio = async (socket) => {
|
|
9188
|
+
audioReader = audio.getReader();
|
|
9189
|
+
try {
|
|
9190
|
+
while (true) {
|
|
9191
|
+
const { done, value } = await audioReader.read();
|
|
9192
|
+
if (done || finished) break;
|
|
9193
|
+
socket.send(
|
|
9194
|
+
JSON.stringify({
|
|
9195
|
+
type: "session.input_audio_buffer.append",
|
|
9196
|
+
audio: convertToBase644(value)
|
|
9197
|
+
})
|
|
9198
|
+
);
|
|
9199
|
+
await waitForWebSocketBufferDrain2(socket);
|
|
9200
|
+
}
|
|
9201
|
+
} finally {
|
|
9202
|
+
audioReader.releaseLock();
|
|
9203
|
+
audioReader = void 0;
|
|
9204
|
+
}
|
|
9205
|
+
if (!finished) {
|
|
9206
|
+
socket.send(JSON.stringify({ type: "session.close" }));
|
|
9207
|
+
}
|
|
9208
|
+
};
|
|
9209
|
+
connection = connectToWebSocket2({
|
|
9210
|
+
url,
|
|
9211
|
+
protocols: realtimeConnection.protocols,
|
|
9212
|
+
headers: realtimeConnection.headers,
|
|
9213
|
+
webSocket,
|
|
9214
|
+
abortSignal,
|
|
9215
|
+
onAbort: finishWithError,
|
|
9216
|
+
onProcessingError: finishWithError,
|
|
9217
|
+
onOpen: (socket) => {
|
|
9218
|
+
controller.enqueue({ type: "stream-start", warnings });
|
|
9219
|
+
socket.send(JSON.stringify(sessionUpdate));
|
|
9220
|
+
void sendAudio(socket).catch(finishWithError);
|
|
9221
|
+
},
|
|
9222
|
+
onMessageText: async (text) => {
|
|
9223
|
+
var _a, _b, _c, _d, _e, _f;
|
|
9224
|
+
if (finished) return;
|
|
9225
|
+
const parsed = await safeParseJSON2({ text });
|
|
9226
|
+
if (!parsed.success) return;
|
|
9227
|
+
const raw = parsed.value;
|
|
9228
|
+
if (includeRawChunks) {
|
|
9229
|
+
controller.enqueue({ type: "raw", rawValue: raw });
|
|
9230
|
+
}
|
|
9231
|
+
switch (raw.type) {
|
|
9232
|
+
case "session.output_audio.delta": {
|
|
9233
|
+
if (raw.delta) {
|
|
9234
|
+
controller.enqueue({
|
|
9235
|
+
type: "audio",
|
|
9236
|
+
audio: raw.delta
|
|
9237
|
+
});
|
|
9238
|
+
}
|
|
9239
|
+
break;
|
|
9240
|
+
}
|
|
9241
|
+
case "session.output_transcript.delta": {
|
|
9242
|
+
translationText += (_a = raw.delta) != null ? _a : "";
|
|
9243
|
+
controller.enqueue({
|
|
9244
|
+
type: "output-text-delta",
|
|
9245
|
+
delta: (_b = raw.delta) != null ? _b : ""
|
|
9246
|
+
});
|
|
9247
|
+
break;
|
|
9248
|
+
}
|
|
9249
|
+
case "session.input_transcript.delta": {
|
|
9250
|
+
sourceText += (_c = raw.delta) != null ? _c : "";
|
|
9251
|
+
controller.enqueue({
|
|
9252
|
+
type: "source-transcript-delta",
|
|
9253
|
+
delta: (_d = raw.delta) != null ? _d : ""
|
|
9254
|
+
});
|
|
9255
|
+
break;
|
|
9256
|
+
}
|
|
9257
|
+
case "session.closed": {
|
|
9258
|
+
finish();
|
|
9259
|
+
break;
|
|
9260
|
+
}
|
|
9261
|
+
case "error": {
|
|
9262
|
+
controller.enqueue({
|
|
9263
|
+
type: "error",
|
|
9264
|
+
error: new Error((_f = (_e = raw.error) == null ? void 0 : _e.message) != null ? _f : "OpenAI realtime error")
|
|
9265
|
+
});
|
|
9266
|
+
break;
|
|
9267
|
+
}
|
|
9268
|
+
}
|
|
9269
|
+
},
|
|
9270
|
+
onSocketError: () => {
|
|
9271
|
+
finishWithError(new Error("OpenAI realtime translation error"));
|
|
9272
|
+
},
|
|
9273
|
+
onClose: ({ code, reason }) => {
|
|
9274
|
+
if (finished) return;
|
|
9275
|
+
finishWithError(
|
|
9276
|
+
new Error(
|
|
9277
|
+
`OpenAI realtime translation WebSocket closed unexpectedly before finishing (code ${code != null ? code : "unknown"}${reason ? `, reason: ${reason}` : ""}).`
|
|
9278
|
+
)
|
|
9279
|
+
);
|
|
9280
|
+
}
|
|
9281
|
+
});
|
|
9282
|
+
},
|
|
9283
|
+
cancel: () => {
|
|
9284
|
+
if (finished) return;
|
|
9285
|
+
finished = true;
|
|
9286
|
+
cleanup();
|
|
9287
|
+
}
|
|
9288
|
+
});
|
|
9289
|
+
}
|
|
9290
|
+
function buildOpenAIRealtimeTranslationSession({
|
|
9291
|
+
targetLanguage
|
|
9292
|
+
}) {
|
|
9293
|
+
return {
|
|
9294
|
+
type: "session.update",
|
|
9295
|
+
session: {
|
|
9296
|
+
audio: {
|
|
9297
|
+
input: {
|
|
9298
|
+
transcription: {
|
|
9299
|
+
model: "gpt-realtime-whisper"
|
|
9300
|
+
},
|
|
9301
|
+
noise_reduction: null
|
|
9302
|
+
},
|
|
9303
|
+
output: {
|
|
9304
|
+
language: targetLanguage
|
|
9305
|
+
}
|
|
9306
|
+
}
|
|
9307
|
+
}
|
|
9308
|
+
};
|
|
9309
|
+
}
|
|
9310
|
+
function validateOpenAITranslationInputAudioFormat(inputAudioFormat) {
|
|
9311
|
+
if (inputAudioFormat.type !== "audio/pcm" || inputAudioFormat.rate != null && inputAudioFormat.rate !== 24e3) {
|
|
9312
|
+
throw new InvalidArgumentError({
|
|
9313
|
+
argument: "inputAudioFormat",
|
|
9314
|
+
message: "The OpenAI Realtime translation API only supports 24kHz 16-bit PCM input audio."
|
|
9315
|
+
});
|
|
9316
|
+
}
|
|
9317
|
+
}
|
|
9318
|
+
function getOpenAIRealtimeConnection2(headers) {
|
|
9319
|
+
var _a;
|
|
9320
|
+
let authorization;
|
|
9321
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
9322
|
+
if (key.toLowerCase() === "authorization" && value != null) {
|
|
9323
|
+
authorization = value;
|
|
9324
|
+
}
|
|
9325
|
+
}
|
|
9326
|
+
const token = (_a = authorization == null ? void 0 : authorization.match(/^bearer\s+(.+)$/i)) == null ? void 0 : _a[1];
|
|
9327
|
+
if (token == null) {
|
|
9328
|
+
return { protocols: ["realtime"], headers };
|
|
9329
|
+
}
|
|
9330
|
+
return {
|
|
9331
|
+
protocols: ["realtime", `openai-insecure-api-key.${token}`],
|
|
9332
|
+
headers: Object.fromEntries(
|
|
9333
|
+
Object.entries(headers).filter(
|
|
9334
|
+
([key]) => key.toLowerCase() !== "authorization"
|
|
9335
|
+
)
|
|
9336
|
+
)
|
|
9337
|
+
};
|
|
9338
|
+
}
|
|
9339
|
+
|
|
9340
|
+
// src/skills/openai-skills.ts
|
|
9341
|
+
import {
|
|
9342
|
+
combineHeaders as combineHeaders10,
|
|
9020
9343
|
convertInlineFileDataToUint8Array as convertInlineFileDataToUint8Array2,
|
|
9021
9344
|
createJsonResponseHandler as createJsonResponseHandler8,
|
|
9022
9345
|
postFormDataToApi as postFormDataToApi4
|
|
9023
9346
|
} from "@ai-sdk/provider-utils";
|
|
9024
9347
|
|
|
9025
9348
|
// 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:
|
|
9349
|
+
import { lazySchema as lazySchema30, zodSchema as zodSchema30 } from "@ai-sdk/provider-utils";
|
|
9350
|
+
import { z as z32 } from "zod/v4";
|
|
9351
|
+
var openaiSkillResponseSchema = lazySchema30(
|
|
9352
|
+
() => zodSchema30(
|
|
9353
|
+
z32.object({
|
|
9354
|
+
id: z32.string(),
|
|
9355
|
+
name: z32.string().nullish(),
|
|
9356
|
+
description: z32.string().nullish(),
|
|
9357
|
+
default_version: z32.string().nullish(),
|
|
9358
|
+
latest_version: z32.string().nullish(),
|
|
9359
|
+
created_at: z32.number(),
|
|
9360
|
+
updated_at: z32.number().nullish()
|
|
9038
9361
|
})
|
|
9039
9362
|
)
|
|
9040
9363
|
);
|
|
9041
|
-
var openaiSkillVersionResponseSchema =
|
|
9042
|
-
() =>
|
|
9043
|
-
|
|
9044
|
-
id:
|
|
9045
|
-
version:
|
|
9046
|
-
name:
|
|
9047
|
-
description:
|
|
9364
|
+
var openaiSkillVersionResponseSchema = lazySchema30(
|
|
9365
|
+
() => zodSchema30(
|
|
9366
|
+
z32.object({
|
|
9367
|
+
id: z32.string(),
|
|
9368
|
+
version: z32.string().nullish(),
|
|
9369
|
+
name: z32.string().nullish(),
|
|
9370
|
+
description: z32.string().nullish()
|
|
9048
9371
|
})
|
|
9049
9372
|
)
|
|
9050
9373
|
);
|
|
@@ -9073,7 +9396,7 @@ var OpenAISkills = class {
|
|
|
9073
9396
|
}
|
|
9074
9397
|
const { value: response } = await postFormDataToApi4({
|
|
9075
9398
|
url: this.config.url({ path: "/skills" }),
|
|
9076
|
-
headers:
|
|
9399
|
+
headers: combineHeaders10(this.config.headers()),
|
|
9077
9400
|
formData,
|
|
9078
9401
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
9079
9402
|
successfulResponseHandler: createJsonResponseHandler8(
|
|
@@ -9099,7 +9422,7 @@ var OpenAISkills = class {
|
|
|
9099
9422
|
};
|
|
9100
9423
|
|
|
9101
9424
|
// src/version.ts
|
|
9102
|
-
var VERSION = true ? "4.0.
|
|
9425
|
+
var VERSION = true ? "4.0.23" : "0.0.0-test";
|
|
9103
9426
|
|
|
9104
9427
|
// src/openai-provider.ts
|
|
9105
9428
|
function createOpenAI(options = {}) {
|
|
@@ -9157,6 +9480,13 @@ function createOpenAI(options = {}) {
|
|
|
9157
9480
|
fetch: options.fetch,
|
|
9158
9481
|
webSocket: options.webSocket
|
|
9159
9482
|
});
|
|
9483
|
+
const createTranslationModel = (modelId) => new OpenAITranslationModel(modelId, {
|
|
9484
|
+
provider: `${providerName}.translation`,
|
|
9485
|
+
url: ({ path }) => `${baseURL}${path}`,
|
|
9486
|
+
headers: getHeaders,
|
|
9487
|
+
fetch: options.fetch,
|
|
9488
|
+
webSocket: options.webSocket
|
|
9489
|
+
});
|
|
9160
9490
|
const createSpeechModel = (modelId) => new OpenAISpeechModel(modelId, {
|
|
9161
9491
|
provider: `${providerName}.speech`,
|
|
9162
9492
|
url: ({ path }) => `${baseURL}${path}`,
|
|
@@ -9232,6 +9562,8 @@ function createOpenAI(options = {}) {
|
|
|
9232
9562
|
provider.imageModel = createImageModel;
|
|
9233
9563
|
provider.transcription = createTranscriptionModel;
|
|
9234
9564
|
provider.transcriptionModel = createTranscriptionModel;
|
|
9565
|
+
provider.translation = createTranslationModel;
|
|
9566
|
+
provider.speechTranslationModel = createTranslationModel;
|
|
9235
9567
|
provider.speech = createSpeechModel;
|
|
9236
9568
|
provider.speechModel = createSpeechModel;
|
|
9237
9569
|
provider.files = createFiles;
|
|
@@ -9243,6 +9575,7 @@ function createOpenAI(options = {}) {
|
|
|
9243
9575
|
var openai = createOpenAI();
|
|
9244
9576
|
export {
|
|
9245
9577
|
OpenAIRealtimeModel as Experimental_OpenAIRealtimeModel,
|
|
9578
|
+
OpenAITranslationModel as Experimental_OpenAITranslationModel,
|
|
9246
9579
|
VERSION,
|
|
9247
9580
|
createOpenAI,
|
|
9248
9581
|
openai
|