@core-ai/openai 0.7.0 → 0.7.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.
|
@@ -29,37 +29,43 @@ var openaiImageProviderOptionsSchema = z.object({
|
|
|
29
29
|
style: z.enum(["vivid", "natural"]).optional(),
|
|
30
30
|
user: z.string().optional()
|
|
31
31
|
}).strict();
|
|
32
|
-
function
|
|
32
|
+
function parseOpenAIProviderOptions(providerOptions, schema) {
|
|
33
33
|
const rawOptions = providerOptions?.openai;
|
|
34
34
|
if (rawOptions === void 0) {
|
|
35
35
|
return void 0;
|
|
36
36
|
}
|
|
37
|
-
return
|
|
37
|
+
return schema.parse(rawOptions);
|
|
38
|
+
}
|
|
39
|
+
function parseOpenAIResponsesGenerateProviderOptions(providerOptions) {
|
|
40
|
+
return parseOpenAIProviderOptions(
|
|
41
|
+
providerOptions,
|
|
42
|
+
openaiResponsesGenerateProviderOptionsSchema
|
|
43
|
+
);
|
|
38
44
|
}
|
|
39
45
|
function parseOpenAICompatGenerateProviderOptions(providerOptions) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return openaiCompatGenerateProviderOptionsSchema.parse(rawOptions);
|
|
46
|
+
return parseOpenAIProviderOptions(
|
|
47
|
+
providerOptions,
|
|
48
|
+
openaiCompatGenerateProviderOptionsSchema
|
|
49
|
+
);
|
|
45
50
|
}
|
|
46
51
|
function parseOpenAIEmbedProviderOptions(providerOptions) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return openaiEmbedProviderOptionsSchema.parse(rawOptions);
|
|
52
|
+
return parseOpenAIProviderOptions(
|
|
53
|
+
providerOptions,
|
|
54
|
+
openaiEmbedProviderOptionsSchema
|
|
55
|
+
);
|
|
52
56
|
}
|
|
53
57
|
function parseOpenAIImageProviderOptions(providerOptions) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return openaiImageProviderOptionsSchema.parse(rawOptions);
|
|
58
|
+
return parseOpenAIProviderOptions(
|
|
59
|
+
providerOptions,
|
|
60
|
+
openaiImageProviderOptionsSchema
|
|
61
|
+
);
|
|
59
62
|
}
|
|
60
63
|
var openaiResponsesProviderOptionsSchema = openaiResponsesGenerateProviderOptionsSchema;
|
|
61
64
|
var openaiCompatProviderOptionsSchema = openaiCompatGenerateProviderOptionsSchema;
|
|
62
65
|
|
|
66
|
+
// src/shared/provider-factory.ts
|
|
67
|
+
import OpenAI from "openai";
|
|
68
|
+
|
|
63
69
|
// src/openai-error.ts
|
|
64
70
|
import { APIError } from "openai";
|
|
65
71
|
import { ProviderError } from "@core-ai/core-ai";
|
|
@@ -160,6 +166,19 @@ function mapOpenAIImageProviderOptionsToRequestFields(options) {
|
|
|
160
166
|
};
|
|
161
167
|
}
|
|
162
168
|
|
|
169
|
+
// src/shared/provider-factory.ts
|
|
170
|
+
function createOpenAIProvider(options, createChatModel) {
|
|
171
|
+
const client = options.client ?? new OpenAI({
|
|
172
|
+
apiKey: options.apiKey,
|
|
173
|
+
baseURL: options.baseURL
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
chatModel: (modelId) => createChatModel(client, modelId),
|
|
177
|
+
embeddingModel: (modelId) => createOpenAIEmbeddingModel(client, modelId),
|
|
178
|
+
imageModel: (modelId) => createOpenAIImageModel(client, modelId)
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
|
|
163
182
|
// src/shared/tools.ts
|
|
164
183
|
import { zodSchemaToJsonSchema } from "@core-ai/core-ai";
|
|
165
184
|
var DEFAULT_STRUCTURED_OUTPUT_TOOL_NAME = "core_ai_generate_object";
|
|
@@ -212,7 +231,168 @@ function createStructuredOutputOptions(options) {
|
|
|
212
231
|
};
|
|
213
232
|
}
|
|
214
233
|
|
|
234
|
+
// src/shared/structured-output.ts
|
|
235
|
+
import {
|
|
236
|
+
StructuredOutputNoObjectGeneratedError,
|
|
237
|
+
StructuredOutputParseError,
|
|
238
|
+
StructuredOutputValidationError
|
|
239
|
+
} from "@core-ai/core-ai";
|
|
240
|
+
function extractStructuredObject(result, schema, provider, toolName) {
|
|
241
|
+
const structuredToolCall = result.toolCalls.find(
|
|
242
|
+
(toolCall) => toolCall.name === toolName
|
|
243
|
+
);
|
|
244
|
+
if (structuredToolCall) {
|
|
245
|
+
return validateStructuredToolArguments(
|
|
246
|
+
schema,
|
|
247
|
+
structuredToolCall.arguments,
|
|
248
|
+
provider
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
const rawOutput = result.content?.trim();
|
|
252
|
+
if (rawOutput && rawOutput.length > 0) {
|
|
253
|
+
return parseAndValidateStructuredPayload(schema, rawOutput, provider);
|
|
254
|
+
}
|
|
255
|
+
throw new StructuredOutputNoObjectGeneratedError(
|
|
256
|
+
"model did not emit a structured object payload",
|
|
257
|
+
provider
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
async function* transformStructuredOutputStream(stream, schema, provider, toolName) {
|
|
261
|
+
let validatedObject;
|
|
262
|
+
let contentBuffer = "";
|
|
263
|
+
const toolArgumentDeltas = /* @__PURE__ */ new Map();
|
|
264
|
+
for await (const event of stream) {
|
|
265
|
+
if (event.type === "text-delta") {
|
|
266
|
+
contentBuffer += event.text;
|
|
267
|
+
yield {
|
|
268
|
+
type: "object-delta",
|
|
269
|
+
text: event.text
|
|
270
|
+
};
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (event.type === "tool-call-delta") {
|
|
274
|
+
const previous = toolArgumentDeltas.get(event.toolCallId) ?? "";
|
|
275
|
+
toolArgumentDeltas.set(
|
|
276
|
+
event.toolCallId,
|
|
277
|
+
`${previous}${event.argumentsDelta}`
|
|
278
|
+
);
|
|
279
|
+
yield {
|
|
280
|
+
type: "object-delta",
|
|
281
|
+
text: event.argumentsDelta
|
|
282
|
+
};
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
if (event.type === "tool-call-end" && event.toolCall.name === toolName) {
|
|
286
|
+
validatedObject = validateStructuredToolArguments(
|
|
287
|
+
schema,
|
|
288
|
+
event.toolCall.arguments,
|
|
289
|
+
provider
|
|
290
|
+
);
|
|
291
|
+
yield {
|
|
292
|
+
type: "object",
|
|
293
|
+
object: validatedObject
|
|
294
|
+
};
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
if (event.type === "finish") {
|
|
298
|
+
if (validatedObject === void 0) {
|
|
299
|
+
const fallbackPayload = getFallbackStructuredPayload(
|
|
300
|
+
contentBuffer,
|
|
301
|
+
toolArgumentDeltas
|
|
302
|
+
);
|
|
303
|
+
if (!fallbackPayload) {
|
|
304
|
+
throw new StructuredOutputNoObjectGeneratedError(
|
|
305
|
+
"structured output stream ended without an object payload",
|
|
306
|
+
provider
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
validatedObject = parseAndValidateStructuredPayload(
|
|
310
|
+
schema,
|
|
311
|
+
fallbackPayload,
|
|
312
|
+
provider
|
|
313
|
+
);
|
|
314
|
+
yield {
|
|
315
|
+
type: "object",
|
|
316
|
+
object: validatedObject
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
yield {
|
|
320
|
+
type: "finish",
|
|
321
|
+
finishReason: event.finishReason,
|
|
322
|
+
usage: event.usage
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function getFallbackStructuredPayload(contentBuffer, toolArgumentDeltas) {
|
|
328
|
+
for (const delta of toolArgumentDeltas.values()) {
|
|
329
|
+
const trimmed = delta.trim();
|
|
330
|
+
if (trimmed.length > 0) {
|
|
331
|
+
return trimmed;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
const trimmedContent = contentBuffer.trim();
|
|
335
|
+
if (trimmedContent.length > 0) {
|
|
336
|
+
return trimmedContent;
|
|
337
|
+
}
|
|
338
|
+
return void 0;
|
|
339
|
+
}
|
|
340
|
+
function validateStructuredToolArguments(schema, toolArguments, provider) {
|
|
341
|
+
return validateStructuredObject(
|
|
342
|
+
schema,
|
|
343
|
+
toolArguments,
|
|
344
|
+
provider,
|
|
345
|
+
JSON.stringify(toolArguments)
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
function parseAndValidateStructuredPayload(schema, rawPayload, provider) {
|
|
349
|
+
const parsedPayload = parseJson(rawPayload, provider);
|
|
350
|
+
return validateStructuredObject(
|
|
351
|
+
schema,
|
|
352
|
+
parsedPayload,
|
|
353
|
+
provider,
|
|
354
|
+
rawPayload
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
function parseJson(rawOutput, provider) {
|
|
358
|
+
try {
|
|
359
|
+
return JSON.parse(rawOutput);
|
|
360
|
+
} catch (error) {
|
|
361
|
+
throw new StructuredOutputParseError(
|
|
362
|
+
"failed to parse structured output as JSON",
|
|
363
|
+
provider,
|
|
364
|
+
{
|
|
365
|
+
rawOutput,
|
|
366
|
+
cause: error
|
|
367
|
+
}
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function validateStructuredObject(schema, value, provider, rawOutput) {
|
|
372
|
+
const parsed = schema.safeParse(value);
|
|
373
|
+
if (parsed.success) {
|
|
374
|
+
return parsed.data;
|
|
375
|
+
}
|
|
376
|
+
throw new StructuredOutputValidationError(
|
|
377
|
+
"structured output does not match schema",
|
|
378
|
+
provider,
|
|
379
|
+
formatZodIssues(parsed.error.issues),
|
|
380
|
+
{
|
|
381
|
+
rawOutput
|
|
382
|
+
}
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
function formatZodIssues(issues) {
|
|
386
|
+
return issues.map((issue) => {
|
|
387
|
+
const path = issue.path.length > 0 ? issue.path.map((segment) => String(segment)).join(".") : "<root>";
|
|
388
|
+
return `${path}: ${issue.message}`;
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
215
392
|
// src/model-capabilities.ts
|
|
393
|
+
import {
|
|
394
|
+
stripModelDateSuffix
|
|
395
|
+
} from "@core-ai/core-ai";
|
|
216
396
|
var DEFAULT_CAPABILITIES = {
|
|
217
397
|
reasoning: {
|
|
218
398
|
supportsEffort: true,
|
|
@@ -220,42 +400,33 @@ var DEFAULT_CAPABILITIES = {
|
|
|
220
400
|
restrictsSamplingParams: false
|
|
221
401
|
}
|
|
222
402
|
};
|
|
403
|
+
var GPT_5_MAX_REASONING_CAPABILITIES = {
|
|
404
|
+
reasoning: {
|
|
405
|
+
supportsEffort: true,
|
|
406
|
+
supportedRange: ["low", "medium", "high", "max"],
|
|
407
|
+
restrictsSamplingParams: true
|
|
408
|
+
}
|
|
409
|
+
};
|
|
410
|
+
var GPT_5_MINIMAL_REASONING_CAPABILITIES = {
|
|
411
|
+
reasoning: {
|
|
412
|
+
supportsEffort: true,
|
|
413
|
+
supportedRange: ["minimal", "low", "medium", "high"],
|
|
414
|
+
restrictsSamplingParams: true
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
var NO_REASONING_EFFORT_CAPABILITIES = {
|
|
418
|
+
reasoning: {
|
|
419
|
+
supportsEffort: false,
|
|
420
|
+
supportedRange: [],
|
|
421
|
+
restrictsSamplingParams: false
|
|
422
|
+
}
|
|
423
|
+
};
|
|
223
424
|
var MODEL_CAPABILITIES = {
|
|
224
|
-
"gpt-5.4":
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
},
|
|
231
|
-
"gpt-5.4-pro": {
|
|
232
|
-
reasoning: {
|
|
233
|
-
supportsEffort: true,
|
|
234
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
235
|
-
restrictsSamplingParams: true
|
|
236
|
-
}
|
|
237
|
-
},
|
|
238
|
-
"gpt-5.2": {
|
|
239
|
-
reasoning: {
|
|
240
|
-
supportsEffort: true,
|
|
241
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
242
|
-
restrictsSamplingParams: true
|
|
243
|
-
}
|
|
244
|
-
},
|
|
245
|
-
"gpt-5.2-codex": {
|
|
246
|
-
reasoning: {
|
|
247
|
-
supportsEffort: true,
|
|
248
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
249
|
-
restrictsSamplingParams: true
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
"gpt-5.2-pro": {
|
|
253
|
-
reasoning: {
|
|
254
|
-
supportsEffort: true,
|
|
255
|
-
supportedRange: ["low", "medium", "high", "max"],
|
|
256
|
-
restrictsSamplingParams: true
|
|
257
|
-
}
|
|
258
|
-
},
|
|
425
|
+
"gpt-5.4": GPT_5_MAX_REASONING_CAPABILITIES,
|
|
426
|
+
"gpt-5.4-pro": GPT_5_MAX_REASONING_CAPABILITIES,
|
|
427
|
+
"gpt-5.2": GPT_5_MAX_REASONING_CAPABILITIES,
|
|
428
|
+
"gpt-5.2-codex": GPT_5_MAX_REASONING_CAPABILITIES,
|
|
429
|
+
"gpt-5.2-pro": GPT_5_MAX_REASONING_CAPABILITIES,
|
|
259
430
|
"gpt-5.1": {
|
|
260
431
|
reasoning: {
|
|
261
432
|
supportsEffort: true,
|
|
@@ -263,27 +434,9 @@ var MODEL_CAPABILITIES = {
|
|
|
263
434
|
restrictsSamplingParams: true
|
|
264
435
|
}
|
|
265
436
|
},
|
|
266
|
-
"gpt-5":
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
270
|
-
restrictsSamplingParams: true
|
|
271
|
-
}
|
|
272
|
-
},
|
|
273
|
-
"gpt-5-mini": {
|
|
274
|
-
reasoning: {
|
|
275
|
-
supportsEffort: true,
|
|
276
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
277
|
-
restrictsSamplingParams: true
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
"gpt-5-nano": {
|
|
281
|
-
reasoning: {
|
|
282
|
-
supportsEffort: true,
|
|
283
|
-
supportedRange: ["minimal", "low", "medium", "high"],
|
|
284
|
-
restrictsSamplingParams: true
|
|
285
|
-
}
|
|
286
|
-
},
|
|
437
|
+
"gpt-5": GPT_5_MINIMAL_REASONING_CAPABILITIES,
|
|
438
|
+
"gpt-5-mini": GPT_5_MINIMAL_REASONING_CAPABILITIES,
|
|
439
|
+
"gpt-5-nano": GPT_5_MINIMAL_REASONING_CAPABILITIES,
|
|
287
440
|
o3: {
|
|
288
441
|
reasoning: {
|
|
289
442
|
supportsEffort: true,
|
|
@@ -312,13 +465,7 @@ var MODEL_CAPABILITIES = {
|
|
|
312
465
|
restrictsSamplingParams: false
|
|
313
466
|
}
|
|
314
467
|
},
|
|
315
|
-
"o1-mini":
|
|
316
|
-
reasoning: {
|
|
317
|
-
supportsEffort: false,
|
|
318
|
-
supportedRange: [],
|
|
319
|
-
restrictsSamplingParams: false
|
|
320
|
-
}
|
|
321
|
-
}
|
|
468
|
+
"o1-mini": NO_REASONING_EFFORT_CAPABILITIES
|
|
322
469
|
};
|
|
323
470
|
var EFFORT_RANK = {
|
|
324
471
|
minimal: 0,
|
|
@@ -327,12 +474,19 @@ var EFFORT_RANK = {
|
|
|
327
474
|
high: 3,
|
|
328
475
|
max: 4
|
|
329
476
|
};
|
|
477
|
+
var OPENAI_REASONING_EFFORT_MAP = {
|
|
478
|
+
minimal: "minimal",
|
|
479
|
+
low: "low",
|
|
480
|
+
medium: "medium",
|
|
481
|
+
high: "high",
|
|
482
|
+
max: "xhigh"
|
|
483
|
+
};
|
|
330
484
|
function getOpenAIModelCapabilities(modelId) {
|
|
331
485
|
const normalizedModelId = normalizeModelId(modelId);
|
|
332
486
|
return MODEL_CAPABILITIES[normalizedModelId] ?? DEFAULT_CAPABILITIES;
|
|
333
487
|
}
|
|
334
488
|
function normalizeModelId(modelId) {
|
|
335
|
-
return modelId
|
|
489
|
+
return stripModelDateSuffix(modelId);
|
|
336
490
|
}
|
|
337
491
|
function clampReasoningEffort(effort, supportedRange) {
|
|
338
492
|
if (supportedRange.length === 0 || supportedRange.includes(effort)) {
|
|
@@ -351,10 +505,7 @@ function clampReasoningEffort(effort, supportedRange) {
|
|
|
351
505
|
return best;
|
|
352
506
|
}
|
|
353
507
|
function toOpenAIReasoningEffort(effort) {
|
|
354
|
-
|
|
355
|
-
return "xhigh";
|
|
356
|
-
}
|
|
357
|
-
return effort;
|
|
508
|
+
return OPENAI_REASONING_EFFORT_MAP[effort];
|
|
358
509
|
}
|
|
359
510
|
|
|
360
511
|
// src/shared/utils.ts
|
|
@@ -378,15 +529,16 @@ function validateOpenAIReasoningConfig(modelId, options) {
|
|
|
378
529
|
if (!capabilities.reasoning.restrictsSamplingParams) {
|
|
379
530
|
return;
|
|
380
531
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
532
|
+
const restrictedSamplingParams = [
|
|
533
|
+
{ name: "temperature", value: options.temperature },
|
|
534
|
+
{ name: "topP", value: options.topP }
|
|
535
|
+
];
|
|
536
|
+
for (const { name, value } of restrictedSamplingParams) {
|
|
537
|
+
if (value === void 0) {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
388
540
|
throw new ProviderError2(
|
|
389
|
-
`OpenAI model "${modelId}" does not support
|
|
541
|
+
`OpenAI model "${modelId}" does not support ${name} when reasoning is enabled`,
|
|
390
542
|
"openai"
|
|
391
543
|
);
|
|
392
544
|
}
|
|
@@ -411,6 +563,7 @@ export {
|
|
|
411
563
|
openaiResponsesProviderOptionsSchema,
|
|
412
564
|
openaiCompatProviderOptionsSchema,
|
|
413
565
|
wrapOpenAIError,
|
|
414
|
-
|
|
415
|
-
|
|
566
|
+
extractStructuredObject,
|
|
567
|
+
transformStructuredOutputStream,
|
|
568
|
+
createOpenAIProvider
|
|
416
569
|
};
|
package/dist/compat.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { O as OpenAIProvider, a as OpenAIProviderBaseOptions } from './provider-options-DzqvHoId.js';
|
|
2
|
+
export { b as OpenAICompatGenerateProviderOptions, c as OpenAICompatRequestOptions, o as openaiCompatGenerateProviderOptionsSchema, d as openaiCompatProviderOptionsSchema } from './provider-options-DzqvHoId.js';
|
|
3
|
+
import 'openai';
|
|
4
|
+
import '@core-ai/core-ai';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
6
|
-
type OpenAICompatProviderOptions =
|
|
7
|
-
|
|
8
|
-
baseURL?: string;
|
|
9
|
-
client?: OpenAI;
|
|
10
|
-
};
|
|
11
|
-
type OpenAICompatProvider = {
|
|
12
|
-
chatModel(modelId: string): ChatModel;
|
|
13
|
-
embeddingModel(modelId: string): EmbeddingModel;
|
|
14
|
-
imageModel(modelId: string): ImageModel;
|
|
15
|
-
};
|
|
7
|
+
type OpenAICompatProviderOptions = OpenAIProviderBaseOptions;
|
|
8
|
+
type OpenAICompatProvider = OpenAIProvider;
|
|
16
9
|
declare function createOpenAICompat(options?: OpenAICompatProviderOptions): OpenAICompatProvider;
|
|
17
10
|
|
|
18
11
|
export { type OpenAICompatProvider, type OpenAICompatProviderOptions, createOpenAICompat };
|
package/dist/compat.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
clampReasoningEffort,
|
|
3
3
|
convertToolChoice,
|
|
4
4
|
convertTools,
|
|
5
|
-
|
|
6
|
-
createOpenAIImageModel,
|
|
5
|
+
createOpenAIProvider,
|
|
7
6
|
createStructuredOutputOptions,
|
|
7
|
+
extractStructuredObject,
|
|
8
8
|
getOpenAIModelCapabilities,
|
|
9
9
|
getStructuredOutputToolName,
|
|
10
10
|
openaiCompatGenerateProviderOptionsSchema,
|
|
@@ -12,21 +12,13 @@ import {
|
|
|
12
12
|
parseOpenAICompatGenerateProviderOptions,
|
|
13
13
|
safeParseJsonObject,
|
|
14
14
|
toOpenAIReasoningEffort,
|
|
15
|
+
transformStructuredOutputStream,
|
|
15
16
|
validateOpenAIReasoningConfig,
|
|
16
17
|
wrapOpenAIError
|
|
17
|
-
} from "./chunk-
|
|
18
|
-
|
|
19
|
-
// src/compat/provider.ts
|
|
20
|
-
import OpenAI from "openai";
|
|
18
|
+
} from "./chunk-AHJSL5X4.js";
|
|
21
19
|
|
|
22
20
|
// src/compat/chat-model.ts
|
|
23
|
-
import {
|
|
24
|
-
StructuredOutputNoObjectGeneratedError,
|
|
25
|
-
StructuredOutputParseError,
|
|
26
|
-
StructuredOutputValidationError,
|
|
27
|
-
createObjectStream,
|
|
28
|
-
createChatStream
|
|
29
|
-
} from "@core-ai/core-ai";
|
|
21
|
+
import { createObjectStream, createChatStream } from "@core-ai/core-ai";
|
|
30
22
|
|
|
31
23
|
// src/compat/chat-adapter.ts
|
|
32
24
|
function convertMessages(messages) {
|
|
@@ -441,169 +433,10 @@ function createOpenAICompatChatModel(client, modelId) {
|
|
|
441
433
|
}
|
|
442
434
|
};
|
|
443
435
|
}
|
|
444
|
-
function extractStructuredObject(result, schema, provider, toolName) {
|
|
445
|
-
const structuredToolCall = result.toolCalls.find(
|
|
446
|
-
(toolCall) => toolCall.name === toolName
|
|
447
|
-
);
|
|
448
|
-
if (structuredToolCall) {
|
|
449
|
-
return validateStructuredToolArguments(
|
|
450
|
-
schema,
|
|
451
|
-
structuredToolCall.arguments,
|
|
452
|
-
provider
|
|
453
|
-
);
|
|
454
|
-
}
|
|
455
|
-
const rawOutput = result.content?.trim();
|
|
456
|
-
if (rawOutput && rawOutput.length > 0) {
|
|
457
|
-
return parseAndValidateStructuredPayload(schema, rawOutput, provider);
|
|
458
|
-
}
|
|
459
|
-
throw new StructuredOutputNoObjectGeneratedError(
|
|
460
|
-
"model did not emit a structured object payload",
|
|
461
|
-
provider
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
async function* transformStructuredOutputStream(stream, schema, provider, toolName) {
|
|
465
|
-
let validatedObject;
|
|
466
|
-
let contentBuffer = "";
|
|
467
|
-
const toolArgumentDeltas = /* @__PURE__ */ new Map();
|
|
468
|
-
for await (const event of stream) {
|
|
469
|
-
if (event.type === "text-delta") {
|
|
470
|
-
contentBuffer += event.text;
|
|
471
|
-
yield {
|
|
472
|
-
type: "object-delta",
|
|
473
|
-
text: event.text
|
|
474
|
-
};
|
|
475
|
-
continue;
|
|
476
|
-
}
|
|
477
|
-
if (event.type === "tool-call-delta") {
|
|
478
|
-
const previous = toolArgumentDeltas.get(event.toolCallId) ?? "";
|
|
479
|
-
toolArgumentDeltas.set(
|
|
480
|
-
event.toolCallId,
|
|
481
|
-
`${previous}${event.argumentsDelta}`
|
|
482
|
-
);
|
|
483
|
-
yield {
|
|
484
|
-
type: "object-delta",
|
|
485
|
-
text: event.argumentsDelta
|
|
486
|
-
};
|
|
487
|
-
continue;
|
|
488
|
-
}
|
|
489
|
-
if (event.type === "tool-call-end" && event.toolCall.name === toolName) {
|
|
490
|
-
validatedObject = validateStructuredToolArguments(
|
|
491
|
-
schema,
|
|
492
|
-
event.toolCall.arguments,
|
|
493
|
-
provider
|
|
494
|
-
);
|
|
495
|
-
yield {
|
|
496
|
-
type: "object",
|
|
497
|
-
object: validatedObject
|
|
498
|
-
};
|
|
499
|
-
continue;
|
|
500
|
-
}
|
|
501
|
-
if (event.type === "finish") {
|
|
502
|
-
if (validatedObject === void 0) {
|
|
503
|
-
const fallbackPayload = getFallbackStructuredPayload(
|
|
504
|
-
contentBuffer,
|
|
505
|
-
toolArgumentDeltas
|
|
506
|
-
);
|
|
507
|
-
if (!fallbackPayload) {
|
|
508
|
-
throw new StructuredOutputNoObjectGeneratedError(
|
|
509
|
-
"structured output stream ended without an object payload",
|
|
510
|
-
provider
|
|
511
|
-
);
|
|
512
|
-
}
|
|
513
|
-
validatedObject = parseAndValidateStructuredPayload(
|
|
514
|
-
schema,
|
|
515
|
-
fallbackPayload,
|
|
516
|
-
provider
|
|
517
|
-
);
|
|
518
|
-
yield {
|
|
519
|
-
type: "object",
|
|
520
|
-
object: validatedObject
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
yield {
|
|
524
|
-
type: "finish",
|
|
525
|
-
finishReason: event.finishReason,
|
|
526
|
-
usage: event.usage
|
|
527
|
-
};
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
function getFallbackStructuredPayload(contentBuffer, toolArgumentDeltas) {
|
|
532
|
-
for (const delta of toolArgumentDeltas.values()) {
|
|
533
|
-
const trimmed = delta.trim();
|
|
534
|
-
if (trimmed.length > 0) {
|
|
535
|
-
return trimmed;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
const trimmedContent = contentBuffer.trim();
|
|
539
|
-
if (trimmedContent.length > 0) {
|
|
540
|
-
return trimmedContent;
|
|
541
|
-
}
|
|
542
|
-
return void 0;
|
|
543
|
-
}
|
|
544
|
-
function validateStructuredToolArguments(schema, toolArguments, provider) {
|
|
545
|
-
return validateStructuredObject(
|
|
546
|
-
schema,
|
|
547
|
-
toolArguments,
|
|
548
|
-
provider,
|
|
549
|
-
JSON.stringify(toolArguments)
|
|
550
|
-
);
|
|
551
|
-
}
|
|
552
|
-
function parseAndValidateStructuredPayload(schema, rawPayload, provider) {
|
|
553
|
-
const parsedPayload = parseJson(rawPayload, provider);
|
|
554
|
-
return validateStructuredObject(
|
|
555
|
-
schema,
|
|
556
|
-
parsedPayload,
|
|
557
|
-
provider,
|
|
558
|
-
rawPayload
|
|
559
|
-
);
|
|
560
|
-
}
|
|
561
|
-
function parseJson(rawOutput, provider) {
|
|
562
|
-
try {
|
|
563
|
-
return JSON.parse(rawOutput);
|
|
564
|
-
} catch (error) {
|
|
565
|
-
throw new StructuredOutputParseError(
|
|
566
|
-
"failed to parse structured output as JSON",
|
|
567
|
-
provider,
|
|
568
|
-
{
|
|
569
|
-
rawOutput,
|
|
570
|
-
cause: error
|
|
571
|
-
}
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
function validateStructuredObject(schema, value, provider, rawOutput) {
|
|
576
|
-
const parsed = schema.safeParse(value);
|
|
577
|
-
if (parsed.success) {
|
|
578
|
-
return parsed.data;
|
|
579
|
-
}
|
|
580
|
-
throw new StructuredOutputValidationError(
|
|
581
|
-
"structured output does not match schema",
|
|
582
|
-
provider,
|
|
583
|
-
formatZodIssues(parsed.error.issues),
|
|
584
|
-
{
|
|
585
|
-
rawOutput
|
|
586
|
-
}
|
|
587
|
-
);
|
|
588
|
-
}
|
|
589
|
-
function formatZodIssues(issues) {
|
|
590
|
-
return issues.map((issue) => {
|
|
591
|
-
const path = issue.path.length > 0 ? issue.path.map((segment) => String(segment)).join(".") : "<root>";
|
|
592
|
-
return `${path}: ${issue.message}`;
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
436
|
|
|
596
437
|
// src/compat/provider.ts
|
|
597
438
|
function createOpenAICompat(options = {}) {
|
|
598
|
-
|
|
599
|
-
apiKey: options.apiKey,
|
|
600
|
-
baseURL: options.baseURL
|
|
601
|
-
});
|
|
602
|
-
return {
|
|
603
|
-
chatModel: (modelId) => createOpenAICompatChatModel(client, modelId),
|
|
604
|
-
embeddingModel: (modelId) => createOpenAIEmbeddingModel(client, modelId),
|
|
605
|
-
imageModel: (modelId) => createOpenAIImageModel(client, modelId)
|
|
606
|
-
};
|
|
439
|
+
return createOpenAIProvider(options, createOpenAICompatChatModel);
|
|
607
440
|
}
|
|
608
441
|
export {
|
|
609
442
|
createOpenAICompat,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { O as OpenAIProvider$1, a as OpenAIProviderBaseOptions } from './provider-options-DzqvHoId.js';
|
|
2
|
+
export { b as OpenAICompatGenerateProviderOptions, c as OpenAICompatRequestOptions, e as OpenAIEmbedProviderOptions, f as OpenAIImageProviderOptions, g as OpenAIResponsesGenerateProviderOptions, h as OpenAIResponsesProviderOptions, o as openaiCompatGenerateProviderOptionsSchema, d as openaiCompatProviderOptionsSchema, i as openaiEmbedProviderOptionsSchema, j as openaiImageProviderOptionsSchema, k as openaiResponsesGenerateProviderOptionsSchema, l as openaiResponsesProviderOptionsSchema } from './provider-options-DzqvHoId.js';
|
|
3
|
+
import 'openai';
|
|
4
|
+
import '@core-ai/core-ai';
|
|
4
5
|
import 'zod';
|
|
5
6
|
|
|
6
|
-
type OpenAIProviderOptions =
|
|
7
|
-
|
|
8
|
-
baseURL?: string;
|
|
9
|
-
client?: OpenAI;
|
|
10
|
-
};
|
|
11
|
-
type OpenAIProvider = {
|
|
12
|
-
chatModel(modelId: string): ChatModel;
|
|
13
|
-
embeddingModel(modelId: string): EmbeddingModel;
|
|
14
|
-
imageModel(modelId: string): ImageModel;
|
|
15
|
-
};
|
|
7
|
+
type OpenAIProviderOptions = OpenAIProviderBaseOptions;
|
|
8
|
+
type OpenAIProvider = OpenAIProvider$1;
|
|
16
9
|
declare function createOpenAI(options?: OpenAIProviderOptions): OpenAIProvider;
|
|
17
10
|
|
|
18
11
|
type OpenAIReasoningMetadata = {
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import {
|
|
|
2
2
|
clampReasoningEffort,
|
|
3
3
|
convertToolChoice,
|
|
4
4
|
convertTools,
|
|
5
|
-
|
|
6
|
-
createOpenAIImageModel,
|
|
5
|
+
createOpenAIProvider,
|
|
7
6
|
createStructuredOutputOptions,
|
|
7
|
+
extractStructuredObject,
|
|
8
8
|
getOpenAIModelCapabilities,
|
|
9
9
|
getStructuredOutputToolName,
|
|
10
10
|
openaiCompatGenerateProviderOptionsSchema,
|
|
@@ -16,21 +16,13 @@ import {
|
|
|
16
16
|
parseOpenAIResponsesGenerateProviderOptions,
|
|
17
17
|
safeParseJsonObject,
|
|
18
18
|
toOpenAIReasoningEffort,
|
|
19
|
+
transformStructuredOutputStream,
|
|
19
20
|
validateOpenAIReasoningConfig,
|
|
20
21
|
wrapOpenAIError
|
|
21
|
-
} from "./chunk-
|
|
22
|
-
|
|
23
|
-
// src/provider.ts
|
|
24
|
-
import OpenAI from "openai";
|
|
22
|
+
} from "./chunk-AHJSL5X4.js";
|
|
25
23
|
|
|
26
24
|
// src/chat-model.ts
|
|
27
|
-
import {
|
|
28
|
-
StructuredOutputNoObjectGeneratedError,
|
|
29
|
-
StructuredOutputParseError,
|
|
30
|
-
StructuredOutputValidationError,
|
|
31
|
-
createObjectStream,
|
|
32
|
-
createChatStream
|
|
33
|
-
} from "@core-ai/core-ai";
|
|
25
|
+
import { createObjectStream, createChatStream } from "@core-ai/core-ai";
|
|
34
26
|
|
|
35
27
|
// src/chat-adapter.ts
|
|
36
28
|
import { getProviderMetadata } from "@core-ai/core-ai";
|
|
@@ -377,14 +369,26 @@ async function* transformStream(stream) {
|
|
|
377
369
|
bufferedToolCalls.set(outputIndex, nextToolCall);
|
|
378
370
|
return nextToolCall;
|
|
379
371
|
};
|
|
372
|
+
const getNextReasoningStartEvent = () => {
|
|
373
|
+
const transition = getReasoningStartTransition(reasoningStarted);
|
|
374
|
+
reasoningStarted = transition.nextReasoningStarted;
|
|
375
|
+
return transition.event;
|
|
376
|
+
};
|
|
377
|
+
const getNextReasoningEndEvent = (providerMetadata) => {
|
|
378
|
+
const transition = getReasoningEndTransition(
|
|
379
|
+
reasoningStarted,
|
|
380
|
+
providerMetadata
|
|
381
|
+
);
|
|
382
|
+
reasoningStarted = transition.nextReasoningStarted;
|
|
383
|
+
return transition.event;
|
|
384
|
+
};
|
|
380
385
|
for await (const event of stream) {
|
|
381
386
|
if (event.type === "response.reasoning_summary_text.delta") {
|
|
382
387
|
seenSummaryDeltas.add(`${event.item_id}:${event.summary_index}`);
|
|
383
388
|
emittedReasoningItems.add(event.item_id);
|
|
384
|
-
const
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
yield reasoningStartTransition.event;
|
|
389
|
+
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
390
|
+
if (reasoningStartEvent) {
|
|
391
|
+
yield reasoningStartEvent;
|
|
388
392
|
}
|
|
389
393
|
yield {
|
|
390
394
|
type: "reasoning-delta",
|
|
@@ -396,10 +400,9 @@ async function* transformStream(stream) {
|
|
|
396
400
|
const key = `${event.item_id}:${event.summary_index}`;
|
|
397
401
|
if (!seenSummaryDeltas.has(key) && event.text.length > 0) {
|
|
398
402
|
emittedReasoningItems.add(event.item_id);
|
|
399
|
-
const
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
yield reasoningStartTransition.event;
|
|
403
|
+
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
404
|
+
if (reasoningStartEvent) {
|
|
405
|
+
yield reasoningStartEvent;
|
|
403
406
|
}
|
|
404
407
|
yield {
|
|
405
408
|
type: "reasoning-delta",
|
|
@@ -473,10 +476,9 @@ async function* transformStream(stream) {
|
|
|
473
476
|
event.item.summary
|
|
474
477
|
);
|
|
475
478
|
if (summaryText.length > 0) {
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
yield reasoningStartTransition.event;
|
|
479
|
+
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
480
|
+
if (reasoningStartEvent) {
|
|
481
|
+
yield reasoningStartEvent;
|
|
480
482
|
}
|
|
481
483
|
yield {
|
|
482
484
|
type: "reasoning-delta",
|
|
@@ -486,23 +488,20 @@ async function* transformStream(stream) {
|
|
|
486
488
|
}
|
|
487
489
|
const encryptedContent = typeof event.item.encrypted_content === "string" && event.item.encrypted_content.length > 0 ? event.item.encrypted_content : void 0;
|
|
488
490
|
if (encryptedContent) {
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
yield reasoningStartTransition.event;
|
|
491
|
+
const reasoningStartEvent = getNextReasoningStartEvent();
|
|
492
|
+
if (reasoningStartEvent) {
|
|
493
|
+
yield reasoningStartEvent;
|
|
493
494
|
}
|
|
494
495
|
}
|
|
495
|
-
const
|
|
496
|
-
reasoningStarted,
|
|
496
|
+
const reasoningEndEvent2 = getNextReasoningEndEvent(
|
|
497
497
|
{
|
|
498
498
|
openai: {
|
|
499
499
|
...encryptedContent ? { encryptedContent } : {}
|
|
500
500
|
}
|
|
501
501
|
}
|
|
502
502
|
);
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
yield reasoningEndTransition2.event;
|
|
503
|
+
if (reasoningEndEvent2) {
|
|
504
|
+
yield reasoningEndEvent2;
|
|
506
505
|
}
|
|
507
506
|
continue;
|
|
508
507
|
}
|
|
@@ -537,13 +536,9 @@ async function* transformStream(stream) {
|
|
|
537
536
|
}
|
|
538
537
|
if (event.type === "response.completed") {
|
|
539
538
|
latestResponse = event.response;
|
|
540
|
-
const
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
);
|
|
544
|
-
reasoningStarted = reasoningEndTransition2.nextReasoningStarted;
|
|
545
|
-
if (reasoningEndTransition2.event) {
|
|
546
|
-
yield reasoningEndTransition2.event;
|
|
539
|
+
const reasoningEndEvent2 = getNextReasoningEndEvent({ openai: {} });
|
|
540
|
+
if (reasoningEndEvent2) {
|
|
541
|
+
yield reasoningEndEvent2;
|
|
547
542
|
}
|
|
548
543
|
for (const bufferedToolCall of bufferedToolCalls.values()) {
|
|
549
544
|
if (emittedToolCalls.has(bufferedToolCall.id)) {
|
|
@@ -570,12 +565,11 @@ async function* transformStream(stream) {
|
|
|
570
565
|
return;
|
|
571
566
|
}
|
|
572
567
|
}
|
|
573
|
-
const
|
|
568
|
+
const reasoningEndEvent = getNextReasoningEndEvent({
|
|
574
569
|
openai: {}
|
|
575
570
|
});
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
yield reasoningEndTransition.event;
|
|
571
|
+
if (reasoningEndEvent) {
|
|
572
|
+
yield reasoningEndEvent;
|
|
579
573
|
}
|
|
580
574
|
const hasToolCalls = bufferedToolCalls.size > 0;
|
|
581
575
|
const usage = latestResponse ? mapUsage(latestResponse.usage) : mapUsage(void 0);
|
|
@@ -682,169 +676,10 @@ function createOpenAIChatModel(client, modelId) {
|
|
|
682
676
|
}
|
|
683
677
|
};
|
|
684
678
|
}
|
|
685
|
-
function extractStructuredObject(result, schema, provider, toolName) {
|
|
686
|
-
const structuredToolCall = result.toolCalls.find(
|
|
687
|
-
(toolCall) => toolCall.name === toolName
|
|
688
|
-
);
|
|
689
|
-
if (structuredToolCall) {
|
|
690
|
-
return validateStructuredToolArguments(
|
|
691
|
-
schema,
|
|
692
|
-
structuredToolCall.arguments,
|
|
693
|
-
provider
|
|
694
|
-
);
|
|
695
|
-
}
|
|
696
|
-
const rawOutput = result.content?.trim();
|
|
697
|
-
if (rawOutput && rawOutput.length > 0) {
|
|
698
|
-
return parseAndValidateStructuredPayload(schema, rawOutput, provider);
|
|
699
|
-
}
|
|
700
|
-
throw new StructuredOutputNoObjectGeneratedError(
|
|
701
|
-
"model did not emit a structured object payload",
|
|
702
|
-
provider
|
|
703
|
-
);
|
|
704
|
-
}
|
|
705
|
-
async function* transformStructuredOutputStream(stream, schema, provider, toolName) {
|
|
706
|
-
let validatedObject;
|
|
707
|
-
let contentBuffer = "";
|
|
708
|
-
const toolArgumentDeltas = /* @__PURE__ */ new Map();
|
|
709
|
-
for await (const event of stream) {
|
|
710
|
-
if (event.type === "text-delta") {
|
|
711
|
-
contentBuffer += event.text;
|
|
712
|
-
yield {
|
|
713
|
-
type: "object-delta",
|
|
714
|
-
text: event.text
|
|
715
|
-
};
|
|
716
|
-
continue;
|
|
717
|
-
}
|
|
718
|
-
if (event.type === "tool-call-delta") {
|
|
719
|
-
const previous = toolArgumentDeltas.get(event.toolCallId) ?? "";
|
|
720
|
-
toolArgumentDeltas.set(
|
|
721
|
-
event.toolCallId,
|
|
722
|
-
`${previous}${event.argumentsDelta}`
|
|
723
|
-
);
|
|
724
|
-
yield {
|
|
725
|
-
type: "object-delta",
|
|
726
|
-
text: event.argumentsDelta
|
|
727
|
-
};
|
|
728
|
-
continue;
|
|
729
|
-
}
|
|
730
|
-
if (event.type === "tool-call-end" && event.toolCall.name === toolName) {
|
|
731
|
-
validatedObject = validateStructuredToolArguments(
|
|
732
|
-
schema,
|
|
733
|
-
event.toolCall.arguments,
|
|
734
|
-
provider
|
|
735
|
-
);
|
|
736
|
-
yield {
|
|
737
|
-
type: "object",
|
|
738
|
-
object: validatedObject
|
|
739
|
-
};
|
|
740
|
-
continue;
|
|
741
|
-
}
|
|
742
|
-
if (event.type === "finish") {
|
|
743
|
-
if (validatedObject === void 0) {
|
|
744
|
-
const fallbackPayload = getFallbackStructuredPayload(
|
|
745
|
-
contentBuffer,
|
|
746
|
-
toolArgumentDeltas
|
|
747
|
-
);
|
|
748
|
-
if (!fallbackPayload) {
|
|
749
|
-
throw new StructuredOutputNoObjectGeneratedError(
|
|
750
|
-
"structured output stream ended without an object payload",
|
|
751
|
-
provider
|
|
752
|
-
);
|
|
753
|
-
}
|
|
754
|
-
validatedObject = parseAndValidateStructuredPayload(
|
|
755
|
-
schema,
|
|
756
|
-
fallbackPayload,
|
|
757
|
-
provider
|
|
758
|
-
);
|
|
759
|
-
yield {
|
|
760
|
-
type: "object",
|
|
761
|
-
object: validatedObject
|
|
762
|
-
};
|
|
763
|
-
}
|
|
764
|
-
yield {
|
|
765
|
-
type: "finish",
|
|
766
|
-
finishReason: event.finishReason,
|
|
767
|
-
usage: event.usage
|
|
768
|
-
};
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
function getFallbackStructuredPayload(contentBuffer, toolArgumentDeltas) {
|
|
773
|
-
for (const delta of toolArgumentDeltas.values()) {
|
|
774
|
-
const trimmed = delta.trim();
|
|
775
|
-
if (trimmed.length > 0) {
|
|
776
|
-
return trimmed;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
const trimmedContent = contentBuffer.trim();
|
|
780
|
-
if (trimmedContent.length > 0) {
|
|
781
|
-
return trimmedContent;
|
|
782
|
-
}
|
|
783
|
-
return void 0;
|
|
784
|
-
}
|
|
785
|
-
function validateStructuredToolArguments(schema, toolArguments, provider) {
|
|
786
|
-
return validateStructuredObject(
|
|
787
|
-
schema,
|
|
788
|
-
toolArguments,
|
|
789
|
-
provider,
|
|
790
|
-
JSON.stringify(toolArguments)
|
|
791
|
-
);
|
|
792
|
-
}
|
|
793
|
-
function parseAndValidateStructuredPayload(schema, rawPayload, provider) {
|
|
794
|
-
const parsedPayload = parseJson(rawPayload, provider);
|
|
795
|
-
return validateStructuredObject(
|
|
796
|
-
schema,
|
|
797
|
-
parsedPayload,
|
|
798
|
-
provider,
|
|
799
|
-
rawPayload
|
|
800
|
-
);
|
|
801
|
-
}
|
|
802
|
-
function parseJson(rawOutput, provider) {
|
|
803
|
-
try {
|
|
804
|
-
return JSON.parse(rawOutput);
|
|
805
|
-
} catch (error) {
|
|
806
|
-
throw new StructuredOutputParseError(
|
|
807
|
-
"failed to parse structured output as JSON",
|
|
808
|
-
provider,
|
|
809
|
-
{
|
|
810
|
-
rawOutput,
|
|
811
|
-
cause: error
|
|
812
|
-
}
|
|
813
|
-
);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
function validateStructuredObject(schema, value, provider, rawOutput) {
|
|
817
|
-
const parsed = schema.safeParse(value);
|
|
818
|
-
if (parsed.success) {
|
|
819
|
-
return parsed.data;
|
|
820
|
-
}
|
|
821
|
-
throw new StructuredOutputValidationError(
|
|
822
|
-
"structured output does not match schema",
|
|
823
|
-
provider,
|
|
824
|
-
formatZodIssues(parsed.error.issues),
|
|
825
|
-
{
|
|
826
|
-
rawOutput
|
|
827
|
-
}
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
function formatZodIssues(issues) {
|
|
831
|
-
return issues.map((issue) => {
|
|
832
|
-
const path = issue.path.length > 0 ? issue.path.map((segment) => String(segment)).join(".") : "<root>";
|
|
833
|
-
return `${path}: ${issue.message}`;
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
679
|
|
|
837
680
|
// src/provider.ts
|
|
838
681
|
function createOpenAI(options = {}) {
|
|
839
|
-
|
|
840
|
-
apiKey: options.apiKey,
|
|
841
|
-
baseURL: options.baseURL
|
|
842
|
-
});
|
|
843
|
-
return {
|
|
844
|
-
chatModel: (modelId) => createOpenAIChatModel(client, modelId),
|
|
845
|
-
embeddingModel: (modelId) => createOpenAIEmbeddingModel(client, modelId),
|
|
846
|
-
imageModel: (modelId) => createOpenAIImageModel(client, modelId)
|
|
847
|
-
};
|
|
682
|
+
return createOpenAIProvider(options, createOpenAIChatModel);
|
|
848
683
|
}
|
|
849
684
|
export {
|
|
850
685
|
createOpenAI,
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { ChatModel, EmbeddingModel, ImageModel } from '@core-ai/core-ai';
|
|
1
3
|
import { z } from 'zod';
|
|
2
4
|
|
|
5
|
+
type OpenAIProviderBaseOptions = {
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
baseURL?: string;
|
|
8
|
+
client?: OpenAI;
|
|
9
|
+
};
|
|
10
|
+
type OpenAIProvider = {
|
|
11
|
+
chatModel(modelId: string): ChatModel;
|
|
12
|
+
embeddingModel(modelId: string): EmbeddingModel;
|
|
13
|
+
imageModel(modelId: string): ImageModel;
|
|
14
|
+
};
|
|
15
|
+
|
|
3
16
|
declare const openaiResponsesGenerateProviderOptionsSchema: z.ZodObject<{
|
|
4
17
|
store: z.ZodOptional<z.ZodBoolean>;
|
|
5
18
|
serviceTier: z.ZodOptional<z.ZodEnum<{
|
|
@@ -117,4 +130,4 @@ declare const openaiCompatProviderOptionsSchema: z.ZodObject<{
|
|
|
117
130
|
}, z.core.$strict>;
|
|
118
131
|
type OpenAICompatRequestOptions = OpenAICompatGenerateProviderOptions;
|
|
119
132
|
|
|
120
|
-
export { type
|
|
133
|
+
export { type OpenAIProvider as O, type OpenAIProviderBaseOptions as a, type OpenAICompatGenerateProviderOptions as b, type OpenAICompatRequestOptions as c, openaiCompatProviderOptionsSchema as d, type OpenAIEmbedProviderOptions as e, type OpenAIImageProviderOptions as f, type OpenAIResponsesGenerateProviderOptions as g, type OpenAIResponsesProviderOptions as h, openaiEmbedProviderOptionsSchema as i, openaiImageProviderOptionsSchema as j, openaiResponsesGenerateProviderOptionsSchema as k, openaiResponsesProviderOptionsSchema as l, openaiCompatGenerateProviderOptionsSchema as o };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@core-ai/openai",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "OpenAI provider package for @core-ai/core-ai",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Omnifact (https://omnifact.ai)",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"test:watch": "vitest"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@core-ai/core-ai": "^0.7.
|
|
49
|
+
"@core-ai/core-ai": "^0.7.1",
|
|
50
50
|
"openai": "^6.1.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|