@core-ai/openai 0.5.1 → 0.6.1
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/README.md +21 -0
- package/dist/chunk-ZHHJ76M7.js +416 -0
- package/dist/compat.d.ts +18 -0
- package/dist/compat.js +612 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +529 -522
- package/dist/provider-options-DK-Tz0pz.d.ts +157 -0
- package/package.json +9 -4
package/dist/index.js
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clampReasoningEffort,
|
|
3
|
+
convertToolChoice,
|
|
4
|
+
convertTools,
|
|
5
|
+
createOpenAIEmbeddingModel,
|
|
6
|
+
createOpenAIImageModel,
|
|
7
|
+
createStructuredOutputOptions,
|
|
8
|
+
getOpenAIModelCapabilities,
|
|
9
|
+
getStructuredOutputToolName,
|
|
10
|
+
openaiCompatGenerateProviderOptionsSchema,
|
|
11
|
+
openaiCompatProviderOptionsSchema,
|
|
12
|
+
openaiEmbedProviderOptionsSchema,
|
|
13
|
+
openaiImageProviderOptionsSchema,
|
|
14
|
+
openaiResponsesGenerateProviderOptionsSchema,
|
|
15
|
+
openaiResponsesProviderOptionsSchema,
|
|
16
|
+
parseOpenAIResponsesGenerateProviderOptions,
|
|
17
|
+
safeParseJsonObject,
|
|
18
|
+
toOpenAIReasoningEffort,
|
|
19
|
+
validateOpenAIReasoningConfig,
|
|
20
|
+
wrapOpenAIError
|
|
21
|
+
} from "./chunk-ZHHJ76M7.js";
|
|
22
|
+
|
|
1
23
|
// src/provider.ts
|
|
2
24
|
import OpenAI from "openai";
|
|
3
25
|
|
|
@@ -6,592 +28,620 @@ import {
|
|
|
6
28
|
StructuredOutputNoObjectGeneratedError,
|
|
7
29
|
StructuredOutputParseError,
|
|
8
30
|
StructuredOutputValidationError,
|
|
9
|
-
|
|
10
|
-
|
|
31
|
+
createObjectStream,
|
|
32
|
+
createChatStream
|
|
11
33
|
} from "@core-ai/core-ai";
|
|
12
34
|
|
|
13
35
|
// src/chat-adapter.ts
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
// src/model-capabilities.ts
|
|
18
|
-
var DEFAULT_CAPABILITIES = {
|
|
19
|
-
reasoning: {
|
|
20
|
-
supportsEffort: true,
|
|
21
|
-
supportedRange: ["low", "medium", "high"],
|
|
22
|
-
restrictsSamplingParams: false
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
var MODEL_CAPABILITIES = {
|
|
26
|
-
"gpt-5.2": {
|
|
27
|
-
reasoning: {
|
|
28
|
-
supportsEffort: true,
|
|
29
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
30
|
-
restrictsSamplingParams: true
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"gpt-5.2-codex": {
|
|
34
|
-
reasoning: {
|
|
35
|
-
supportsEffort: true,
|
|
36
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
37
|
-
restrictsSamplingParams: true
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
"gpt-5.2-pro": {
|
|
41
|
-
reasoning: {
|
|
42
|
-
supportsEffort: true,
|
|
43
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
44
|
-
restrictsSamplingParams: true
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"gpt-5.1": {
|
|
48
|
-
reasoning: {
|
|
49
|
-
supportsEffort: true,
|
|
50
|
-
supportedRange: ["low", "medium", "high"],
|
|
51
|
-
restrictsSamplingParams: true
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
"gpt-5": {
|
|
55
|
-
reasoning: {
|
|
56
|
-
supportsEffort: true,
|
|
57
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
58
|
-
restrictsSamplingParams: true
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
"gpt-5-mini": {
|
|
62
|
-
reasoning: {
|
|
63
|
-
supportsEffort: true,
|
|
64
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
65
|
-
restrictsSamplingParams: true
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
"gpt-5-nano": {
|
|
69
|
-
reasoning: {
|
|
70
|
-
supportsEffort: true,
|
|
71
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
72
|
-
restrictsSamplingParams: true
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
o3: {
|
|
76
|
-
reasoning: {
|
|
77
|
-
supportsEffort: true,
|
|
78
|
-
supportedRange: ["low", "medium", "high"],
|
|
79
|
-
restrictsSamplingParams: false
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
"o3-mini": {
|
|
83
|
-
reasoning: {
|
|
84
|
-
supportsEffort: true,
|
|
85
|
-
supportedRange: ["low", "medium", "high"],
|
|
86
|
-
restrictsSamplingParams: false
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
"o4-mini": {
|
|
90
|
-
reasoning: {
|
|
91
|
-
supportsEffort: true,
|
|
92
|
-
supportedRange: ["low", "medium", "high"],
|
|
93
|
-
restrictsSamplingParams: false
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
o1: {
|
|
97
|
-
reasoning: {
|
|
98
|
-
supportsEffort: true,
|
|
99
|
-
supportedRange: ["low", "medium", "high"],
|
|
100
|
-
restrictsSamplingParams: false
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
"o1-mini": {
|
|
104
|
-
reasoning: {
|
|
105
|
-
supportsEffort: false,
|
|
106
|
-
supportedRange: [],
|
|
107
|
-
restrictsSamplingParams: false
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
var EFFORT_RANK = {
|
|
112
|
-
minimal: 0,
|
|
113
|
-
low: 1,
|
|
114
|
-
medium: 2,
|
|
115
|
-
high: 3,
|
|
116
|
-
max: 4
|
|
117
|
-
};
|
|
118
|
-
function getOpenAIModelCapabilities(modelId) {
|
|
119
|
-
const normalizedModelId = normalizeModelId(modelId);
|
|
120
|
-
return MODEL_CAPABILITIES[normalizedModelId] ?? DEFAULT_CAPABILITIES;
|
|
121
|
-
}
|
|
122
|
-
function normalizeModelId(modelId) {
|
|
123
|
-
return modelId.replace(/-\d{8}$/, "");
|
|
124
|
-
}
|
|
125
|
-
function clampReasoningEffort(effort, supportedRange) {
|
|
126
|
-
if (supportedRange.length === 0 || supportedRange.includes(effort)) {
|
|
127
|
-
return effort;
|
|
128
|
-
}
|
|
129
|
-
const targetRank = EFFORT_RANK[effort];
|
|
130
|
-
let best = supportedRange[0] ?? effort;
|
|
131
|
-
let bestDistance = Math.abs(EFFORT_RANK[best] - targetRank);
|
|
132
|
-
for (const candidate of supportedRange) {
|
|
133
|
-
const distance = Math.abs(EFFORT_RANK[candidate] - targetRank);
|
|
134
|
-
if (distance < bestDistance) {
|
|
135
|
-
best = candidate;
|
|
136
|
-
bestDistance = distance;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
return best;
|
|
140
|
-
}
|
|
141
|
-
function toOpenAIReasoningEffort(effort) {
|
|
142
|
-
if (effort === "max") {
|
|
143
|
-
return "xhigh";
|
|
144
|
-
}
|
|
145
|
-
return effort;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// src/chat-adapter.ts
|
|
149
|
-
var DEFAULT_STRUCTURED_OUTPUT_TOOL_NAME = "core_ai_generate_object";
|
|
150
|
-
var DEFAULT_STRUCTURED_OUTPUT_TOOL_DESCRIPTION = "Return a JSON object that matches the requested schema.";
|
|
36
|
+
import { getProviderMetadata } from "@core-ai/core-ai";
|
|
37
|
+
var ENCRYPTED_REASONING_INCLUDE = "reasoning.encrypted_content";
|
|
151
38
|
function convertMessages(messages) {
|
|
152
|
-
return messages.
|
|
39
|
+
return messages.flatMap(convertMessage);
|
|
153
40
|
}
|
|
154
41
|
function convertMessage(message) {
|
|
155
42
|
if (message.role === "system") {
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
43
|
+
return [
|
|
44
|
+
{
|
|
45
|
+
role: "developer",
|
|
46
|
+
content: message.content
|
|
47
|
+
}
|
|
48
|
+
];
|
|
160
49
|
}
|
|
161
50
|
if (message.role === "user") {
|
|
162
|
-
return
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
role: "user",
|
|
54
|
+
content: typeof message.content === "string" ? message.content : message.content.map(convertUserContentPart)
|
|
55
|
+
}
|
|
56
|
+
];
|
|
166
57
|
}
|
|
167
58
|
if (message.role === "assistant") {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
59
|
+
return convertAssistantMessage(message.parts);
|
|
60
|
+
}
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
type: "function_call_output",
|
|
64
|
+
call_id: message.toolCallId,
|
|
65
|
+
output: message.content
|
|
66
|
+
}
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function convertAssistantMessage(parts) {
|
|
70
|
+
const items = [];
|
|
71
|
+
const textParts = [];
|
|
72
|
+
const flushTextBuffer = () => {
|
|
73
|
+
if (textParts.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
items.push({
|
|
173
77
|
role: "assistant",
|
|
174
|
-
content:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
78
|
+
content: textParts.join("\n\n")
|
|
79
|
+
});
|
|
80
|
+
textParts.length = 0;
|
|
81
|
+
};
|
|
82
|
+
for (const part of parts) {
|
|
83
|
+
if (part.type === "text") {
|
|
84
|
+
textParts.push(part.text);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (part.type === "reasoning") {
|
|
88
|
+
if (getProviderMetadata(
|
|
89
|
+
part.providerMetadata,
|
|
90
|
+
"openai"
|
|
91
|
+
) == null) {
|
|
92
|
+
if (part.text.length > 0) {
|
|
93
|
+
textParts.push(`<thinking>${part.text}</thinking>`);
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
flushTextBuffer();
|
|
98
|
+
const encryptedContent = getEncryptedReasoningContent(part);
|
|
99
|
+
items.push({
|
|
100
|
+
type: "reasoning",
|
|
101
|
+
summary: [
|
|
102
|
+
{
|
|
103
|
+
type: "summary_text",
|
|
104
|
+
text: part.text
|
|
182
105
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
106
|
+
],
|
|
107
|
+
...encryptedContent ? { encrypted_content: encryptedContent } : {}
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
flushTextBuffer();
|
|
112
|
+
items.push({
|
|
113
|
+
type: "function_call",
|
|
114
|
+
call_id: part.toolCall.id,
|
|
115
|
+
name: part.toolCall.name,
|
|
116
|
+
arguments: JSON.stringify(part.toolCall.arguments)
|
|
117
|
+
});
|
|
186
118
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
119
|
+
flushTextBuffer();
|
|
120
|
+
return items;
|
|
121
|
+
}
|
|
122
|
+
function getEncryptedReasoningContent(part) {
|
|
123
|
+
const { encryptedContent } = getProviderMetadata(
|
|
124
|
+
part.providerMetadata,
|
|
125
|
+
"openai"
|
|
126
|
+
) ?? {};
|
|
127
|
+
return typeof encryptedContent === "string" && encryptedContent.length > 0 ? encryptedContent : void 0;
|
|
192
128
|
}
|
|
193
129
|
function convertUserContentPart(part) {
|
|
194
130
|
if (part.type === "text") {
|
|
195
131
|
return {
|
|
196
|
-
type: "
|
|
132
|
+
type: "input_text",
|
|
197
133
|
text: part.text
|
|
198
134
|
};
|
|
199
135
|
}
|
|
200
136
|
if (part.type === "image") {
|
|
201
|
-
const
|
|
137
|
+
const imageUrl = part.source.type === "url" ? part.source.url : `data:${part.source.mediaType};base64,${part.source.data}`;
|
|
202
138
|
return {
|
|
203
|
-
type: "
|
|
204
|
-
image_url:
|
|
205
|
-
url
|
|
206
|
-
}
|
|
139
|
+
type: "input_image",
|
|
140
|
+
image_url: imageUrl
|
|
207
141
|
};
|
|
208
142
|
}
|
|
209
143
|
return {
|
|
210
|
-
type: "
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
...part.filename ? { filename: part.filename } : {}
|
|
214
|
-
}
|
|
144
|
+
type: "input_file",
|
|
145
|
+
file_data: part.data,
|
|
146
|
+
...part.filename ? { filename: part.filename } : {}
|
|
215
147
|
};
|
|
216
148
|
}
|
|
217
|
-
function
|
|
218
|
-
return
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
parameters: zodToJsonSchema(tool.parameters)
|
|
224
|
-
}
|
|
225
|
-
}));
|
|
149
|
+
function createGenerateRequest(modelId, options) {
|
|
150
|
+
return createRequest(
|
|
151
|
+
modelId,
|
|
152
|
+
options,
|
|
153
|
+
false
|
|
154
|
+
);
|
|
226
155
|
}
|
|
227
|
-
function
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
function: {
|
|
234
|
-
name: choice.toolName
|
|
235
|
-
}
|
|
236
|
-
};
|
|
156
|
+
function createStreamRequest(modelId, options) {
|
|
157
|
+
return createRequest(
|
|
158
|
+
modelId,
|
|
159
|
+
options,
|
|
160
|
+
true
|
|
161
|
+
);
|
|
237
162
|
}
|
|
238
|
-
function
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
163
|
+
function createRequest(modelId, options, stream) {
|
|
164
|
+
const openaiOptions = parseOpenAIResponsesGenerateProviderOptions(
|
|
165
|
+
options.providerOptions
|
|
166
|
+
);
|
|
167
|
+
const request = {
|
|
168
|
+
...createRequestBase(modelId, options),
|
|
169
|
+
...stream ? { stream: true } : {},
|
|
170
|
+
...mapOpenAIProviderOptionsToRequestFields(openaiOptions)
|
|
171
|
+
};
|
|
172
|
+
if (options.reasoning) {
|
|
173
|
+
request.include = mergeInclude(request.include, [
|
|
174
|
+
ENCRYPTED_REASONING_INCLUDE
|
|
175
|
+
]);
|
|
242
176
|
}
|
|
243
|
-
return
|
|
177
|
+
return request;
|
|
244
178
|
}
|
|
245
|
-
function
|
|
246
|
-
|
|
179
|
+
function createRequestBase(modelId, options) {
|
|
180
|
+
validateOpenAIReasoningConfig(modelId, options);
|
|
247
181
|
return {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
},
|
|
256
|
-
toolChoice: {
|
|
257
|
-
type: "tool",
|
|
258
|
-
toolName
|
|
259
|
-
},
|
|
260
|
-
reasoning: options.reasoning,
|
|
261
|
-
config: options.config,
|
|
262
|
-
providerOptions: options.providerOptions,
|
|
263
|
-
signal: options.signal
|
|
182
|
+
model: modelId,
|
|
183
|
+
store: false,
|
|
184
|
+
input: convertMessages(options.messages),
|
|
185
|
+
...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertResponseTools(options.tools) } : {},
|
|
186
|
+
...options.toolChoice ? { tool_choice: convertResponseToolChoice(options.toolChoice) } : {},
|
|
187
|
+
...mapReasoningToRequestFields(modelId, options),
|
|
188
|
+
...mapSamplingToRequestFields(options)
|
|
264
189
|
};
|
|
265
190
|
}
|
|
266
|
-
function
|
|
267
|
-
return {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
191
|
+
function convertResponseTools(tools) {
|
|
192
|
+
return convertTools(tools).map((tool) => ({
|
|
193
|
+
type: "function",
|
|
194
|
+
name: tool.function.name,
|
|
195
|
+
description: tool.function.description,
|
|
196
|
+
parameters: tool.function.parameters
|
|
197
|
+
}));
|
|
271
198
|
}
|
|
272
|
-
function
|
|
199
|
+
function convertResponseToolChoice(choice) {
|
|
200
|
+
const converted = convertToolChoice(choice);
|
|
201
|
+
if (typeof converted === "string") {
|
|
202
|
+
return converted;
|
|
203
|
+
}
|
|
273
204
|
return {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
stream_options: {
|
|
277
|
-
include_usage: true
|
|
278
|
-
},
|
|
279
|
-
...options.providerOptions
|
|
205
|
+
type: "function",
|
|
206
|
+
name: converted.function.name
|
|
280
207
|
};
|
|
281
208
|
}
|
|
282
|
-
function
|
|
283
|
-
|
|
284
|
-
const
|
|
209
|
+
function mergeInclude(value, requiredIncludes) {
|
|
210
|
+
const include = Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
211
|
+
for (const requiredInclude of requiredIncludes) {
|
|
212
|
+
if (!include.includes(requiredInclude)) {
|
|
213
|
+
include.push(requiredInclude);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return include.length > 0 ? include : void 0;
|
|
217
|
+
}
|
|
218
|
+
function mapSamplingToRequestFields(options) {
|
|
285
219
|
return {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
...options.
|
|
289
|
-
...options.toolChoice ? { tool_choice: convertToolChoice(options.toolChoice) } : {},
|
|
290
|
-
...reasoningFields,
|
|
291
|
-
...mapConfigToRequestFields(options.config)
|
|
220
|
+
...options.temperature !== void 0 ? { temperature: options.temperature } : {},
|
|
221
|
+
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
222
|
+
...options.topP !== void 0 ? { top_p: options.topP } : {}
|
|
292
223
|
};
|
|
293
224
|
}
|
|
294
|
-
function
|
|
225
|
+
function mapOpenAIProviderOptionsToRequestFields(options) {
|
|
295
226
|
return {
|
|
296
|
-
...
|
|
297
|
-
...
|
|
298
|
-
...
|
|
299
|
-
...
|
|
300
|
-
...
|
|
301
|
-
...config?.presencePenalty !== void 0 ? { presence_penalty: config.presencePenalty } : {}
|
|
227
|
+
...options?.store !== void 0 ? { store: options.store } : {},
|
|
228
|
+
...options?.serviceTier !== void 0 ? { service_tier: options.serviceTier } : {},
|
|
229
|
+
...options?.include ? { include: options.include } : {},
|
|
230
|
+
...options?.parallelToolCalls !== void 0 ? { parallel_tool_calls: options.parallelToolCalls } : {},
|
|
231
|
+
...options?.user !== void 0 ? { user: options.user } : {}
|
|
302
232
|
};
|
|
303
233
|
}
|
|
304
234
|
function mapGenerateResponse(response) {
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
toolCalls: [],
|
|
312
|
-
finishReason: "unknown",
|
|
313
|
-
usage: {
|
|
314
|
-
inputTokens: 0,
|
|
315
|
-
outputTokens: 0,
|
|
316
|
-
inputTokenDetails: {
|
|
317
|
-
cacheReadTokens: 0,
|
|
318
|
-
cacheWriteTokens: 0
|
|
319
|
-
},
|
|
320
|
-
outputTokenDetails: {}
|
|
235
|
+
const parts = [];
|
|
236
|
+
for (const item of response.output) {
|
|
237
|
+
if (isReasoningItem(item)) {
|
|
238
|
+
const reasoningPart = mapReasoningPart(item);
|
|
239
|
+
if (reasoningPart) {
|
|
240
|
+
parts.push(reasoningPart);
|
|
321
241
|
}
|
|
322
|
-
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (isOutputMessage(item)) {
|
|
245
|
+
parts.push(...mapMessageTextParts(item));
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
if (isFunctionToolCall(item)) {
|
|
249
|
+
parts.push({
|
|
250
|
+
type: "tool-call",
|
|
251
|
+
toolCall: {
|
|
252
|
+
id: item.call_id,
|
|
253
|
+
name: item.name,
|
|
254
|
+
arguments: safeParseJsonObject(item.arguments)
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
}
|
|
323
258
|
}
|
|
324
|
-
const
|
|
325
|
-
const
|
|
326
|
-
const toolCalls =
|
|
327
|
-
const parts = createAssistantParts(content, toolCalls);
|
|
259
|
+
const content = getTextContent(parts);
|
|
260
|
+
const reasoning = getReasoningText(parts);
|
|
261
|
+
const toolCalls = getToolCalls(parts);
|
|
328
262
|
return {
|
|
329
263
|
parts,
|
|
330
264
|
content,
|
|
331
|
-
reasoning
|
|
265
|
+
reasoning,
|
|
332
266
|
toolCalls,
|
|
333
|
-
finishReason: mapFinishReason(
|
|
334
|
-
usage:
|
|
335
|
-
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
336
|
-
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
337
|
-
inputTokenDetails: {
|
|
338
|
-
cacheReadTokens: response.usage?.prompt_tokens_details?.cached_tokens ?? 0,
|
|
339
|
-
cacheWriteTokens: 0
|
|
340
|
-
},
|
|
341
|
-
outputTokenDetails: {
|
|
342
|
-
...reasoningTokens !== void 0 ? { reasoningTokens } : {}
|
|
343
|
-
}
|
|
344
|
-
}
|
|
267
|
+
finishReason: mapFinishReason(response, toolCalls.length > 0),
|
|
268
|
+
usage: mapUsage(response.usage)
|
|
345
269
|
};
|
|
346
270
|
}
|
|
347
|
-
function
|
|
348
|
-
|
|
349
|
-
|
|
271
|
+
function mapReasoningPart(item) {
|
|
272
|
+
const text = getReasoningSummaryText(item.summary);
|
|
273
|
+
const encryptedContent = typeof item.encrypted_content === "string" && item.encrypted_content.length > 0 ? item.encrypted_content : void 0;
|
|
274
|
+
if (text.length === 0 && !encryptedContent) {
|
|
275
|
+
return null;
|
|
350
276
|
}
|
|
351
|
-
return calls.flatMap((toolCall) => {
|
|
352
|
-
if (toolCall.type !== "function") {
|
|
353
|
-
return [];
|
|
354
|
-
}
|
|
355
|
-
return [mapFunctionToolCall(toolCall)];
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
function mapFunctionToolCall(toolCall) {
|
|
359
277
|
return {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
278
|
+
type: "reasoning",
|
|
279
|
+
text,
|
|
280
|
+
providerMetadata: {
|
|
281
|
+
openai: { ...encryptedContent ? { encryptedContent } : {} }
|
|
282
|
+
}
|
|
363
283
|
};
|
|
364
284
|
}
|
|
365
|
-
function
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
285
|
+
function getReasoningSummaryText(summary) {
|
|
286
|
+
return summary.map((item) => item.text).join("");
|
|
287
|
+
}
|
|
288
|
+
function mapMessageTextParts(message) {
|
|
289
|
+
return message.content.flatMap(
|
|
290
|
+
(contentItem) => contentItem.type === "output_text" && contentItem.text.length > 0 ? [{ type: "text", text: contentItem.text }] : []
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function getTextContent(parts) {
|
|
294
|
+
return getJoinedPartText(parts, "text");
|
|
295
|
+
}
|
|
296
|
+
function getReasoningText(parts) {
|
|
297
|
+
return getJoinedPartText(parts, "reasoning");
|
|
298
|
+
}
|
|
299
|
+
function getJoinedPartText(parts, type) {
|
|
300
|
+
const text = parts.flatMap(
|
|
301
|
+
(part) => part.type === type && "text" in part ? [part.text] : []
|
|
302
|
+
).join("");
|
|
303
|
+
return text.length > 0 ? text : null;
|
|
304
|
+
}
|
|
305
|
+
function getToolCalls(parts) {
|
|
306
|
+
return parts.flatMap(
|
|
307
|
+
(part) => part.type === "tool-call" ? [part.toolCall] : []
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
function mapFinishReason(response, hasToolCalls) {
|
|
311
|
+
const incompleteReason = response.incomplete_details?.reason;
|
|
312
|
+
if (incompleteReason === "max_output_tokens") {
|
|
370
313
|
return "length";
|
|
371
314
|
}
|
|
372
|
-
if (
|
|
315
|
+
if (incompleteReason === "content_filter") {
|
|
316
|
+
return "content-filter";
|
|
317
|
+
}
|
|
318
|
+
if (hasToolCalls) {
|
|
373
319
|
return "tool-calls";
|
|
374
320
|
}
|
|
375
|
-
if (
|
|
376
|
-
return "
|
|
321
|
+
if (response.status === "completed") {
|
|
322
|
+
return "stop";
|
|
377
323
|
}
|
|
378
324
|
return "unknown";
|
|
379
325
|
}
|
|
380
|
-
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
inputTokens: 0,
|
|
386
|
-
outputTokens: 0,
|
|
326
|
+
function mapUsage(usage) {
|
|
327
|
+
const reasoningTokens = usage?.output_tokens_details?.reasoning_tokens;
|
|
328
|
+
return {
|
|
329
|
+
inputTokens: usage?.input_tokens ?? 0,
|
|
330
|
+
outputTokens: usage?.output_tokens ?? 0,
|
|
387
331
|
inputTokenDetails: {
|
|
388
|
-
cacheReadTokens: 0,
|
|
332
|
+
cacheReadTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
389
333
|
cacheWriteTokens: 0
|
|
390
334
|
},
|
|
391
|
-
outputTokenDetails: {
|
|
335
|
+
outputTokenDetails: {
|
|
336
|
+
...reasoningTokens !== void 0 ? { reasoningTokens } : {}
|
|
337
|
+
}
|
|
392
338
|
};
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
339
|
+
}
|
|
340
|
+
function getReasoningStartTransition(reasoningStarted) {
|
|
341
|
+
if (reasoningStarted) {
|
|
342
|
+
return {
|
|
343
|
+
nextReasoningStarted: true,
|
|
344
|
+
event: null
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
nextReasoningStarted: true,
|
|
349
|
+
event: { type: "reasoning-start" }
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function getReasoningEndTransition(reasoningStarted, providerMetadata) {
|
|
353
|
+
if (!reasoningStarted) {
|
|
354
|
+
return {
|
|
355
|
+
nextReasoningStarted: false,
|
|
356
|
+
event: null
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
nextReasoningStarted: false,
|
|
361
|
+
event: {
|
|
362
|
+
type: "reasoning-end",
|
|
363
|
+
providerMetadata
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
async function* transformStream(stream) {
|
|
368
|
+
const bufferedToolCalls = /* @__PURE__ */ new Map();
|
|
369
|
+
const emittedToolCalls = /* @__PURE__ */ new Set();
|
|
370
|
+
const startedToolCalls = /* @__PURE__ */ new Set();
|
|
371
|
+
const seenSummaryDeltas = /* @__PURE__ */ new Set();
|
|
372
|
+
const emittedReasoningItems = /* @__PURE__ */ new Set();
|
|
373
|
+
let latestResponse;
|
|
374
|
+
let reasoningStarted = false;
|
|
375
|
+
const upsertBufferedToolCall = (outputIndex, getNextToolCall) => {
|
|
376
|
+
const nextToolCall = getNextToolCall(bufferedToolCalls.get(outputIndex));
|
|
377
|
+
bufferedToolCalls.set(outputIndex, nextToolCall);
|
|
378
|
+
return nextToolCall;
|
|
379
|
+
};
|
|
380
|
+
for await (const event of stream) {
|
|
381
|
+
if (event.type === "response.reasoning_summary_text.delta") {
|
|
382
|
+
seenSummaryDeltas.add(`${event.item_id}:${event.summary_index}`);
|
|
383
|
+
emittedReasoningItems.add(event.item_id);
|
|
384
|
+
const reasoningStartTransition = getReasoningStartTransition(reasoningStarted);
|
|
385
|
+
reasoningStarted = reasoningStartTransition.nextReasoningStarted;
|
|
386
|
+
if (reasoningStartTransition.event) {
|
|
387
|
+
yield reasoningStartTransition.event;
|
|
388
|
+
}
|
|
389
|
+
yield {
|
|
390
|
+
type: "reasoning-delta",
|
|
391
|
+
text: event.delta
|
|
406
392
|
};
|
|
393
|
+
continue;
|
|
407
394
|
}
|
|
408
|
-
|
|
409
|
-
|
|
395
|
+
if (event.type === "response.reasoning_summary_text.done") {
|
|
396
|
+
const key = `${event.item_id}:${event.summary_index}`;
|
|
397
|
+
if (!seenSummaryDeltas.has(key) && event.text.length > 0) {
|
|
398
|
+
emittedReasoningItems.add(event.item_id);
|
|
399
|
+
const reasoningStartTransition = getReasoningStartTransition(reasoningStarted);
|
|
400
|
+
reasoningStarted = reasoningStartTransition.nextReasoningStarted;
|
|
401
|
+
if (reasoningStartTransition.event) {
|
|
402
|
+
yield reasoningStartTransition.event;
|
|
403
|
+
}
|
|
404
|
+
yield {
|
|
405
|
+
type: "reasoning-delta",
|
|
406
|
+
text: event.text
|
|
407
|
+
};
|
|
408
|
+
}
|
|
410
409
|
continue;
|
|
411
410
|
}
|
|
412
|
-
if (
|
|
411
|
+
if (event.type === "response.output_text.delta") {
|
|
413
412
|
yield {
|
|
414
413
|
type: "text-delta",
|
|
415
|
-
text:
|
|
414
|
+
text: event.delta
|
|
416
415
|
};
|
|
416
|
+
continue;
|
|
417
417
|
}
|
|
418
|
-
if (
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
418
|
+
if (event.type === "response.output_item.added") {
|
|
419
|
+
if (!isFunctionToolCall(event.item)) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const toolCallId = event.item.call_id;
|
|
423
|
+
const toolCallName = event.item.name;
|
|
424
|
+
const toolCallArguments = event.item.arguments;
|
|
425
|
+
upsertBufferedToolCall(
|
|
426
|
+
event.output_index,
|
|
427
|
+
() => ({
|
|
428
|
+
id: toolCallId,
|
|
429
|
+
name: toolCallName,
|
|
430
|
+
arguments: toolCallArguments
|
|
431
|
+
})
|
|
432
|
+
);
|
|
433
|
+
const shouldStartToolCall = !startedToolCalls.has(toolCallId);
|
|
434
|
+
if (shouldStartToolCall) {
|
|
435
|
+
startedToolCalls.add(toolCallId);
|
|
436
|
+
yield {
|
|
437
|
+
type: "tool-call-start",
|
|
438
|
+
toolCallId,
|
|
439
|
+
toolName: toolCallName
|
|
426
440
|
};
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
441
|
+
}
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
if (event.type === "response.function_call_arguments.delta") {
|
|
445
|
+
const currentToolCall = upsertBufferedToolCall(
|
|
446
|
+
event.output_index,
|
|
447
|
+
(bufferedToolCall) => ({
|
|
448
|
+
id: bufferedToolCall?.id ?? event.item_id,
|
|
449
|
+
name: bufferedToolCall?.name ?? "",
|
|
450
|
+
arguments: `${bufferedToolCall?.arguments ?? ""}${event.delta}`
|
|
451
|
+
})
|
|
452
|
+
);
|
|
453
|
+
const shouldStartToolCall = !startedToolCalls.has(currentToolCall.id);
|
|
454
|
+
if (shouldStartToolCall) {
|
|
455
|
+
startedToolCalls.add(currentToolCall.id);
|
|
456
|
+
yield {
|
|
457
|
+
type: "tool-call-start",
|
|
458
|
+
toolCallId: currentToolCall.id,
|
|
459
|
+
toolName: currentToolCall.name
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
yield {
|
|
463
|
+
type: "tool-call-delta",
|
|
464
|
+
toolCallId: currentToolCall.id,
|
|
465
|
+
argumentsDelta: event.delta
|
|
466
|
+
};
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
if (event.type === "response.output_item.done") {
|
|
470
|
+
if (isReasoningItem(event.item)) {
|
|
471
|
+
if (!emittedReasoningItems.has(event.item.id)) {
|
|
472
|
+
const summaryText = getReasoningSummaryText(
|
|
473
|
+
event.item.summary
|
|
474
|
+
);
|
|
475
|
+
if (summaryText.length > 0) {
|
|
476
|
+
const reasoningStartTransition = getReasoningStartTransition(reasoningStarted);
|
|
477
|
+
reasoningStarted = reasoningStartTransition.nextReasoningStarted;
|
|
478
|
+
if (reasoningStartTransition.event) {
|
|
479
|
+
yield reasoningStartTransition.event;
|
|
480
|
+
}
|
|
481
|
+
yield {
|
|
482
|
+
type: "reasoning-delta",
|
|
483
|
+
text: summaryText
|
|
484
|
+
};
|
|
485
|
+
}
|
|
433
486
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
487
|
+
const encryptedContent = typeof event.item.encrypted_content === "string" && event.item.encrypted_content.length > 0 ? event.item.encrypted_content : void 0;
|
|
488
|
+
if (encryptedContent) {
|
|
489
|
+
const reasoningStartTransition = getReasoningStartTransition(reasoningStarted);
|
|
490
|
+
reasoningStarted = reasoningStartTransition.nextReasoningStarted;
|
|
491
|
+
if (reasoningStartTransition.event) {
|
|
492
|
+
yield reasoningStartTransition.event;
|
|
493
|
+
}
|
|
441
494
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
495
|
+
const reasoningEndTransition2 = getReasoningEndTransition(
|
|
496
|
+
reasoningStarted,
|
|
497
|
+
{
|
|
498
|
+
openai: {
|
|
499
|
+
...encryptedContent ? { encryptedContent } : {}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
reasoningStarted = reasoningEndTransition2.nextReasoningStarted;
|
|
504
|
+
if (reasoningEndTransition2.event) {
|
|
505
|
+
yield reasoningEndTransition2.event;
|
|
449
506
|
}
|
|
507
|
+
continue;
|
|
450
508
|
}
|
|
509
|
+
if (!isFunctionToolCall(event.item)) {
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
const toolCallId = event.item.call_id;
|
|
513
|
+
const toolCallName = event.item.name;
|
|
514
|
+
const toolCallArguments = event.item.arguments;
|
|
515
|
+
const currentToolCall = upsertBufferedToolCall(
|
|
516
|
+
event.output_index,
|
|
517
|
+
(bufferedToolCall) => ({
|
|
518
|
+
id: toolCallId,
|
|
519
|
+
name: toolCallName,
|
|
520
|
+
arguments: toolCallArguments || bufferedToolCall?.arguments || ""
|
|
521
|
+
})
|
|
522
|
+
);
|
|
523
|
+
if (!emittedToolCalls.has(currentToolCall.id)) {
|
|
524
|
+
emittedToolCalls.add(currentToolCall.id);
|
|
525
|
+
yield {
|
|
526
|
+
type: "tool-call-end",
|
|
527
|
+
toolCall: {
|
|
528
|
+
id: currentToolCall.id,
|
|
529
|
+
name: currentToolCall.name,
|
|
530
|
+
arguments: safeParseJsonObject(
|
|
531
|
+
currentToolCall.arguments
|
|
532
|
+
)
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
continue;
|
|
451
537
|
}
|
|
452
|
-
if (
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
538
|
+
if (event.type === "response.completed") {
|
|
539
|
+
latestResponse = event.response;
|
|
540
|
+
const reasoningEndTransition2 = getReasoningEndTransition(
|
|
541
|
+
reasoningStarted,
|
|
542
|
+
{ openai: {} }
|
|
543
|
+
);
|
|
544
|
+
reasoningStarted = reasoningEndTransition2.nextReasoningStarted;
|
|
545
|
+
if (reasoningEndTransition2.event) {
|
|
546
|
+
yield reasoningEndTransition2.event;
|
|
547
|
+
}
|
|
548
|
+
for (const bufferedToolCall of bufferedToolCalls.values()) {
|
|
549
|
+
if (emittedToolCalls.has(bufferedToolCall.id)) {
|
|
458
550
|
continue;
|
|
459
551
|
}
|
|
460
|
-
emittedToolCalls.add(
|
|
552
|
+
emittedToolCalls.add(bufferedToolCall.id);
|
|
461
553
|
yield {
|
|
462
554
|
type: "tool-call-end",
|
|
463
555
|
toolCall: {
|
|
464
|
-
id:
|
|
465
|
-
name:
|
|
466
|
-
arguments: safeParseJsonObject(
|
|
556
|
+
id: bufferedToolCall.id,
|
|
557
|
+
name: bufferedToolCall.name,
|
|
558
|
+
arguments: safeParseJsonObject(
|
|
559
|
+
bufferedToolCall.arguments
|
|
560
|
+
)
|
|
467
561
|
}
|
|
468
562
|
};
|
|
469
563
|
}
|
|
564
|
+
const hasToolCalls2 = bufferedToolCalls.size > 0;
|
|
565
|
+
yield {
|
|
566
|
+
type: "finish",
|
|
567
|
+
finishReason: mapFinishReason(latestResponse, hasToolCalls2),
|
|
568
|
+
usage: mapUsage(latestResponse.usage)
|
|
569
|
+
};
|
|
570
|
+
return;
|
|
470
571
|
}
|
|
471
572
|
}
|
|
573
|
+
const reasoningEndTransition = getReasoningEndTransition(reasoningStarted, {
|
|
574
|
+
openai: {}
|
|
575
|
+
});
|
|
576
|
+
reasoningStarted = reasoningEndTransition.nextReasoningStarted;
|
|
577
|
+
if (reasoningEndTransition.event) {
|
|
578
|
+
yield reasoningEndTransition.event;
|
|
579
|
+
}
|
|
580
|
+
const hasToolCalls = bufferedToolCalls.size > 0;
|
|
581
|
+
const usage = latestResponse ? mapUsage(latestResponse.usage) : mapUsage(void 0);
|
|
582
|
+
const finishReason = latestResponse ? mapFinishReason(latestResponse, hasToolCalls) : "unknown";
|
|
472
583
|
yield {
|
|
473
584
|
type: "finish",
|
|
474
585
|
finishReason,
|
|
475
586
|
usage
|
|
476
587
|
};
|
|
477
588
|
}
|
|
478
|
-
function safeParseJsonObject(json) {
|
|
479
|
-
try {
|
|
480
|
-
const parsed = JSON.parse(json);
|
|
481
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
482
|
-
return parsed;
|
|
483
|
-
}
|
|
484
|
-
return {};
|
|
485
|
-
} catch {
|
|
486
|
-
return {};
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
function validateOpenAIReasoningConfig(modelId, options) {
|
|
490
|
-
if (!options.reasoning) {
|
|
491
|
-
return;
|
|
492
|
-
}
|
|
493
|
-
const capabilities = getOpenAIModelCapabilities(modelId);
|
|
494
|
-
if (!capabilities.reasoning.restrictsSamplingParams) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
if (options.config?.temperature !== void 0) {
|
|
498
|
-
throw new ProviderError(
|
|
499
|
-
`OpenAI model "${modelId}" does not support temperature when reasoning is enabled`,
|
|
500
|
-
"openai"
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
if (options.config?.topP !== void 0) {
|
|
504
|
-
throw new ProviderError(
|
|
505
|
-
`OpenAI model "${modelId}" does not support topP when reasoning is enabled`,
|
|
506
|
-
"openai"
|
|
507
|
-
);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
589
|
function mapReasoningToRequestFields(modelId, options) {
|
|
511
590
|
if (!options.reasoning) {
|
|
512
591
|
return {};
|
|
513
592
|
}
|
|
514
593
|
const capabilities = getOpenAIModelCapabilities(modelId);
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
);
|
|
594
|
+
const effort = capabilities.reasoning.supportsEffort ? toOpenAIReasoningEffort(
|
|
595
|
+
clampReasoningEffort(
|
|
596
|
+
options.reasoning.effort,
|
|
597
|
+
capabilities.reasoning.supportedRange
|
|
598
|
+
)
|
|
599
|
+
) : void 0;
|
|
522
600
|
return {
|
|
523
|
-
|
|
601
|
+
reasoning: {
|
|
602
|
+
...effort ? { effort } : {},
|
|
603
|
+
summary: "auto"
|
|
604
|
+
}
|
|
524
605
|
};
|
|
525
606
|
}
|
|
526
|
-
function
|
|
527
|
-
|
|
528
|
-
if (content) {
|
|
529
|
-
parts.push({
|
|
530
|
-
type: "text",
|
|
531
|
-
text: content
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
|
-
for (const toolCall of toolCalls) {
|
|
535
|
-
parts.push({
|
|
536
|
-
type: "tool-call",
|
|
537
|
-
toolCall
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
return parts;
|
|
607
|
+
function isFunctionToolCall(item) {
|
|
608
|
+
return item.type === "function_call";
|
|
541
609
|
}
|
|
542
|
-
function
|
|
543
|
-
|
|
544
|
-
return content;
|
|
545
|
-
}
|
|
546
|
-
if (!Array.isArray(content)) {
|
|
547
|
-
return null;
|
|
548
|
-
}
|
|
549
|
-
const text = content.flatMap((item) => {
|
|
550
|
-
if (!item || typeof item !== "object") {
|
|
551
|
-
return [];
|
|
552
|
-
}
|
|
553
|
-
const textValue = item.text;
|
|
554
|
-
return typeof textValue === "string" ? [textValue] : [];
|
|
555
|
-
}).join("");
|
|
556
|
-
return text.length > 0 ? text : null;
|
|
610
|
+
function isOutputMessage(item) {
|
|
611
|
+
return item.type === "message";
|
|
557
612
|
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
import { APIError } from "openai";
|
|
561
|
-
import { ProviderError as ProviderError2 } from "@core-ai/core-ai";
|
|
562
|
-
function wrapOpenAIError(error) {
|
|
563
|
-
if (error instanceof APIError) {
|
|
564
|
-
return new ProviderError2(error.message, "openai", error.status, error);
|
|
565
|
-
}
|
|
566
|
-
return new ProviderError2(
|
|
567
|
-
error instanceof Error ? error.message : String(error),
|
|
568
|
-
"openai",
|
|
569
|
-
void 0,
|
|
570
|
-
error
|
|
571
|
-
);
|
|
613
|
+
function isReasoningItem(item) {
|
|
614
|
+
return item.type === "reasoning";
|
|
572
615
|
}
|
|
573
616
|
|
|
574
617
|
// src/chat-model.ts
|
|
575
618
|
function createOpenAIChatModel(client, modelId) {
|
|
576
619
|
const provider = "openai";
|
|
577
|
-
async function
|
|
620
|
+
async function callOpenAIResponsesApi(request, signal) {
|
|
578
621
|
try {
|
|
579
|
-
return await client.
|
|
580
|
-
|
|
581
|
-
);
|
|
622
|
+
return await client.responses.create(request, {
|
|
623
|
+
signal
|
|
624
|
+
});
|
|
582
625
|
} catch (error) {
|
|
583
626
|
throw wrapOpenAIError(error);
|
|
584
627
|
}
|
|
585
628
|
}
|
|
586
629
|
async function generateChat(options) {
|
|
587
630
|
const request = createGenerateRequest(modelId, options);
|
|
588
|
-
const response = await
|
|
631
|
+
const response = await callOpenAIResponsesApi(
|
|
632
|
+
request,
|
|
633
|
+
options.signal
|
|
634
|
+
);
|
|
589
635
|
return mapGenerateResponse(response);
|
|
590
636
|
}
|
|
591
637
|
async function streamChat(options) {
|
|
592
638
|
const request = createStreamRequest(modelId, options);
|
|
593
|
-
|
|
594
|
-
|
|
639
|
+
return createChatStream(
|
|
640
|
+
async () => transformStream(
|
|
641
|
+
await callOpenAIResponsesApi(request, options.signal)
|
|
642
|
+
),
|
|
643
|
+
{ signal: options.signal }
|
|
644
|
+
);
|
|
595
645
|
}
|
|
596
646
|
return {
|
|
597
647
|
provider,
|
|
@@ -618,13 +668,16 @@ function createOpenAIChatModel(client, modelId) {
|
|
|
618
668
|
const structuredOptions = createStructuredOutputOptions(options);
|
|
619
669
|
const stream = await streamChat(structuredOptions);
|
|
620
670
|
const toolName = getStructuredOutputToolName(options);
|
|
621
|
-
return
|
|
671
|
+
return createObjectStream(
|
|
622
672
|
transformStructuredOutputStream(
|
|
623
673
|
stream,
|
|
624
674
|
options.schema,
|
|
625
675
|
provider,
|
|
626
676
|
toolName
|
|
627
|
-
)
|
|
677
|
+
),
|
|
678
|
+
{
|
|
679
|
+
signal: options.signal
|
|
680
|
+
}
|
|
628
681
|
);
|
|
629
682
|
}
|
|
630
683
|
};
|
|
@@ -739,7 +792,12 @@ function validateStructuredToolArguments(schema, toolArguments, provider) {
|
|
|
739
792
|
}
|
|
740
793
|
function parseAndValidateStructuredPayload(schema, rawPayload, provider) {
|
|
741
794
|
const parsedPayload = parseJson(rawPayload, provider);
|
|
742
|
-
return validateStructuredObject(
|
|
795
|
+
return validateStructuredObject(
|
|
796
|
+
schema,
|
|
797
|
+
parsedPayload,
|
|
798
|
+
provider,
|
|
799
|
+
rawPayload
|
|
800
|
+
);
|
|
743
801
|
}
|
|
744
802
|
function parseJson(rawOutput, provider) {
|
|
745
803
|
try {
|
|
@@ -776,63 +834,6 @@ function formatZodIssues(issues) {
|
|
|
776
834
|
});
|
|
777
835
|
}
|
|
778
836
|
|
|
779
|
-
// src/embedding-model.ts
|
|
780
|
-
function createOpenAIEmbeddingModel(client, modelId) {
|
|
781
|
-
return {
|
|
782
|
-
provider: "openai",
|
|
783
|
-
modelId,
|
|
784
|
-
async embed(options) {
|
|
785
|
-
try {
|
|
786
|
-
const response = await client.embeddings.create({
|
|
787
|
-
model: modelId,
|
|
788
|
-
input: options.input,
|
|
789
|
-
...options.dimensions !== void 0 ? { dimensions: options.dimensions } : {},
|
|
790
|
-
...options.providerOptions
|
|
791
|
-
});
|
|
792
|
-
return {
|
|
793
|
-
embeddings: response.data.slice().sort((a, b) => a.index - b.index).map((item) => item.embedding),
|
|
794
|
-
usage: {
|
|
795
|
-
inputTokens: response.usage.prompt_tokens
|
|
796
|
-
}
|
|
797
|
-
};
|
|
798
|
-
} catch (error) {
|
|
799
|
-
throw wrapOpenAIError(error);
|
|
800
|
-
}
|
|
801
|
-
}
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
// src/image-model.ts
|
|
806
|
-
function createOpenAIImageModel(client, modelId) {
|
|
807
|
-
return {
|
|
808
|
-
provider: "openai",
|
|
809
|
-
modelId,
|
|
810
|
-
async generate(options) {
|
|
811
|
-
try {
|
|
812
|
-
const request = {
|
|
813
|
-
model: modelId,
|
|
814
|
-
prompt: options.prompt,
|
|
815
|
-
...options.n !== void 0 ? { n: options.n } : {},
|
|
816
|
-
...options.size !== void 0 ? { size: options.size } : {},
|
|
817
|
-
...options.providerOptions
|
|
818
|
-
};
|
|
819
|
-
const response = await client.images.generate(
|
|
820
|
-
request
|
|
821
|
-
);
|
|
822
|
-
return {
|
|
823
|
-
images: (response.data ?? []).map((image) => ({
|
|
824
|
-
base64: image.b64_json ?? void 0,
|
|
825
|
-
url: image.url ?? void 0,
|
|
826
|
-
revisedPrompt: image.revised_prompt ?? void 0
|
|
827
|
-
}))
|
|
828
|
-
};
|
|
829
|
-
} catch (error) {
|
|
830
|
-
throw wrapOpenAIError(error);
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
};
|
|
834
|
-
}
|
|
835
|
-
|
|
836
837
|
// src/provider.ts
|
|
837
838
|
function createOpenAI(options = {}) {
|
|
838
839
|
const client = options.client ?? new OpenAI({
|
|
@@ -846,5 +847,11 @@ function createOpenAI(options = {}) {
|
|
|
846
847
|
};
|
|
847
848
|
}
|
|
848
849
|
export {
|
|
849
|
-
createOpenAI
|
|
850
|
+
createOpenAI,
|
|
851
|
+
openaiCompatGenerateProviderOptionsSchema,
|
|
852
|
+
openaiCompatProviderOptionsSchema,
|
|
853
|
+
openaiEmbedProviderOptionsSchema,
|
|
854
|
+
openaiImageProviderOptionsSchema,
|
|
855
|
+
openaiResponsesGenerateProviderOptionsSchema,
|
|
856
|
+
openaiResponsesProviderOptionsSchema
|
|
850
857
|
};
|