@ai-sdk/openai 4.0.54 → 4.0.55
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.js +209 -46
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/files/openai-files-api.ts +10 -0
- package/src/files/openai-files.ts +250 -46
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 4.0.55
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 3fc40db: feat(openai): implement `getFileMetadata`, `downloadFile` (streaming), and `deleteFile` on the OpenAI files interface, support streaming uploads via `{ type: 'stream' }` data, expose `byteSize`/`createdAt`/`expiresAt` on upload results, and thread `abortSignal`/`headers` through all file operations; blank and dot-segment file ids are rejected/encoded so they cannot retarget request paths
|
|
8
|
+
- Updated dependencies [5190b67]
|
|
9
|
+
- @ai-sdk/provider@4.0.10
|
|
10
|
+
- @ai-sdk/provider-utils@5.0.35
|
|
11
|
+
|
|
3
12
|
## 4.0.54
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -2043,12 +2043,19 @@ var OpenAIEmbeddingModel = class _OpenAIEmbeddingModel {
|
|
|
2043
2043
|
};
|
|
2044
2044
|
|
|
2045
2045
|
// src/files/openai-files.ts
|
|
2046
|
+
import {
|
|
2047
|
+
InvalidArgumentError
|
|
2048
|
+
} from "@ai-sdk/provider";
|
|
2046
2049
|
import {
|
|
2047
2050
|
combineHeaders as combineHeaders4,
|
|
2048
2051
|
convertInlineFileDataToUint8Array,
|
|
2052
|
+
createBinaryStreamResponseHandler,
|
|
2049
2053
|
createJsonResponseHandler as createJsonResponseHandler4,
|
|
2054
|
+
deleteFromApi,
|
|
2055
|
+
getFromApi,
|
|
2050
2056
|
parseProviderOptions as parseProviderOptions4,
|
|
2051
|
-
postFormDataToApi
|
|
2057
|
+
postFormDataToApi,
|
|
2058
|
+
postMultipartStreamToApi
|
|
2052
2059
|
} from "@ai-sdk/provider-utils";
|
|
2053
2060
|
|
|
2054
2061
|
// src/files/openai-files-api.ts
|
|
@@ -2068,6 +2075,15 @@ var openaiFilesResponseSchema = lazySchema7(
|
|
|
2068
2075
|
})
|
|
2069
2076
|
)
|
|
2070
2077
|
);
|
|
2078
|
+
var openaiFileDeleteResponseSchema = lazySchema7(
|
|
2079
|
+
() => zodSchema7(
|
|
2080
|
+
z8.object({
|
|
2081
|
+
id: z8.string(),
|
|
2082
|
+
object: z8.string().nullish(),
|
|
2083
|
+
deleted: z8.boolean()
|
|
2084
|
+
})
|
|
2085
|
+
)
|
|
2086
|
+
);
|
|
2071
2087
|
|
|
2072
2088
|
// src/files/openai-files-options.ts
|
|
2073
2089
|
import {
|
|
@@ -2090,6 +2106,10 @@ var openaiFilesOptionsSchema = lazySchema8(
|
|
|
2090
2106
|
);
|
|
2091
2107
|
|
|
2092
2108
|
// src/files/openai-files.ts
|
|
2109
|
+
function encodePathSegment(value) {
|
|
2110
|
+
const encodedValue = encodeURIComponent(value);
|
|
2111
|
+
return encodedValue === "." ? "%252E" : encodedValue === ".." ? "%252E%252E" : encodedValue;
|
|
2112
|
+
}
|
|
2093
2113
|
var OpenAIFiles = class {
|
|
2094
2114
|
constructor(config) {
|
|
2095
2115
|
this.config = config;
|
|
@@ -2098,63 +2118,206 @@ var OpenAIFiles = class {
|
|
|
2098
2118
|
get provider() {
|
|
2099
2119
|
return this.config.provider;
|
|
2100
2120
|
}
|
|
2121
|
+
getFileId(file) {
|
|
2122
|
+
const fileId = file.openai;
|
|
2123
|
+
if (fileId == null || fileId.trim() === "") {
|
|
2124
|
+
throw new InvalidArgumentError({
|
|
2125
|
+
argument: "file",
|
|
2126
|
+
message: "file reference is missing an 'openai' file id."
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
return fileId;
|
|
2130
|
+
}
|
|
2131
|
+
getHeaders(headers) {
|
|
2132
|
+
return combineHeaders4(this.config.headers(), headers);
|
|
2133
|
+
}
|
|
2101
2134
|
async uploadFile({
|
|
2102
2135
|
data,
|
|
2103
2136
|
mediaType,
|
|
2104
2137
|
filename,
|
|
2138
|
+
abortSignal,
|
|
2139
|
+
headers,
|
|
2105
2140
|
providerOptions
|
|
2106
2141
|
}) {
|
|
2107
2142
|
var _a2, _b, _c;
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
formData.append("file", blob);
|
|
2143
|
+
let openaiOptions;
|
|
2144
|
+
try {
|
|
2145
|
+
openaiOptions = await parseProviderOptions4({
|
|
2146
|
+
provider: "openai",
|
|
2147
|
+
providerOptions,
|
|
2148
|
+
schema: openaiFilesOptionsSchema
|
|
2149
|
+
});
|
|
2150
|
+
} catch (error) {
|
|
2151
|
+
if (data.type === "stream") {
|
|
2152
|
+
await data.stream.cancel(error).catch(() => {
|
|
2153
|
+
});
|
|
2154
|
+
}
|
|
2155
|
+
throw error;
|
|
2122
2156
|
}
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2157
|
+
const purpose = (_a2 = openaiOptions == null ? void 0 : openaiOptions.purpose) != null ? _a2 : "assistants";
|
|
2158
|
+
const requestHeaders = this.getHeaders(headers);
|
|
2159
|
+
const url = `${this.config.baseURL}/files`;
|
|
2160
|
+
let response;
|
|
2161
|
+
if (data.type === "stream") {
|
|
2162
|
+
const parts = [
|
|
2163
|
+
{ type: "field", name: "purpose", value: purpose }
|
|
2164
|
+
];
|
|
2165
|
+
if ((openaiOptions == null ? void 0 : openaiOptions.expiresAfter) != null) {
|
|
2166
|
+
parts.push(
|
|
2167
|
+
{ type: "field", name: "expires_after[anchor]", value: "created_at" },
|
|
2168
|
+
{
|
|
2169
|
+
type: "field",
|
|
2170
|
+
name: "expires_after[seconds]",
|
|
2171
|
+
value: String(openaiOptions.expiresAfter)
|
|
2172
|
+
}
|
|
2173
|
+
);
|
|
2174
|
+
}
|
|
2175
|
+
parts.push({
|
|
2176
|
+
type: "file",
|
|
2177
|
+
name: "file",
|
|
2178
|
+
filename,
|
|
2179
|
+
mediaType,
|
|
2180
|
+
content: data.stream
|
|
2181
|
+
});
|
|
2182
|
+
({ value: response } = await postMultipartStreamToApi({
|
|
2183
|
+
url,
|
|
2184
|
+
headers: requestHeaders,
|
|
2185
|
+
parts,
|
|
2186
|
+
failedResponseHandler: openaiFailedResponseHandler,
|
|
2187
|
+
successfulResponseHandler: createJsonResponseHandler4(
|
|
2188
|
+
openaiFilesResponseSchema
|
|
2189
|
+
),
|
|
2190
|
+
abortSignal,
|
|
2191
|
+
fetch: this.config.fetch
|
|
2192
|
+
}));
|
|
2193
|
+
} else {
|
|
2194
|
+
const fileBytes = convertInlineFileDataToUint8Array(data);
|
|
2195
|
+
const blob = new Blob([fileBytes], {
|
|
2196
|
+
type: mediaType
|
|
2197
|
+
});
|
|
2198
|
+
const formData = new FormData();
|
|
2199
|
+
if (filename != null) {
|
|
2200
|
+
formData.append("file", blob, filename);
|
|
2201
|
+
} else {
|
|
2202
|
+
formData.append("file", blob);
|
|
2203
|
+
}
|
|
2204
|
+
formData.append("purpose", purpose);
|
|
2205
|
+
if ((openaiOptions == null ? void 0 : openaiOptions.expiresAfter) != null) {
|
|
2206
|
+
formData.append("expires_after[anchor]", "created_at");
|
|
2207
|
+
formData.append(
|
|
2208
|
+
"expires_after[seconds]",
|
|
2209
|
+
String(openaiOptions.expiresAfter)
|
|
2210
|
+
);
|
|
2211
|
+
}
|
|
2212
|
+
({ value: response } = await postFormDataToApi({
|
|
2213
|
+
url,
|
|
2214
|
+
headers: requestHeaders,
|
|
2215
|
+
formData,
|
|
2216
|
+
failedResponseHandler: openaiFailedResponseHandler,
|
|
2217
|
+
successfulResponseHandler: createJsonResponseHandler4(
|
|
2218
|
+
openaiFilesResponseSchema
|
|
2219
|
+
),
|
|
2220
|
+
abortSignal,
|
|
2221
|
+
fetch: this.config.fetch
|
|
2222
|
+
}));
|
|
2130
2223
|
}
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2224
|
+
return {
|
|
2225
|
+
warnings: [],
|
|
2226
|
+
providerReference: { openai: response.id },
|
|
2227
|
+
...((_b = response.filename) != null ? _b : filename) ? { filename: (_c = response.filename) != null ? _c : filename } : {},
|
|
2228
|
+
...mediaType != null ? { mediaType } : {},
|
|
2229
|
+
...response.bytes != null ? { byteSize: response.bytes } : {},
|
|
2230
|
+
...response.created_at != null ? { createdAt: new Date(response.created_at * 1e3) } : {},
|
|
2231
|
+
...response.expires_at != null ? { expiresAt: new Date(response.expires_at * 1e3) } : {},
|
|
2232
|
+
providerMetadata: {
|
|
2233
|
+
openai: this.toFileMetadata(response)
|
|
2234
|
+
}
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
async getFileMetadata({
|
|
2238
|
+
file,
|
|
2239
|
+
abortSignal,
|
|
2240
|
+
headers
|
|
2241
|
+
}) {
|
|
2242
|
+
const fileId = this.getFileId(file);
|
|
2243
|
+
const { value: response } = await getFromApi({
|
|
2244
|
+
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
|
|
2245
|
+
headers: this.getHeaders(headers),
|
|
2135
2246
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
2136
2247
|
successfulResponseHandler: createJsonResponseHandler4(
|
|
2137
2248
|
openaiFilesResponseSchema
|
|
2138
2249
|
),
|
|
2139
|
-
|
|
2250
|
+
abortSignal,
|
|
2251
|
+
fetch: this.config.fetch,
|
|
2252
|
+
validateUrl: false
|
|
2140
2253
|
});
|
|
2141
2254
|
return {
|
|
2142
2255
|
warnings: [],
|
|
2143
2256
|
providerReference: { openai: response.id },
|
|
2144
|
-
...
|
|
2145
|
-
...
|
|
2257
|
+
...response.filename != null ? { filename: response.filename } : {},
|
|
2258
|
+
...response.bytes != null ? { byteSize: response.bytes } : {},
|
|
2259
|
+
...response.created_at != null ? { createdAt: new Date(response.created_at * 1e3) } : {},
|
|
2260
|
+
...response.expires_at != null ? { expiresAt: new Date(response.expires_at * 1e3) } : {},
|
|
2146
2261
|
providerMetadata: {
|
|
2147
|
-
openai:
|
|
2148
|
-
...response.filename != null ? { filename: response.filename } : {},
|
|
2149
|
-
...response.purpose != null ? { purpose: response.purpose } : {},
|
|
2150
|
-
...response.bytes != null ? { bytes: response.bytes } : {},
|
|
2151
|
-
...response.created_at != null ? { createdAt: response.created_at } : {},
|
|
2152
|
-
...response.status != null ? { status: response.status } : {},
|
|
2153
|
-
...response.expires_at != null ? { expiresAt: response.expires_at } : {}
|
|
2154
|
-
}
|
|
2262
|
+
openai: this.toFileMetadata(response)
|
|
2155
2263
|
}
|
|
2156
2264
|
};
|
|
2157
2265
|
}
|
|
2266
|
+
async downloadFile({
|
|
2267
|
+
file,
|
|
2268
|
+
abortSignal,
|
|
2269
|
+
headers
|
|
2270
|
+
}) {
|
|
2271
|
+
var _a2;
|
|
2272
|
+
const fileId = this.getFileId(file);
|
|
2273
|
+
const { value: content, responseHeaders } = await getFromApi({
|
|
2274
|
+
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}/content`,
|
|
2275
|
+
headers: this.getHeaders(headers),
|
|
2276
|
+
failedResponseHandler: openaiFailedResponseHandler,
|
|
2277
|
+
successfulResponseHandler: createBinaryStreamResponseHandler(),
|
|
2278
|
+
abortSignal,
|
|
2279
|
+
fetch: this.config.fetch,
|
|
2280
|
+
validateUrl: false
|
|
2281
|
+
});
|
|
2282
|
+
const mediaType = (_a2 = responseHeaders == null ? void 0 : responseHeaders["content-type"]) == null ? void 0 : _a2.split(";")[0].trim();
|
|
2283
|
+
return {
|
|
2284
|
+
warnings: [],
|
|
2285
|
+
content,
|
|
2286
|
+
...mediaType ? { mediaType } : {}
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2289
|
+
async deleteFile({
|
|
2290
|
+
file,
|
|
2291
|
+
abortSignal,
|
|
2292
|
+
headers
|
|
2293
|
+
}) {
|
|
2294
|
+
const fileId = this.getFileId(file);
|
|
2295
|
+
const { value: response } = await deleteFromApi({
|
|
2296
|
+
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
|
|
2297
|
+
headers: this.getHeaders(headers),
|
|
2298
|
+
failedResponseHandler: openaiFailedResponseHandler,
|
|
2299
|
+
successfulResponseHandler: createJsonResponseHandler4(
|
|
2300
|
+
openaiFileDeleteResponseSchema
|
|
2301
|
+
),
|
|
2302
|
+
abortSignal,
|
|
2303
|
+
fetch: this.config.fetch
|
|
2304
|
+
});
|
|
2305
|
+
return {
|
|
2306
|
+
warnings: [],
|
|
2307
|
+
providerReference: { openai: response.id },
|
|
2308
|
+
deleted: response.deleted
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
toFileMetadata(response) {
|
|
2312
|
+
return {
|
|
2313
|
+
...response.filename != null ? { filename: response.filename } : {},
|
|
2314
|
+
...response.purpose != null ? { purpose: response.purpose } : {},
|
|
2315
|
+
...response.bytes != null ? { bytes: response.bytes } : {},
|
|
2316
|
+
...response.created_at != null ? { createdAt: response.created_at } : {},
|
|
2317
|
+
...response.status != null ? { status: response.status } : {},
|
|
2318
|
+
...response.expires_at != null ? { expiresAt: response.expires_at } : {}
|
|
2319
|
+
};
|
|
2320
|
+
}
|
|
2158
2321
|
};
|
|
2159
2322
|
|
|
2160
2323
|
// src/image/openai-image-model.ts
|
|
@@ -3355,7 +3518,7 @@ var openaiTools = {
|
|
|
3355
3518
|
|
|
3356
3519
|
// src/openai-responses-batch.ts
|
|
3357
3520
|
import {
|
|
3358
|
-
InvalidArgumentError,
|
|
3521
|
+
InvalidArgumentError as InvalidArgumentError2,
|
|
3359
3522
|
InvalidResponseDataError
|
|
3360
3523
|
} from "@ai-sdk/provider";
|
|
3361
3524
|
import {
|
|
@@ -3363,7 +3526,7 @@ import {
|
|
|
3363
3526
|
convertAsyncIteratorToReadableStream,
|
|
3364
3527
|
createJsonLinesResponseHandler,
|
|
3365
3528
|
createJsonResponseHandler as createJsonResponseHandler7,
|
|
3366
|
-
getFromApi,
|
|
3529
|
+
getFromApi as getFromApi2,
|
|
3367
3530
|
lazySchema as lazySchema26,
|
|
3368
3531
|
normalizeBatchRequestCounts,
|
|
3369
3532
|
postJsonToApi as postJsonToApi6,
|
|
@@ -8913,7 +9076,7 @@ var OpenAIResponsesBatch = class {
|
|
|
8913
9076
|
const batch = await this.retrieveBatch(options);
|
|
8914
9077
|
const batchStatus = convertOpenAIBatchStatus(batch);
|
|
8915
9078
|
if (batchStatus.status === "pending") {
|
|
8916
|
-
throw new
|
|
9079
|
+
throw new InvalidArgumentError2({
|
|
8917
9080
|
argument: "batchId",
|
|
8918
9081
|
message: `OpenAI batch "${options.batchId}" is not complete.`
|
|
8919
9082
|
});
|
|
@@ -8932,7 +9095,7 @@ var OpenAIResponsesBatch = class {
|
|
|
8932
9095
|
}
|
|
8933
9096
|
async retrieveBatch(options) {
|
|
8934
9097
|
var _a2, _b;
|
|
8935
|
-
const { value: batch } = await
|
|
9098
|
+
const { value: batch } = await getFromApi2({
|
|
8936
9099
|
url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}`),
|
|
8937
9100
|
headers: combineHeaders7((_b = (_a2 = this.options.config).headers) == null ? void 0 : _b.call(_a2), options.headers),
|
|
8938
9101
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
@@ -8951,7 +9114,7 @@ var OpenAIResponsesBatch = class {
|
|
|
8951
9114
|
}) {
|
|
8952
9115
|
var _a2, _b;
|
|
8953
9116
|
for (const fileId of fileIds) {
|
|
8954
|
-
const { value: lines } = await
|
|
9117
|
+
const { value: lines } = await getFromApi2({
|
|
8955
9118
|
url: this.getUrl(`/files/${encodeURIComponent(fileId)}/content`),
|
|
8956
9119
|
headers: combineHeaders7(
|
|
8957
9120
|
(_b = (_a2 = this.options.config).headers) == null ? void 0 : _b.call(_a2),
|
|
@@ -10400,7 +10563,7 @@ function getOpenAIRealtimeConnection(headers) {
|
|
|
10400
10563
|
|
|
10401
10564
|
// src/speech-translation/openai-speech-translation-model.ts
|
|
10402
10565
|
import {
|
|
10403
|
-
InvalidArgumentError as
|
|
10566
|
+
InvalidArgumentError as InvalidArgumentError3
|
|
10404
10567
|
} from "@ai-sdk/provider";
|
|
10405
10568
|
import {
|
|
10406
10569
|
combineHeaders as combineHeaders10,
|
|
@@ -10447,7 +10610,7 @@ var OpenAISpeechTranslationModel = class _OpenAISpeechTranslationModel {
|
|
|
10447
10610
|
async doStream(options) {
|
|
10448
10611
|
var _a2, _b, _c, _d, _e;
|
|
10449
10612
|
if (options.targetLanguage == null) {
|
|
10450
|
-
throw new
|
|
10613
|
+
throw new InvalidArgumentError3({
|
|
10451
10614
|
argument: "targetLanguage",
|
|
10452
10615
|
message: `targetLanguage is required for translation model '${this.modelId}'.`
|
|
10453
10616
|
});
|
|
@@ -10687,7 +10850,7 @@ function buildOpenAIRealtimeSpeechTranslationSession({
|
|
|
10687
10850
|
}
|
|
10688
10851
|
function validateOpenAISpeechTranslationInputAudioFormat(inputAudioFormat) {
|
|
10689
10852
|
if (inputAudioFormat.type !== "audio/pcm" || inputAudioFormat.rate != null && inputAudioFormat.rate !== 24e3) {
|
|
10690
|
-
throw new
|
|
10853
|
+
throw new InvalidArgumentError3({
|
|
10691
10854
|
argument: "inputAudioFormat",
|
|
10692
10855
|
message: "The OpenAI Realtime translation API only supports 24kHz 16-bit PCM input audio."
|
|
10693
10856
|
});
|
|
@@ -10800,7 +10963,7 @@ var OpenAISkills = class {
|
|
|
10800
10963
|
};
|
|
10801
10964
|
|
|
10802
10965
|
// src/version.ts
|
|
10803
|
-
var VERSION = true ? "4.0.
|
|
10966
|
+
var VERSION = true ? "4.0.55" : "0.0.0-test";
|
|
10804
10967
|
|
|
10805
10968
|
// src/openai-provider.ts
|
|
10806
10969
|
function createOpenAI(options = {}) {
|