@ai-sdk/openai 4.0.24 → 4.0.26
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 +21 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.js +93 -8
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +10 -2
- package/dist/internal/index.js +87 -6
- package/dist/internal/index.js.map +1 -1
- package/package.json +5 -5
- package/src/files/openai-files.ts +5 -1
- package/src/openai-stream-error.ts +84 -3
- package/src/responses/openai-responses-api.ts +9 -0
- package/src/responses/openai-responses-language-model.ts +8 -0
- package/src/tool/programmatic-tool-calling.ts +23 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @ai-sdk/openai
|
|
2
2
|
|
|
3
|
+
## 4.0.26
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f7c4a38: Serialize file upload expiry settings in the multipart field shape accepted by OpenAI.
|
|
8
|
+
- Updated dependencies [fa95504]
|
|
9
|
+
- @ai-sdk/provider-utils@5.0.17
|
|
10
|
+
|
|
11
|
+
## 4.0.25
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- beaecb3: fix(provider/openai): resolve responses doStream at response.in_progress instead of first output token
|
|
16
|
+
|
|
17
|
+
The early-stream-error peek treated `response.in_progress` as an unknown chunk, so `doStream` did not resolve until the first output item arrived — delaying stream availability (and downstream TTFB for proxies/gateways) by the model's full time-to-first-token. `response.in_progress` is now modeled in the chunk schema and marks the request as accepted: the peek keeps watching for error frames for a short grace window (50ms) so quota/rate-limit errors flushed alongside `response.in_progress` still throw as retryable `APICallError`s, while healthy streams become available right after upstream acknowledges the request.
|
|
18
|
+
|
|
19
|
+
- b192878: feat: add experimental_toolCaller routing to generateText for code mode
|
|
20
|
+
- Updated dependencies [d8210b6]
|
|
21
|
+
- Updated dependencies [b192878]
|
|
22
|
+
- @ai-sdk/provider-utils@5.0.16
|
|
23
|
+
|
|
3
24
|
## 4.0.24
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -311,6 +311,14 @@ declare const openaiResponsesChunkSchema: _ai_sdk_provider_utils.LazySchema<{
|
|
|
311
311
|
model: string;
|
|
312
312
|
service_tier?: string | null | undefined;
|
|
313
313
|
};
|
|
314
|
+
} | {
|
|
315
|
+
type: "response.in_progress";
|
|
316
|
+
response: {
|
|
317
|
+
id: string;
|
|
318
|
+
created_at: number;
|
|
319
|
+
model: string;
|
|
320
|
+
service_tier?: string | null | undefined;
|
|
321
|
+
};
|
|
314
322
|
} | {
|
|
315
323
|
type: "response.output_item.added";
|
|
316
324
|
output_index: number;
|
|
@@ -1300,13 +1308,13 @@ declare const openaiTools: {
|
|
|
1300
1308
|
* Programmatic Tool Calling lets OpenAI Responses models write and execute
|
|
1301
1309
|
* JavaScript that orchestrates eligible tools.
|
|
1302
1310
|
*/
|
|
1303
|
-
programmaticToolCalling: () => _ai_sdk_provider_utils.ProviderExecutedTool<{
|
|
1311
|
+
programmaticToolCalling: () => _ai_sdk_provider_utils.Experimental_ToolCallerTool<_ai_sdk_provider_utils.ProviderExecutedTool<{
|
|
1304
1312
|
code: string;
|
|
1305
1313
|
fingerprint: string;
|
|
1306
1314
|
}, {
|
|
1307
1315
|
result: string;
|
|
1308
1316
|
status: "completed" | "incomplete";
|
|
1309
|
-
}, {}
|
|
1317
|
+
}, {}>>;
|
|
1310
1318
|
/**
|
|
1311
1319
|
* Tool search allows the model to dynamically search for and load deferred
|
|
1312
1320
|
* tools into the model's context as needed. This helps reduce overall token
|
package/dist/index.js
CHANGED
|
@@ -83,15 +83,28 @@ async function throwIfOpenAIStreamErrorBeforeOutput({
|
|
|
83
83
|
stream,
|
|
84
84
|
getError,
|
|
85
85
|
isOutputChunk,
|
|
86
|
+
isAcceptedChunk,
|
|
87
|
+
acceptedGraceMs = 50,
|
|
86
88
|
url,
|
|
87
89
|
requestBodyValues,
|
|
88
90
|
responseHeaders
|
|
89
91
|
}) {
|
|
90
92
|
const [streamForEarlyError, streamForConsumer] = stream.tee();
|
|
91
93
|
const reader = streamForEarlyError.getReader();
|
|
94
|
+
let drainAfterError = false;
|
|
92
95
|
try {
|
|
96
|
+
let accepted = false;
|
|
93
97
|
while (true) {
|
|
94
|
-
|
|
98
|
+
let result;
|
|
99
|
+
if (accepted) {
|
|
100
|
+
const raced = await raceWithTimeout(reader.read(), acceptedGraceMs);
|
|
101
|
+
if (raced.timedOut) {
|
|
102
|
+
return streamForConsumer;
|
|
103
|
+
}
|
|
104
|
+
result = raced.value;
|
|
105
|
+
} else {
|
|
106
|
+
result = await reader.read();
|
|
107
|
+
}
|
|
95
108
|
if (result.done) {
|
|
96
109
|
return streamForConsumer;
|
|
97
110
|
}
|
|
@@ -101,7 +114,10 @@ async function throwIfOpenAIStreamErrorBeforeOutput({
|
|
|
101
114
|
}
|
|
102
115
|
const errorFrame = getError(chunk.value);
|
|
103
116
|
if (errorFrame != null) {
|
|
104
|
-
|
|
117
|
+
drainAfterError = true;
|
|
118
|
+
drainReader(reader).catch(() => {
|
|
119
|
+
});
|
|
120
|
+
drainReader(streamForConsumer.getReader()).catch(() => {
|
|
105
121
|
});
|
|
106
122
|
throw createOpenAIStreamError({
|
|
107
123
|
frame: errorFrame,
|
|
@@ -113,13 +129,46 @@ async function throwIfOpenAIStreamErrorBeforeOutput({
|
|
|
113
129
|
if (isOutputChunk(chunk.value)) {
|
|
114
130
|
return streamForConsumer;
|
|
115
131
|
}
|
|
132
|
+
if (!accepted && (isAcceptedChunk == null ? void 0 : isAcceptedChunk(chunk.value)) === true) {
|
|
133
|
+
accepted = true;
|
|
134
|
+
}
|
|
116
135
|
}
|
|
117
136
|
} finally {
|
|
118
|
-
|
|
119
|
-
|
|
137
|
+
if (!drainAfterError) {
|
|
138
|
+
reader.cancel().catch(() => {
|
|
139
|
+
});
|
|
140
|
+
reader.releaseLock();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function drainReader(reader) {
|
|
145
|
+
try {
|
|
146
|
+
while (!(await reader.read()).done) {
|
|
147
|
+
}
|
|
148
|
+
} catch (e) {
|
|
149
|
+
} finally {
|
|
120
150
|
reader.releaseLock();
|
|
121
151
|
}
|
|
122
152
|
}
|
|
153
|
+
async function raceWithTimeout(promise, timeoutMs) {
|
|
154
|
+
let timer;
|
|
155
|
+
const wrapped = promise.then((value) => ({ timedOut: false, value }));
|
|
156
|
+
try {
|
|
157
|
+
const raced = await Promise.race([
|
|
158
|
+
wrapped,
|
|
159
|
+
new Promise((resolve) => {
|
|
160
|
+
timer = setTimeout(() => resolve({ timedOut: true }), timeoutMs);
|
|
161
|
+
})
|
|
162
|
+
]);
|
|
163
|
+
if (raced.timedOut) {
|
|
164
|
+
wrapped.catch(() => {
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return raced;
|
|
168
|
+
} finally {
|
|
169
|
+
clearTimeout(timer);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
123
172
|
function createOpenAIStreamError({
|
|
124
173
|
frame,
|
|
125
174
|
url,
|
|
@@ -2065,7 +2114,11 @@ var OpenAIFiles = class {
|
|
|
2065
2114
|
}
|
|
2066
2115
|
formData.append("purpose", (_a = openaiOptions == null ? void 0 : openaiOptions.purpose) != null ? _a : "assistants");
|
|
2067
2116
|
if ((openaiOptions == null ? void 0 : openaiOptions.expiresAfter) != null) {
|
|
2068
|
-
formData.append("expires_after",
|
|
2117
|
+
formData.append("expires_after[anchor]", "created_at");
|
|
2118
|
+
formData.append(
|
|
2119
|
+
"expires_after[seconds]",
|
|
2120
|
+
String(openaiOptions.expiresAfter)
|
|
2121
|
+
);
|
|
2069
2122
|
}
|
|
2070
2123
|
const { value: response } = await postFormDataToApi({
|
|
2071
2124
|
url: `${this.config.baseURL}/files`,
|
|
@@ -3114,6 +3167,7 @@ var mcp = (args) => mcpToolFactory(args);
|
|
|
3114
3167
|
// src/tool/programmatic-tool-calling.ts
|
|
3115
3168
|
import {
|
|
3116
3169
|
createProviderExecutedToolFactory as createProviderExecutedToolFactory7,
|
|
3170
|
+
experimental_toolCaller,
|
|
3117
3171
|
lazySchema as lazySchema23,
|
|
3118
3172
|
zodSchema as zodSchema23
|
|
3119
3173
|
} from "@ai-sdk/provider-utils";
|
|
@@ -3140,7 +3194,25 @@ var programmaticToolCallingFactory = createProviderExecutedToolFactory7({
|
|
|
3140
3194
|
outputSchema: programmaticToolCallingOutputSchema,
|
|
3141
3195
|
supportsDeferredResults: true
|
|
3142
3196
|
});
|
|
3143
|
-
var programmaticToolCalling = () => programmaticToolCallingFactory({})
|
|
3197
|
+
var programmaticToolCalling = () => experimental_toolCaller(programmaticToolCallingFactory({}), {
|
|
3198
|
+
type: "provider",
|
|
3199
|
+
prepareProviderOptions: (providerOptions) => {
|
|
3200
|
+
var _a;
|
|
3201
|
+
const openaiOptions = providerOptions == null ? void 0 : providerOptions.openai;
|
|
3202
|
+
return {
|
|
3203
|
+
...providerOptions,
|
|
3204
|
+
openai: {
|
|
3205
|
+
...openaiOptions,
|
|
3206
|
+
allowedCallers: [
|
|
3207
|
+
.../* @__PURE__ */ new Set([
|
|
3208
|
+
...(_a = openaiOptions == null ? void 0 : openaiOptions.allowedCallers) != null ? _a : [],
|
|
3209
|
+
"programmatic"
|
|
3210
|
+
])
|
|
3211
|
+
]
|
|
3212
|
+
}
|
|
3213
|
+
};
|
|
3214
|
+
}
|
|
3215
|
+
});
|
|
3144
3216
|
|
|
3145
3217
|
// src/openai-tools.ts
|
|
3146
3218
|
var openaiTools = {
|
|
@@ -4870,6 +4942,15 @@ var openaiResponsesChunkSchema = lazySchema24(
|
|
|
4870
4942
|
service_tier: z26.string().nullish()
|
|
4871
4943
|
})
|
|
4872
4944
|
}),
|
|
4945
|
+
z26.object({
|
|
4946
|
+
type: z26.literal("response.in_progress"),
|
|
4947
|
+
response: z26.object({
|
|
4948
|
+
id: z26.string(),
|
|
4949
|
+
created_at: z26.number(),
|
|
4950
|
+
model: z26.string(),
|
|
4951
|
+
service_tier: z26.string().nullish()
|
|
4952
|
+
})
|
|
4953
|
+
}),
|
|
4873
4954
|
z26.object({
|
|
4874
4955
|
type: z26.literal("response.output_item.added"),
|
|
4875
4956
|
output_index: z26.number(),
|
|
@@ -7275,6 +7356,7 @@ var OpenAIResponsesLanguageModel = class _OpenAIResponsesLanguageModel {
|
|
|
7275
7356
|
stream: response,
|
|
7276
7357
|
getError: (chunk) => isErrorChunk(chunk) || isResponseFailedChunk(chunk) && chunk.response.error != null ? chunk : void 0,
|
|
7277
7358
|
isOutputChunk: isResponseOutputChunk,
|
|
7359
|
+
isAcceptedChunk: isResponseInProgressChunk,
|
|
7278
7360
|
url,
|
|
7279
7361
|
requestBodyValues: body,
|
|
7280
7362
|
responseHeaders
|
|
@@ -8316,8 +8398,11 @@ function isResponseAnnotationAddedChunk(chunk) {
|
|
|
8316
8398
|
function isErrorChunk(chunk) {
|
|
8317
8399
|
return chunk.type === "error";
|
|
8318
8400
|
}
|
|
8401
|
+
function isResponseInProgressChunk(chunk) {
|
|
8402
|
+
return chunk.type === "response.in_progress";
|
|
8403
|
+
}
|
|
8319
8404
|
function isResponseOutputChunk(chunk) {
|
|
8320
|
-
return !(chunk.type === "response.created" || chunk.type === "response.failed" || chunk.type === "error" || chunk.type === "unknown_chunk");
|
|
8405
|
+
return !(chunk.type === "response.created" || chunk.type === "response.in_progress" || chunk.type === "response.failed" || chunk.type === "error" || chunk.type === "unknown_chunk");
|
|
8321
8406
|
}
|
|
8322
8407
|
function mapWebSearchOutput(action) {
|
|
8323
8408
|
var _a;
|
|
@@ -9422,7 +9507,7 @@ var OpenAISkills = class {
|
|
|
9422
9507
|
};
|
|
9423
9508
|
|
|
9424
9509
|
// src/version.ts
|
|
9425
|
-
var VERSION = true ? "4.0.
|
|
9510
|
+
var VERSION = true ? "4.0.26" : "0.0.0-test";
|
|
9426
9511
|
|
|
9427
9512
|
// src/openai-provider.ts
|
|
9428
9513
|
function createOpenAI(options = {}) {
|