@core-ai/openai 0.14.0 → 0.16.0
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 +8 -5
- package/dist/chunk-YORO2XQ3.js +1852 -0
- package/dist/compat.d.ts +11 -9
- package/dist/compat.js +19 -456
- package/dist/index.d.ts +4 -7
- package/dist/index.js +8 -740
- package/dist/{provider-options-DzqvHoId.d.ts → provider-options-CpxtGjm0.d.ts} +64 -6
- package/package.json +2 -2
- package/dist/chunk-7MAEB5C7.js +0 -568
package/dist/index.js
CHANGED
|
@@ -1,758 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
convertTools,
|
|
2
|
+
createOpenAIChatCompletionsModel,
|
|
4
3
|
createOpenAIProvider,
|
|
5
|
-
createStructuredOutputOptions,
|
|
6
|
-
extractStructuredObject,
|
|
7
4
|
getOpenAIModelCapabilities,
|
|
8
|
-
|
|
5
|
+
openaiChatGenerateProviderOptionsSchema,
|
|
9
6
|
openaiCompatGenerateProviderOptionsSchema,
|
|
10
7
|
openaiCompatProviderOptionsSchema,
|
|
11
8
|
openaiEmbedProviderOptionsSchema,
|
|
12
9
|
openaiImageProviderOptionsSchema,
|
|
13
10
|
openaiResponsesGenerateProviderOptionsSchema,
|
|
14
|
-
openaiResponsesProviderOptionsSchema
|
|
15
|
-
|
|
16
|
-
safeParseJsonObject,
|
|
17
|
-
toOpenAIReasoningEffort,
|
|
18
|
-
transformStructuredOutputStream,
|
|
19
|
-
validateOpenAIReasoningConfig,
|
|
20
|
-
wrapOpenAIError
|
|
21
|
-
} from "./chunk-7MAEB5C7.js";
|
|
22
|
-
|
|
23
|
-
// src/chat-model.ts
|
|
24
|
-
import { createObjectStream, createChatStream } from "@core-ai/core-ai";
|
|
25
|
-
|
|
26
|
-
// src/chat-adapter.ts
|
|
27
|
-
import { getProviderMetadata, clampReasoningEffort } from "@core-ai/core-ai";
|
|
28
|
-
var ENCRYPTED_REASONING_INCLUDE = "reasoning.encrypted_content";
|
|
29
|
-
var REASONING_SUMMARY_SEPARATOR = "\n\n";
|
|
30
|
-
function convertMessages(messages) {
|
|
31
|
-
return messages.flatMap(convertMessage);
|
|
32
|
-
}
|
|
33
|
-
function convertMessage(message) {
|
|
34
|
-
if (message.role === "system") {
|
|
35
|
-
return [
|
|
36
|
-
{
|
|
37
|
-
role: "developer",
|
|
38
|
-
content: message.content
|
|
39
|
-
}
|
|
40
|
-
];
|
|
41
|
-
}
|
|
42
|
-
if (message.role === "user") {
|
|
43
|
-
return [
|
|
44
|
-
{
|
|
45
|
-
role: "user",
|
|
46
|
-
content: typeof message.content === "string" ? message.content : message.content.map(convertUserContentPart)
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
}
|
|
50
|
-
if (message.role === "assistant") {
|
|
51
|
-
return convertAssistantMessage(message.parts);
|
|
52
|
-
}
|
|
53
|
-
return [
|
|
54
|
-
{
|
|
55
|
-
type: "function_call_output",
|
|
56
|
-
call_id: message.toolCallId,
|
|
57
|
-
output: message.content
|
|
58
|
-
}
|
|
59
|
-
];
|
|
60
|
-
}
|
|
61
|
-
function convertAssistantMessage(parts) {
|
|
62
|
-
const items = [];
|
|
63
|
-
const textParts = [];
|
|
64
|
-
const flushTextBuffer = () => {
|
|
65
|
-
if (textParts.length === 0) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
items.push({
|
|
69
|
-
role: "assistant",
|
|
70
|
-
content: textParts.join("\n\n")
|
|
71
|
-
});
|
|
72
|
-
textParts.length = 0;
|
|
73
|
-
};
|
|
74
|
-
for (const part of parts) {
|
|
75
|
-
if (part.type === "text") {
|
|
76
|
-
textParts.push(part.text);
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
if (part.type === "reasoning") {
|
|
80
|
-
if (getProviderMetadata(
|
|
81
|
-
part.providerMetadata,
|
|
82
|
-
"openai"
|
|
83
|
-
) == null) {
|
|
84
|
-
if (part.text.length > 0) {
|
|
85
|
-
textParts.push(`<thinking>${part.text}</thinking>`);
|
|
86
|
-
}
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
flushTextBuffer();
|
|
90
|
-
const encryptedContent = getEncryptedReasoningContent(part);
|
|
91
|
-
items.push({
|
|
92
|
-
type: "reasoning",
|
|
93
|
-
summary: [
|
|
94
|
-
{
|
|
95
|
-
type: "summary_text",
|
|
96
|
-
text: part.text
|
|
97
|
-
}
|
|
98
|
-
],
|
|
99
|
-
...encryptedContent ? { encrypted_content: encryptedContent } : {}
|
|
100
|
-
});
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
flushTextBuffer();
|
|
104
|
-
items.push({
|
|
105
|
-
type: "function_call",
|
|
106
|
-
call_id: part.toolCall.id,
|
|
107
|
-
name: part.toolCall.name,
|
|
108
|
-
arguments: JSON.stringify(part.toolCall.arguments)
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
flushTextBuffer();
|
|
112
|
-
return items;
|
|
113
|
-
}
|
|
114
|
-
function getEncryptedReasoningContent(part) {
|
|
115
|
-
const { encryptedContent } = getProviderMetadata(
|
|
116
|
-
part.providerMetadata,
|
|
117
|
-
"openai"
|
|
118
|
-
) ?? {};
|
|
119
|
-
return typeof encryptedContent === "string" && encryptedContent.length > 0 ? encryptedContent : void 0;
|
|
120
|
-
}
|
|
121
|
-
function convertUserContentPart(part) {
|
|
122
|
-
if (part.type === "text") {
|
|
123
|
-
return {
|
|
124
|
-
type: "input_text",
|
|
125
|
-
text: part.text
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
if (part.type === "image") {
|
|
129
|
-
const imageUrl = part.source.type === "url" ? part.source.url : `data:${part.source.mediaType};base64,${part.source.data}`;
|
|
130
|
-
return {
|
|
131
|
-
type: "input_image",
|
|
132
|
-
image_url: imageUrl
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
return {
|
|
136
|
-
type: "input_file",
|
|
137
|
-
file_data: part.data,
|
|
138
|
-
...part.filename ? { filename: part.filename } : {}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
function createGenerateRequest(modelId, options) {
|
|
142
|
-
return createRequest(
|
|
143
|
-
modelId,
|
|
144
|
-
options,
|
|
145
|
-
false
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
function createStreamRequest(modelId, options) {
|
|
149
|
-
return createRequest(
|
|
150
|
-
modelId,
|
|
151
|
-
options,
|
|
152
|
-
true
|
|
153
|
-
);
|
|
154
|
-
}
|
|
155
|
-
function createRequest(modelId, options, stream) {
|
|
156
|
-
const openaiOptions = parseOpenAIResponsesGenerateProviderOptions(
|
|
157
|
-
options.providerOptions
|
|
158
|
-
);
|
|
159
|
-
const request = {
|
|
160
|
-
...createRequestBase(modelId, options),
|
|
161
|
-
...stream ? { stream: true } : {},
|
|
162
|
-
...mapOpenAIProviderOptionsToRequestFields(openaiOptions)
|
|
163
|
-
};
|
|
164
|
-
if (options.reasoning && getOpenAIModelCapabilities(modelId).reasoning.supported) {
|
|
165
|
-
request.include = mergeInclude(request.include, [
|
|
166
|
-
ENCRYPTED_REASONING_INCLUDE
|
|
167
|
-
]);
|
|
168
|
-
}
|
|
169
|
-
return request;
|
|
170
|
-
}
|
|
171
|
-
function createRequestBase(modelId, options) {
|
|
172
|
-
validateOpenAIReasoningConfig(modelId, options);
|
|
173
|
-
return {
|
|
174
|
-
model: modelId,
|
|
175
|
-
store: false,
|
|
176
|
-
input: convertMessages(options.messages),
|
|
177
|
-
...options.tools && Object.keys(options.tools).length > 0 ? { tools: convertResponseTools(options.tools) } : {},
|
|
178
|
-
...options.toolChoice ? { tool_choice: convertResponseToolChoice(options.toolChoice) } : {},
|
|
179
|
-
...mapReasoningToRequestFields(modelId, options),
|
|
180
|
-
...mapSamplingToRequestFields(options)
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
function convertResponseTools(tools) {
|
|
184
|
-
return convertTools(tools).map((tool) => ({
|
|
185
|
-
type: "function",
|
|
186
|
-
name: tool.function.name,
|
|
187
|
-
description: tool.function.description,
|
|
188
|
-
parameters: tool.function.parameters
|
|
189
|
-
}));
|
|
190
|
-
}
|
|
191
|
-
function convertResponseToolChoice(choice) {
|
|
192
|
-
const converted = convertToolChoice(choice);
|
|
193
|
-
if (typeof converted === "string") {
|
|
194
|
-
return converted;
|
|
195
|
-
}
|
|
196
|
-
return {
|
|
197
|
-
type: "function",
|
|
198
|
-
name: converted.function.name
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
function mergeInclude(value, requiredIncludes) {
|
|
202
|
-
const include = Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
203
|
-
for (const requiredInclude of requiredIncludes) {
|
|
204
|
-
if (!include.includes(requiredInclude)) {
|
|
205
|
-
include.push(requiredInclude);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return include.length > 0 ? include : void 0;
|
|
209
|
-
}
|
|
210
|
-
function mapSamplingToRequestFields(options) {
|
|
211
|
-
return {
|
|
212
|
-
...options.temperature !== void 0 ? { temperature: options.temperature } : {},
|
|
213
|
-
...options.maxTokens !== void 0 ? { max_output_tokens: options.maxTokens } : {},
|
|
214
|
-
...options.topP !== void 0 ? { top_p: options.topP } : {}
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
function mapOpenAIProviderOptionsToRequestFields(options) {
|
|
218
|
-
return {
|
|
219
|
-
...options?.store !== void 0 ? { store: options.store } : {},
|
|
220
|
-
...options?.serviceTier !== void 0 ? { service_tier: options.serviceTier } : {},
|
|
221
|
-
...options?.include ? { include: options.include } : {},
|
|
222
|
-
...options?.parallelToolCalls !== void 0 ? { parallel_tool_calls: options.parallelToolCalls } : {},
|
|
223
|
-
...options?.user !== void 0 ? { user: options.user } : {}
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function mapGenerateResponse(response) {
|
|
227
|
-
const parts = [];
|
|
228
|
-
for (const item of response.output) {
|
|
229
|
-
if (isReasoningItem(item)) {
|
|
230
|
-
const reasoningPart = mapReasoningPart(item);
|
|
231
|
-
if (reasoningPart) {
|
|
232
|
-
parts.push(reasoningPart);
|
|
233
|
-
}
|
|
234
|
-
continue;
|
|
235
|
-
}
|
|
236
|
-
if (isOutputMessage(item)) {
|
|
237
|
-
parts.push(...mapMessageTextParts(item));
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
if (isFunctionToolCall(item)) {
|
|
241
|
-
parts.push({
|
|
242
|
-
type: "tool-call",
|
|
243
|
-
toolCall: {
|
|
244
|
-
id: item.call_id,
|
|
245
|
-
name: item.name,
|
|
246
|
-
arguments: safeParseJsonObject(item.arguments)
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
const content = getTextContent(parts);
|
|
252
|
-
const reasoning = getReasoningText(parts);
|
|
253
|
-
const toolCalls = getToolCalls(parts);
|
|
254
|
-
return {
|
|
255
|
-
parts,
|
|
256
|
-
content,
|
|
257
|
-
reasoning,
|
|
258
|
-
toolCalls,
|
|
259
|
-
finishReason: mapFinishReason(response, toolCalls.length > 0),
|
|
260
|
-
usage: mapUsage(response.usage)
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
function mapReasoningPart(item) {
|
|
264
|
-
const text = getReasoningSummaryText(item.summary);
|
|
265
|
-
const encryptedContent = typeof item.encrypted_content === "string" && item.encrypted_content.length > 0 ? item.encrypted_content : void 0;
|
|
266
|
-
if (text.length === 0 && !encryptedContent) {
|
|
267
|
-
return null;
|
|
268
|
-
}
|
|
269
|
-
return {
|
|
270
|
-
type: "reasoning",
|
|
271
|
-
text,
|
|
272
|
-
providerMetadata: {
|
|
273
|
-
openai: { ...encryptedContent ? { encryptedContent } : {} }
|
|
274
|
-
}
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
function getReasoningSummaryText(summary) {
|
|
278
|
-
return summary.map((item) => item.text).join(REASONING_SUMMARY_SEPARATOR);
|
|
279
|
-
}
|
|
280
|
-
function mapMessageTextParts(message) {
|
|
281
|
-
return message.content.flatMap(
|
|
282
|
-
(contentItem) => contentItem.type === "output_text" && contentItem.text.length > 0 ? [{ type: "text", text: contentItem.text }] : []
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
function getTextContent(parts) {
|
|
286
|
-
return getJoinedPartText(parts, "text", "");
|
|
287
|
-
}
|
|
288
|
-
function getReasoningText(parts) {
|
|
289
|
-
return getJoinedPartText(parts, "reasoning", REASONING_SUMMARY_SEPARATOR);
|
|
290
|
-
}
|
|
291
|
-
function getJoinedPartText(parts, type, separator) {
|
|
292
|
-
const text = parts.flatMap(
|
|
293
|
-
(part) => part.type === type && "text" in part ? [part.text] : []
|
|
294
|
-
).join(separator);
|
|
295
|
-
return text.length > 0 ? text : null;
|
|
296
|
-
}
|
|
297
|
-
function getToolCalls(parts) {
|
|
298
|
-
return parts.flatMap(
|
|
299
|
-
(part) => part.type === "tool-call" ? [part.toolCall] : []
|
|
300
|
-
);
|
|
301
|
-
}
|
|
302
|
-
function mapFinishReason(response, hasToolCalls) {
|
|
303
|
-
const incompleteReason = response.incomplete_details?.reason;
|
|
304
|
-
if (incompleteReason === "max_output_tokens") {
|
|
305
|
-
return "length";
|
|
306
|
-
}
|
|
307
|
-
if (incompleteReason === "content_filter") {
|
|
308
|
-
return "content-filter";
|
|
309
|
-
}
|
|
310
|
-
if (hasToolCalls) {
|
|
311
|
-
return "tool-calls";
|
|
312
|
-
}
|
|
313
|
-
if (response.status === "completed") {
|
|
314
|
-
return "stop";
|
|
315
|
-
}
|
|
316
|
-
return "unknown";
|
|
317
|
-
}
|
|
318
|
-
function mapUsage(usage) {
|
|
319
|
-
const reasoningTokens = usage?.output_tokens_details?.reasoning_tokens;
|
|
320
|
-
return {
|
|
321
|
-
inputTokens: usage?.input_tokens ?? 0,
|
|
322
|
-
outputTokens: usage?.output_tokens ?? 0,
|
|
323
|
-
inputTokenDetails: {
|
|
324
|
-
cacheReadTokens: usage?.input_tokens_details?.cached_tokens ?? 0,
|
|
325
|
-
cacheWriteTokens: 0
|
|
326
|
-
},
|
|
327
|
-
outputTokenDetails: {
|
|
328
|
-
...reasoningTokens !== void 0 ? { reasoningTokens } : {}
|
|
329
|
-
}
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
function getReasoningSummaryKey(part) {
|
|
333
|
-
return `${part.itemId}:${part.summaryIndex}`;
|
|
334
|
-
}
|
|
335
|
-
function isSameReasoningSummaryPart(left, right) {
|
|
336
|
-
return left.itemId === right.itemId && left.summaryIndex === right.summaryIndex;
|
|
337
|
-
}
|
|
338
|
-
function getReasoningStartTransition(reasoningStarted) {
|
|
339
|
-
if (reasoningStarted) {
|
|
340
|
-
return {
|
|
341
|
-
nextReasoningStarted: true,
|
|
342
|
-
event: null
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
return {
|
|
346
|
-
nextReasoningStarted: true,
|
|
347
|
-
event: { type: "reasoning-start" }
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
function getReasoningEndTransition(reasoningStarted, providerMetadata) {
|
|
351
|
-
if (!reasoningStarted) {
|
|
352
|
-
return {
|
|
353
|
-
nextReasoningStarted: false,
|
|
354
|
-
event: null
|
|
355
|
-
};
|
|
356
|
-
}
|
|
357
|
-
return {
|
|
358
|
-
nextReasoningStarted: false,
|
|
359
|
-
event: {
|
|
360
|
-
type: "reasoning-end",
|
|
361
|
-
providerMetadata
|
|
362
|
-
}
|
|
363
|
-
};
|
|
364
|
-
}
|
|
365
|
-
async function* transformStream(stream) {
|
|
366
|
-
const bufferedToolCalls = /* @__PURE__ */ new Map();
|
|
367
|
-
const emittedToolCalls = /* @__PURE__ */ new Set();
|
|
368
|
-
const startedToolCalls = /* @__PURE__ */ new Set();
|
|
369
|
-
const seenSummaryDeltas = /* @__PURE__ */ new Set();
|
|
370
|
-
const emittedReasoningItems = /* @__PURE__ */ new Set();
|
|
371
|
-
let latestResponse;
|
|
372
|
-
let textOpen = false;
|
|
373
|
-
let reasoningStarted = false;
|
|
374
|
-
let latestReasoningSummaryPart;
|
|
375
|
-
const upsertBufferedToolCall = (outputIndex, getNextToolCall) => {
|
|
376
|
-
const nextToolCall = getNextToolCall(
|
|
377
|
-
bufferedToolCalls.get(outputIndex)
|
|
378
|
-
);
|
|
379
|
-
bufferedToolCalls.set(outputIndex, nextToolCall);
|
|
380
|
-
return nextToolCall;
|
|
381
|
-
};
|
|
382
|
-
const getNextReasoningStartEvent = () => {
|
|
383
|
-
const transition = getReasoningStartTransition(reasoningStarted);
|
|
384
|
-
reasoningStarted = transition.nextReasoningStarted;
|
|
385
|
-
return transition.event;
|
|
386
|
-
};
|
|
387
|
-
const startText = function* () {
|
|
388
|
-
if (textOpen) {
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
textOpen = true;
|
|
392
|
-
yield { type: "text-start" };
|
|
393
|
-
};
|
|
394
|
-
const closeText = function* () {
|
|
395
|
-
if (!textOpen) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
textOpen = false;
|
|
399
|
-
yield { type: "text-end" };
|
|
400
|
-
};
|
|
401
|
-
const getNextReasoningEndEvent = (providerMetadata) => {
|
|
402
|
-
const transition = getReasoningEndTransition(
|
|
403
|
-
reasoningStarted,
|
|
404
|
-
providerMetadata
|
|
405
|
-
);
|
|
406
|
-
reasoningStarted = transition.nextReasoningStarted;
|
|
407
|
-
if (transition.event) {
|
|
408
|
-
latestReasoningSummaryPart = void 0;
|
|
409
|
-
}
|
|
410
|
-
return transition.event;
|
|
411
|
-
};
|
|
412
|
-
const getReasoningSummarySeparatorEvent = (currentPart) => {
|
|
413
|
-
const previousPart = latestReasoningSummaryPart;
|
|
414
|
-
latestReasoningSummaryPart = currentPart;
|
|
415
|
-
if (previousPart === void 0 || isSameReasoningSummaryPart(previousPart, currentPart)) {
|
|
416
|
-
return null;
|
|
417
|
-
}
|
|
418
|
-
return {
|
|
419
|
-
type: "reasoning-delta",
|
|
420
|
-
text: REASONING_SUMMARY_SEPARATOR
|
|
421
|
-
};
|
|
422
|
-
};
|
|
423
|
-
for await (const event of stream) {
|
|
424
|
-
if (event.type === "response.reasoning_summary_text.delta") {
|
|
425
|
-
const summaryPart = {
|
|
426
|
-
itemId: event.item_id,
|
|
427
|
-
summaryIndex: event.summary_index
|
|
428
|
-
};
|
|
429
|
-
seenSummaryDeltas.add(getReasoningSummaryKey(summaryPart));
|
|
430
|
-
emittedReasoningItems.add(event.item_id);
|
|
431
|
-
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
432
|
-
if (reasoningStartEvent) {
|
|
433
|
-
yield* closeText();
|
|
434
|
-
yield reasoningStartEvent;
|
|
435
|
-
}
|
|
436
|
-
const separatorEvent = getReasoningSummarySeparatorEvent(summaryPart);
|
|
437
|
-
if (separatorEvent) {
|
|
438
|
-
yield separatorEvent;
|
|
439
|
-
}
|
|
440
|
-
yield {
|
|
441
|
-
type: "reasoning-delta",
|
|
442
|
-
text: event.delta
|
|
443
|
-
};
|
|
444
|
-
continue;
|
|
445
|
-
}
|
|
446
|
-
if (event.type === "response.reasoning_summary_text.done") {
|
|
447
|
-
const summaryPart = {
|
|
448
|
-
itemId: event.item_id,
|
|
449
|
-
summaryIndex: event.summary_index
|
|
450
|
-
};
|
|
451
|
-
const key = getReasoningSummaryKey(summaryPart);
|
|
452
|
-
if (!seenSummaryDeltas.has(key) && event.text.length > 0) {
|
|
453
|
-
emittedReasoningItems.add(event.item_id);
|
|
454
|
-
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
455
|
-
if (reasoningStartEvent) {
|
|
456
|
-
yield* closeText();
|
|
457
|
-
yield reasoningStartEvent;
|
|
458
|
-
}
|
|
459
|
-
const separatorEvent = getReasoningSummarySeparatorEvent(summaryPart);
|
|
460
|
-
if (separatorEvent) {
|
|
461
|
-
yield separatorEvent;
|
|
462
|
-
}
|
|
463
|
-
yield {
|
|
464
|
-
type: "reasoning-delta",
|
|
465
|
-
text: event.text
|
|
466
|
-
};
|
|
467
|
-
}
|
|
468
|
-
continue;
|
|
469
|
-
}
|
|
470
|
-
if (event.type === "response.output_text.delta") {
|
|
471
|
-
const reasoningEndEvent2 = getNextReasoningEndEvent({ openai: {} });
|
|
472
|
-
if (reasoningEndEvent2) {
|
|
473
|
-
yield reasoningEndEvent2;
|
|
474
|
-
}
|
|
475
|
-
yield* startText();
|
|
476
|
-
yield {
|
|
477
|
-
type: "text-delta",
|
|
478
|
-
text: event.delta
|
|
479
|
-
};
|
|
480
|
-
continue;
|
|
481
|
-
}
|
|
482
|
-
if (event.type === "response.output_item.added") {
|
|
483
|
-
if (!isFunctionToolCall(event.item)) {
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
486
|
-
yield* closeText();
|
|
487
|
-
const toolCallId = event.item.call_id;
|
|
488
|
-
const toolCallName = event.item.name;
|
|
489
|
-
const toolCallArguments = event.item.arguments;
|
|
490
|
-
upsertBufferedToolCall(event.output_index, () => ({
|
|
491
|
-
id: toolCallId,
|
|
492
|
-
name: toolCallName,
|
|
493
|
-
arguments: toolCallArguments
|
|
494
|
-
}));
|
|
495
|
-
const shouldStartToolCall = !startedToolCalls.has(toolCallId);
|
|
496
|
-
if (shouldStartToolCall) {
|
|
497
|
-
startedToolCalls.add(toolCallId);
|
|
498
|
-
yield {
|
|
499
|
-
type: "tool-call-start",
|
|
500
|
-
toolCallId,
|
|
501
|
-
toolName: toolCallName
|
|
502
|
-
};
|
|
503
|
-
}
|
|
504
|
-
continue;
|
|
505
|
-
}
|
|
506
|
-
if (event.type === "response.function_call_arguments.delta") {
|
|
507
|
-
yield* closeText();
|
|
508
|
-
const currentToolCall = upsertBufferedToolCall(
|
|
509
|
-
event.output_index,
|
|
510
|
-
(bufferedToolCall) => ({
|
|
511
|
-
id: bufferedToolCall?.id ?? event.item_id,
|
|
512
|
-
name: bufferedToolCall?.name ?? "",
|
|
513
|
-
arguments: `${bufferedToolCall?.arguments ?? ""}${event.delta}`
|
|
514
|
-
})
|
|
515
|
-
);
|
|
516
|
-
const shouldStartToolCall = !startedToolCalls.has(
|
|
517
|
-
currentToolCall.id
|
|
518
|
-
);
|
|
519
|
-
if (shouldStartToolCall) {
|
|
520
|
-
startedToolCalls.add(currentToolCall.id);
|
|
521
|
-
yield {
|
|
522
|
-
type: "tool-call-start",
|
|
523
|
-
toolCallId: currentToolCall.id,
|
|
524
|
-
toolName: currentToolCall.name
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
yield {
|
|
528
|
-
type: "tool-call-delta",
|
|
529
|
-
toolCallId: currentToolCall.id,
|
|
530
|
-
argumentsDelta: event.delta
|
|
531
|
-
};
|
|
532
|
-
continue;
|
|
533
|
-
}
|
|
534
|
-
if (event.type === "response.output_item.done") {
|
|
535
|
-
if (isReasoningItem(event.item)) {
|
|
536
|
-
if (!emittedReasoningItems.has(event.item.id)) {
|
|
537
|
-
const summaryText = getReasoningSummaryText(
|
|
538
|
-
event.item.summary
|
|
539
|
-
);
|
|
540
|
-
if (summaryText.length > 0) {
|
|
541
|
-
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
542
|
-
if (reasoningStartEvent) {
|
|
543
|
-
yield* closeText();
|
|
544
|
-
yield reasoningStartEvent;
|
|
545
|
-
}
|
|
546
|
-
yield {
|
|
547
|
-
type: "reasoning-delta",
|
|
548
|
-
text: summaryText
|
|
549
|
-
};
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
const encryptedContent = typeof event.item.encrypted_content === "string" && event.item.encrypted_content.length > 0 ? event.item.encrypted_content : void 0;
|
|
553
|
-
if (encryptedContent) {
|
|
554
|
-
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
555
|
-
if (reasoningStartEvent) {
|
|
556
|
-
yield* closeText();
|
|
557
|
-
yield reasoningStartEvent;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
const reasoningEndEvent2 = getNextReasoningEndEvent({
|
|
561
|
-
openai: {
|
|
562
|
-
...encryptedContent ? { encryptedContent } : {}
|
|
563
|
-
}
|
|
564
|
-
});
|
|
565
|
-
if (reasoningEndEvent2) {
|
|
566
|
-
yield reasoningEndEvent2;
|
|
567
|
-
}
|
|
568
|
-
continue;
|
|
569
|
-
}
|
|
570
|
-
if (!isFunctionToolCall(event.item)) {
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
yield* closeText();
|
|
574
|
-
const toolCallId = event.item.call_id;
|
|
575
|
-
const toolCallName = event.item.name;
|
|
576
|
-
const toolCallArguments = event.item.arguments;
|
|
577
|
-
const currentToolCall = upsertBufferedToolCall(
|
|
578
|
-
event.output_index,
|
|
579
|
-
(bufferedToolCall) => ({
|
|
580
|
-
id: toolCallId,
|
|
581
|
-
name: toolCallName,
|
|
582
|
-
arguments: toolCallArguments || bufferedToolCall?.arguments || ""
|
|
583
|
-
})
|
|
584
|
-
);
|
|
585
|
-
if (!emittedToolCalls.has(currentToolCall.id)) {
|
|
586
|
-
emittedToolCalls.add(currentToolCall.id);
|
|
587
|
-
yield {
|
|
588
|
-
type: "tool-call-end",
|
|
589
|
-
toolCall: {
|
|
590
|
-
id: currentToolCall.id,
|
|
591
|
-
name: currentToolCall.name,
|
|
592
|
-
arguments: safeParseJsonObject(
|
|
593
|
-
currentToolCall.arguments
|
|
594
|
-
)
|
|
595
|
-
}
|
|
596
|
-
};
|
|
597
|
-
}
|
|
598
|
-
continue;
|
|
599
|
-
}
|
|
600
|
-
if (event.type === "response.completed") {
|
|
601
|
-
latestResponse = event.response;
|
|
602
|
-
yield* closeText();
|
|
603
|
-
const reasoningEndEvent2 = getNextReasoningEndEvent({ openai: {} });
|
|
604
|
-
if (reasoningEndEvent2) {
|
|
605
|
-
yield reasoningEndEvent2;
|
|
606
|
-
}
|
|
607
|
-
for (const bufferedToolCall of bufferedToolCalls.values()) {
|
|
608
|
-
if (emittedToolCalls.has(bufferedToolCall.id)) {
|
|
609
|
-
continue;
|
|
610
|
-
}
|
|
611
|
-
emittedToolCalls.add(bufferedToolCall.id);
|
|
612
|
-
yield {
|
|
613
|
-
type: "tool-call-end",
|
|
614
|
-
toolCall: {
|
|
615
|
-
id: bufferedToolCall.id,
|
|
616
|
-
name: bufferedToolCall.name,
|
|
617
|
-
arguments: safeParseJsonObject(
|
|
618
|
-
bufferedToolCall.arguments
|
|
619
|
-
)
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
}
|
|
623
|
-
const hasToolCalls2 = bufferedToolCalls.size > 0;
|
|
624
|
-
yield {
|
|
625
|
-
type: "finish",
|
|
626
|
-
finishReason: mapFinishReason(latestResponse, hasToolCalls2),
|
|
627
|
-
usage: mapUsage(latestResponse.usage)
|
|
628
|
-
};
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
const reasoningEndEvent = getNextReasoningEndEvent({
|
|
633
|
-
openai: {}
|
|
634
|
-
});
|
|
635
|
-
yield* closeText();
|
|
636
|
-
if (reasoningEndEvent) {
|
|
637
|
-
yield reasoningEndEvent;
|
|
638
|
-
}
|
|
639
|
-
const hasToolCalls = bufferedToolCalls.size > 0;
|
|
640
|
-
const usage = latestResponse ? mapUsage(latestResponse.usage) : mapUsage(void 0);
|
|
641
|
-
const finishReason = latestResponse ? mapFinishReason(latestResponse, hasToolCalls) : "unknown";
|
|
642
|
-
yield {
|
|
643
|
-
type: "finish",
|
|
644
|
-
finishReason,
|
|
645
|
-
usage
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
function mapReasoningToRequestFields(modelId, options) {
|
|
649
|
-
if (!options.reasoning) {
|
|
650
|
-
return {};
|
|
651
|
-
}
|
|
652
|
-
const capabilities = getOpenAIModelCapabilities(modelId);
|
|
653
|
-
if (!capabilities.reasoning.supported) {
|
|
654
|
-
return {};
|
|
655
|
-
}
|
|
656
|
-
const effort = toOpenAIReasoningEffort(
|
|
657
|
-
clampReasoningEffort(
|
|
658
|
-
options.reasoning.effort,
|
|
659
|
-
capabilities.reasoning.supportedEfforts
|
|
660
|
-
)
|
|
661
|
-
);
|
|
662
|
-
return {
|
|
663
|
-
reasoning: {
|
|
664
|
-
effort,
|
|
665
|
-
summary: "auto"
|
|
666
|
-
}
|
|
667
|
-
};
|
|
668
|
-
}
|
|
669
|
-
function isFunctionToolCall(item) {
|
|
670
|
-
return item.type === "function_call";
|
|
671
|
-
}
|
|
672
|
-
function isOutputMessage(item) {
|
|
673
|
-
return item.type === "message";
|
|
674
|
-
}
|
|
675
|
-
function isReasoningItem(item) {
|
|
676
|
-
return item.type === "reasoning";
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// src/chat-model.ts
|
|
680
|
-
function createOpenAIChatModel(client, modelId) {
|
|
681
|
-
const provider = "openai";
|
|
682
|
-
async function callOpenAIResponsesApi(request, signal) {
|
|
683
|
-
try {
|
|
684
|
-
return await client.responses.create(request, {
|
|
685
|
-
signal
|
|
686
|
-
});
|
|
687
|
-
} catch (error) {
|
|
688
|
-
throw wrapOpenAIError(error);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
async function generateChat(options) {
|
|
692
|
-
const request = createGenerateRequest(modelId, options);
|
|
693
|
-
const response = await callOpenAIResponsesApi(
|
|
694
|
-
request,
|
|
695
|
-
options.signal
|
|
696
|
-
);
|
|
697
|
-
return mapGenerateResponse(response);
|
|
698
|
-
}
|
|
699
|
-
async function streamChat(options) {
|
|
700
|
-
const request = createStreamRequest(modelId, options);
|
|
701
|
-
return createChatStream(
|
|
702
|
-
async () => transformStream(
|
|
703
|
-
await callOpenAIResponsesApi(request, options.signal)
|
|
704
|
-
),
|
|
705
|
-
{ signal: options.signal }
|
|
706
|
-
);
|
|
707
|
-
}
|
|
708
|
-
return {
|
|
709
|
-
provider,
|
|
710
|
-
modelId,
|
|
711
|
-
capabilities: getOpenAIModelCapabilities(modelId),
|
|
712
|
-
generate: generateChat,
|
|
713
|
-
stream: streamChat,
|
|
714
|
-
async generateObject(options) {
|
|
715
|
-
const structuredOptions = createStructuredOutputOptions(options);
|
|
716
|
-
const result = await generateChat(structuredOptions);
|
|
717
|
-
const toolName = getStructuredOutputToolName(options);
|
|
718
|
-
const object = extractStructuredObject(
|
|
719
|
-
result,
|
|
720
|
-
options.schema,
|
|
721
|
-
provider,
|
|
722
|
-
toolName
|
|
723
|
-
);
|
|
724
|
-
return {
|
|
725
|
-
object,
|
|
726
|
-
finishReason: result.finishReason,
|
|
727
|
-
usage: result.usage
|
|
728
|
-
};
|
|
729
|
-
},
|
|
730
|
-
async streamObject(options) {
|
|
731
|
-
const structuredOptions = createStructuredOutputOptions(options);
|
|
732
|
-
const stream = await streamChat(structuredOptions);
|
|
733
|
-
const toolName = getStructuredOutputToolName(options);
|
|
734
|
-
return createObjectStream(
|
|
735
|
-
transformStructuredOutputStream(
|
|
736
|
-
stream,
|
|
737
|
-
options.schema,
|
|
738
|
-
provider,
|
|
739
|
-
toolName
|
|
740
|
-
),
|
|
741
|
-
{
|
|
742
|
-
signal: options.signal
|
|
743
|
-
}
|
|
744
|
-
);
|
|
745
|
-
}
|
|
746
|
-
};
|
|
747
|
-
}
|
|
11
|
+
openaiResponsesProviderOptionsSchema
|
|
12
|
+
} from "./chunk-YORO2XQ3.js";
|
|
748
13
|
|
|
749
14
|
// src/provider.ts
|
|
750
15
|
function createOpenAI(options = {}) {
|
|
751
|
-
return createOpenAIProvider(options
|
|
16
|
+
return createOpenAIProvider(options);
|
|
752
17
|
}
|
|
753
18
|
export {
|
|
754
19
|
createOpenAI,
|
|
20
|
+
createOpenAIChatCompletionsModel,
|
|
21
|
+
createOpenAIProvider,
|
|
755
22
|
getOpenAIModelCapabilities,
|
|
23
|
+
openaiChatGenerateProviderOptionsSchema,
|
|
756
24
|
openaiCompatGenerateProviderOptionsSchema,
|
|
757
25
|
openaiCompatProviderOptionsSchema,
|
|
758
26
|
openaiEmbedProviderOptionsSchema,
|