@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.
@@ -1,7 +1,32 @@
1
1
  import OpenAI from 'openai';
2
- import { ChatModel, EmbeddingModel, ImageModel } from '@core-ai/core-ai';
2
+ import { ModelCapabilities, ChatModel, EmbeddingModel, ImageModel } from '@core-ai/core-ai';
3
3
  import { z } from 'zod';
4
4
 
5
+ type OpenAIChatCompletionsCapabilities = {
6
+ maxTokensParameter: 'max_tokens' | 'max_completion_tokens';
7
+ };
8
+ type OpenAIModelCapabilities = ModelCapabilities & {
9
+ chatCompletions: OpenAIChatCompletionsCapabilities;
10
+ };
11
+ declare function getOpenAIModelCapabilities(modelId: string): OpenAIModelCapabilities;
12
+
13
+ type OpenAIChatCompletionsAdapterOptions = {
14
+ compatibility?: boolean;
15
+ maxTokensParameter?: OpenAIChatCompletionsCapabilities['maxTokensParameter'];
16
+ };
17
+
18
+ type OpenAIStructuredOutputMode = 'native' | 'tool';
19
+
20
+ type OpenAIChatClient = {
21
+ chat: OpenAI['chat'];
22
+ };
23
+ type OpenAIChatCompletionsModelOptions = OpenAIChatCompletionsAdapterOptions & {
24
+ providerId?: string;
25
+ nonStandardReasoning?: boolean;
26
+ structuredOutputMode?: OpenAIStructuredOutputMode;
27
+ };
28
+ declare function createOpenAIChatCompletionsModel(client: OpenAIChatClient, modelId: string, modelOptions?: OpenAIChatCompletionsModelOptions): ChatModel;
29
+
5
30
  type OpenAIProviderBaseOptions = {
6
31
  apiKey?: string;
7
32
  baseURL?: string;
@@ -9,9 +34,25 @@ type OpenAIProviderBaseOptions = {
9
34
  };
10
35
  type OpenAIProvider = {
11
36
  chatModel(modelId: string): ChatModel;
37
+ chat: OpenAIChatProvider;
12
38
  embeddingModel(modelId: string): EmbeddingModel;
13
39
  imageModel(modelId: string): ImageModel;
14
40
  };
41
+ type OpenAIChatProvider = {
42
+ chatModel(modelId: string): ChatModel;
43
+ };
44
+ type OpenAICompatibilityOptions = {
45
+ reasoning?: boolean;
46
+ structuredOutputMode?: OpenAIChatCompletionsModelOptions['structuredOutputMode'];
47
+ maxTokensParameter?: OpenAIChatCompletionsModelOptions['maxTokensParameter'];
48
+ };
49
+ type OpenAICompatibility = boolean | OpenAICompatibilityOptions;
50
+ type OpenAIProviderFactoryOptions = {
51
+ providerId?: string;
52
+ defaultApi?: 'responses' | 'chat-completions';
53
+ compatibility?: OpenAICompatibility;
54
+ };
55
+ declare function createOpenAIProvider(options: OpenAIProviderBaseOptions, factoryOptions?: OpenAIProviderFactoryOptions): OpenAIProvider;
15
56
 
16
57
  declare const openaiResponsesGenerateProviderOptionsSchema: z.ZodObject<{
17
58
  store: z.ZodOptional<z.ZodBoolean>;
@@ -27,7 +68,7 @@ declare const openaiResponsesGenerateProviderOptionsSchema: z.ZodObject<{
27
68
  user: z.ZodOptional<z.ZodString>;
28
69
  }, z.core.$strict>;
29
70
  type OpenAIResponsesGenerateProviderOptions = z.infer<typeof openaiResponsesGenerateProviderOptionsSchema>;
30
- declare const openaiCompatGenerateProviderOptionsSchema: z.ZodObject<{
71
+ declare const openaiChatGenerateProviderOptionsSchema: z.ZodObject<{
31
72
  store: z.ZodOptional<z.ZodBoolean>;
32
73
  serviceTier: z.ZodOptional<z.ZodEnum<{
33
74
  auto: "auto";
@@ -43,7 +84,7 @@ declare const openaiCompatGenerateProviderOptionsSchema: z.ZodObject<{
43
84
  presencePenalty: z.ZodOptional<z.ZodNumber>;
44
85
  seed: z.ZodOptional<z.ZodNumber>;
45
86
  }, z.core.$strict>;
46
- type OpenAICompatGenerateProviderOptions = z.infer<typeof openaiCompatGenerateProviderOptionsSchema>;
87
+ type OpenAIChatGenerateProviderOptions = z.infer<typeof openaiChatGenerateProviderOptionsSchema>;
47
88
  declare const openaiEmbedProviderOptionsSchema: z.ZodObject<{
48
89
  encodingFormat: z.ZodOptional<z.ZodEnum<{
49
90
  float: "float";
@@ -89,7 +130,7 @@ declare const openaiImageProviderOptionsSchema: z.ZodObject<{
89
130
  type OpenAIImageProviderOptions = z.infer<typeof openaiImageProviderOptionsSchema>;
90
131
  declare module '@core-ai/core-ai' {
91
132
  interface GenerateProviderOptions {
92
- openai?: OpenAIResponsesGenerateProviderOptions | OpenAICompatGenerateProviderOptions;
133
+ openai?: OpenAIResponsesGenerateProviderOptions | OpenAIChatGenerateProviderOptions;
93
134
  }
94
135
  interface EmbedProviderOptions {
95
136
  openai?: OpenAIEmbedProviderOptions;
@@ -128,6 +169,23 @@ declare const openaiCompatProviderOptionsSchema: z.ZodObject<{
128
169
  presencePenalty: z.ZodOptional<z.ZodNumber>;
129
170
  seed: z.ZodOptional<z.ZodNumber>;
130
171
  }, z.core.$strict>;
131
- type OpenAICompatRequestOptions = OpenAICompatGenerateProviderOptions;
172
+ declare const openaiCompatGenerateProviderOptionsSchema: z.ZodObject<{
173
+ store: z.ZodOptional<z.ZodBoolean>;
174
+ serviceTier: z.ZodOptional<z.ZodEnum<{
175
+ auto: "auto";
176
+ default: "default";
177
+ flex: "flex";
178
+ scale: "scale";
179
+ priority: "priority";
180
+ }>>;
181
+ parallelToolCalls: z.ZodOptional<z.ZodBoolean>;
182
+ user: z.ZodOptional<z.ZodString>;
183
+ stopSequences: z.ZodOptional<z.ZodArray<z.ZodString>>;
184
+ frequencyPenalty: z.ZodOptional<z.ZodNumber>;
185
+ presencePenalty: z.ZodOptional<z.ZodNumber>;
186
+ seed: z.ZodOptional<z.ZodNumber>;
187
+ }, z.core.$strict>;
188
+ type OpenAICompatGenerateProviderOptions = OpenAIChatGenerateProviderOptions;
189
+ type OpenAICompatRequestOptions = OpenAIChatGenerateProviderOptions;
132
190
 
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 };
191
+ export { type OpenAIChatClient as O, type OpenAIProvider as a, type OpenAIProviderBaseOptions as b, type OpenAICompatGenerateProviderOptions as c, type OpenAICompatRequestOptions as d, openaiCompatProviderOptionsSchema as e, type OpenAIChatCompletionsModelOptions as f, type OpenAIChatGenerateProviderOptions as g, type OpenAIChatProvider as h, type OpenAICompatibility as i, type OpenAICompatibilityOptions as j, type OpenAIEmbedProviderOptions as k, type OpenAIImageProviderOptions as l, type OpenAIModelCapabilities as m, type OpenAIProviderFactoryOptions as n, openaiCompatGenerateProviderOptionsSchema as o, type OpenAIResponsesGenerateProviderOptions as p, type OpenAIResponsesProviderOptions as q, type OpenAIStructuredOutputMode as r, createOpenAIChatCompletionsModel as s, createOpenAIProvider as t, getOpenAIModelCapabilities as u, openaiChatGenerateProviderOptionsSchema as v, openaiEmbedProviderOptionsSchema as w, openaiImageProviderOptionsSchema as x, openaiResponsesGenerateProviderOptionsSchema as y, openaiResponsesProviderOptionsSchema as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@core-ai/openai",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "description": "OpenAI provider package for @core-ai/core-ai",
5
5
  "license": "MIT",
6
6
  "author": "Omnifact (https://omnifact.ai)",
@@ -50,7 +50,7 @@
50
50
  "test:watch": "vitest"
51
51
  },
52
52
  "dependencies": {
53
- "@core-ai/core-ai": "^0.14.0",
53
+ "@core-ai/core-ai": "^0.16.0",
54
54
  "openai": "^6.46.0"
55
55
  },
56
56
  "peerDependencies": {
@@ -1,568 +0,0 @@
1
- // src/model-capabilities.ts
2
- import {
3
- stripModelDateSuffix
4
- } from "@core-ai/core-ai";
5
- var STANDARD_EFFORTS = [
6
- "low",
7
- "medium",
8
- "high"
9
- ];
10
- var MAX_EFFORTS = [
11
- "low",
12
- "medium",
13
- "high",
14
- "max"
15
- ];
16
- var MINIMAL_EFFORTS = [
17
- "minimal",
18
- "low",
19
- "medium",
20
- "high"
21
- ];
22
- var PRO_EFFORTS = [
23
- "medium",
24
- "high",
25
- "max"
26
- ];
27
- var HIGH_EFFORT = ["high"];
28
- function createCapabilities(supportedEfforts, restrictsSamplingParams) {
29
- return {
30
- reasoning: {
31
- supported: true,
32
- supportedEfforts,
33
- restrictsSamplingParams
34
- }
35
- };
36
- }
37
- var DEFAULT_CAPABILITIES = createCapabilities(STANDARD_EFFORTS, false);
38
- var SAMPLING_RESTRICTED_STANDARD_CAPABILITIES = createCapabilities(
39
- STANDARD_EFFORTS,
40
- true
41
- );
42
- var GPT_5_MAX_REASONING_CAPABILITIES = createCapabilities(MAX_EFFORTS, true);
43
- var GPT_5_MINIMAL_REASONING_CAPABILITIES = createCapabilities(
44
- MINIMAL_EFFORTS,
45
- true
46
- );
47
- var GPT_5_PRO_REASONING_CAPABILITIES = createCapabilities(PRO_EFFORTS, true);
48
- var GPT_5_HIGH_REASONING_CAPABILITIES = createCapabilities(HIGH_EFFORT, true);
49
- var NO_REASONING_EFFORT_CAPABILITIES = {
50
- reasoning: {
51
- supported: false,
52
- supportedEfforts: [],
53
- restrictsSamplingParams: false
54
- }
55
- };
56
- var O_SERIES_MAX_REASONING_CAPABILITIES = createCapabilities(
57
- MAX_EFFORTS,
58
- false
59
- );
60
- var MODEL_CAPABILITIES = {
61
- "gpt-5.6-sol": GPT_5_MAX_REASONING_CAPABILITIES,
62
- "gpt-5.6-terra": SAMPLING_RESTRICTED_STANDARD_CAPABILITIES,
63
- "gpt-5.6-luna": GPT_5_MINIMAL_REASONING_CAPABILITIES,
64
- "gpt-5.5": GPT_5_MAX_REASONING_CAPABILITIES,
65
- "gpt-5.5-pro": GPT_5_PRO_REASONING_CAPABILITIES,
66
- "gpt-5.4": GPT_5_MAX_REASONING_CAPABILITIES,
67
- "gpt-5.4-pro": GPT_5_PRO_REASONING_CAPABILITIES,
68
- "gpt-5.4-mini": GPT_5_MAX_REASONING_CAPABILITIES,
69
- "gpt-5.4-nano": GPT_5_MAX_REASONING_CAPABILITIES,
70
- "gpt-5.3-codex": GPT_5_MAX_REASONING_CAPABILITIES,
71
- "gpt-5.2": GPT_5_MAX_REASONING_CAPABILITIES,
72
- "gpt-5.2-codex": GPT_5_MAX_REASONING_CAPABILITIES,
73
- "gpt-5.2-pro": GPT_5_MAX_REASONING_CAPABILITIES,
74
- "gpt-5.1-codex": GPT_5_MAX_REASONING_CAPABILITIES,
75
- "gpt-5.1-codex-max": GPT_5_MAX_REASONING_CAPABILITIES,
76
- "gpt-5.1-codex-mini": GPT_5_MAX_REASONING_CAPABILITIES,
77
- "gpt-5.1": SAMPLING_RESTRICTED_STANDARD_CAPABILITIES,
78
- "gpt-5": GPT_5_MINIMAL_REASONING_CAPABILITIES,
79
- "gpt-5-mini": GPT_5_MINIMAL_REASONING_CAPABILITIES,
80
- "gpt-5-nano": GPT_5_MINIMAL_REASONING_CAPABILITIES,
81
- "gpt-5-pro": GPT_5_HIGH_REASONING_CAPABILITIES,
82
- "gpt-5-codex": GPT_5_MAX_REASONING_CAPABILITIES,
83
- "o3-pro": O_SERIES_MAX_REASONING_CAPABILITIES,
84
- o3: DEFAULT_CAPABILITIES,
85
- "o3-mini": DEFAULT_CAPABILITIES,
86
- "o4-mini": DEFAULT_CAPABILITIES,
87
- o1: DEFAULT_CAPABILITIES,
88
- "o1-mini": NO_REASONING_EFFORT_CAPABILITIES
89
- };
90
- var OPENAI_REASONING_EFFORT_MAP = {
91
- minimal: "minimal",
92
- low: "low",
93
- medium: "medium",
94
- high: "high",
95
- max: "xhigh"
96
- };
97
- function getOpenAIModelCapabilities(modelId) {
98
- const normalizedModelId = normalizeModelId(modelId);
99
- return MODEL_CAPABILITIES[normalizedModelId] ?? DEFAULT_CAPABILITIES;
100
- }
101
- function normalizeModelId(modelId) {
102
- return stripModelDateSuffix(modelId);
103
- }
104
- function toOpenAIReasoningEffort(effort) {
105
- return OPENAI_REASONING_EFFORT_MAP[effort];
106
- }
107
-
108
- // src/provider-options.ts
109
- import { z } from "zod";
110
- var openaiResponsesGenerateProviderOptionsSchema = z.object({
111
- store: z.boolean().optional(),
112
- serviceTier: z.enum(["auto", "default", "flex", "scale", "priority"]).optional(),
113
- include: z.array(z.string()).optional(),
114
- parallelToolCalls: z.boolean().optional(),
115
- user: z.string().optional()
116
- }).strict();
117
- var openaiCompatGenerateProviderOptionsSchema = openaiResponsesGenerateProviderOptionsSchema.omit({
118
- include: true
119
- }).extend({
120
- stopSequences: z.array(z.string()).optional(),
121
- frequencyPenalty: z.number().optional(),
122
- presencePenalty: z.number().optional(),
123
- seed: z.number().int().optional()
124
- }).strict();
125
- var openaiEmbedProviderOptionsSchema = z.object({
126
- encodingFormat: z.enum(["float", "base64"]).optional(),
127
- user: z.string().optional()
128
- }).strict();
129
- var openaiImageProviderOptionsSchema = z.object({
130
- background: z.enum(["transparent", "opaque", "auto"]).optional(),
131
- moderation: z.enum(["low", "auto"]).optional(),
132
- outputCompression: z.number().int().min(0).max(100).optional(),
133
- outputFormat: z.enum(["png", "jpeg", "webp"]).optional(),
134
- quality: z.enum(["standard", "hd", "low", "medium", "high", "auto"]).optional(),
135
- responseFormat: z.enum(["url", "b64_json"]).optional(),
136
- style: z.enum(["vivid", "natural"]).optional(),
137
- user: z.string().optional()
138
- }).strict();
139
- function parseOpenAIProviderOptions(providerOptions, schema) {
140
- const rawOptions = providerOptions?.openai;
141
- if (rawOptions === void 0) {
142
- return void 0;
143
- }
144
- return schema.parse(rawOptions);
145
- }
146
- function parseOpenAIResponsesGenerateProviderOptions(providerOptions) {
147
- return parseOpenAIProviderOptions(
148
- providerOptions,
149
- openaiResponsesGenerateProviderOptionsSchema
150
- );
151
- }
152
- function parseOpenAICompatGenerateProviderOptions(providerOptions) {
153
- return parseOpenAIProviderOptions(
154
- providerOptions,
155
- openaiCompatGenerateProviderOptionsSchema
156
- );
157
- }
158
- function parseOpenAIEmbedProviderOptions(providerOptions) {
159
- return parseOpenAIProviderOptions(
160
- providerOptions,
161
- openaiEmbedProviderOptionsSchema
162
- );
163
- }
164
- function parseOpenAIImageProviderOptions(providerOptions) {
165
- return parseOpenAIProviderOptions(
166
- providerOptions,
167
- openaiImageProviderOptionsSchema
168
- );
169
- }
170
- var openaiResponsesProviderOptionsSchema = openaiResponsesGenerateProviderOptionsSchema;
171
- var openaiCompatProviderOptionsSchema = openaiCompatGenerateProviderOptionsSchema;
172
-
173
- // src/shared/tools.ts
174
- import { zodSchemaToJsonSchema } from "@core-ai/core-ai";
175
- var DEFAULT_STRUCTURED_OUTPUT_TOOL_NAME = "core_ai_generate_object";
176
- var DEFAULT_STRUCTURED_OUTPUT_TOOL_DESCRIPTION = "Return a JSON object that matches the requested schema.";
177
- function convertTools(tools) {
178
- return Object.values(tools).map((tool) => ({
179
- type: "function",
180
- function: {
181
- name: tool.name,
182
- description: tool.description,
183
- parameters: zodSchemaToJsonSchema(tool.parameters)
184
- }
185
- }));
186
- }
187
- function convertToolChoice(choice) {
188
- if (typeof choice === "string") {
189
- return choice;
190
- }
191
- return {
192
- type: "function",
193
- function: {
194
- name: choice.toolName
195
- }
196
- };
197
- }
198
- function getStructuredOutputToolName(options) {
199
- return options.schemaName?.trim() || DEFAULT_STRUCTURED_OUTPUT_TOOL_NAME;
200
- }
201
- function createStructuredOutputOptions(options) {
202
- const toolName = getStructuredOutputToolName(options);
203
- return {
204
- messages: options.messages,
205
- tools: {
206
- structured_output: {
207
- name: toolName,
208
- description: options.schemaDescription ?? DEFAULT_STRUCTURED_OUTPUT_TOOL_DESCRIPTION,
209
- parameters: options.schema
210
- }
211
- },
212
- toolChoice: {
213
- type: "tool",
214
- toolName
215
- },
216
- reasoning: options.reasoning,
217
- temperature: options.temperature,
218
- maxTokens: options.maxTokens,
219
- topP: options.topP,
220
- providerOptions: options.providerOptions,
221
- signal: options.signal
222
- };
223
- }
224
-
225
- // src/openai-error.ts
226
- import { APIError, APIUserAbortError } from "openai";
227
- import { AbortedError, ProviderError } from "@core-ai/core-ai";
228
- function isOpenAIAbortError(error) {
229
- return error instanceof APIUserAbortError || error instanceof Error && error.name === "AbortError";
230
- }
231
- function wrapOpenAIError(error, provider = "openai") {
232
- if (isOpenAIAbortError(error)) {
233
- return new AbortedError(error, provider);
234
- }
235
- if (error instanceof APIError) {
236
- return new ProviderError(
237
- error.message,
238
- provider,
239
- error.status,
240
- error
241
- );
242
- }
243
- return new ProviderError(
244
- error instanceof Error ? error.message : String(error),
245
- provider,
246
- void 0,
247
- error
248
- );
249
- }
250
-
251
- // src/shared/structured-output.ts
252
- import {
253
- StructuredOutputNoObjectGeneratedError,
254
- StructuredOutputParseError,
255
- StructuredOutputValidationError
256
- } from "@core-ai/core-ai";
257
- function extractStructuredObject(result, schema, provider, toolName) {
258
- const structuredToolCall = result.toolCalls.find(
259
- (toolCall) => toolCall.name === toolName
260
- );
261
- if (structuredToolCall) {
262
- return validateStructuredToolArguments(
263
- schema,
264
- structuredToolCall.arguments,
265
- provider
266
- );
267
- }
268
- const rawOutput = result.content?.trim();
269
- if (rawOutput && rawOutput.length > 0) {
270
- return parseAndValidateStructuredPayload(schema, rawOutput, provider);
271
- }
272
- throw new StructuredOutputNoObjectGeneratedError(
273
- "model did not emit a structured object payload",
274
- provider
275
- );
276
- }
277
- async function* transformStructuredOutputStream(stream, schema, provider, toolName) {
278
- let validatedObject;
279
- let contentBuffer = "";
280
- const toolArgumentDeltas = /* @__PURE__ */ new Map();
281
- for await (const event of stream) {
282
- if (event.type === "text-delta") {
283
- contentBuffer += event.text;
284
- yield {
285
- type: "object-delta",
286
- text: event.text
287
- };
288
- continue;
289
- }
290
- if (event.type === "tool-call-delta") {
291
- const previous = toolArgumentDeltas.get(event.toolCallId) ?? "";
292
- toolArgumentDeltas.set(
293
- event.toolCallId,
294
- `${previous}${event.argumentsDelta}`
295
- );
296
- yield {
297
- type: "object-delta",
298
- text: event.argumentsDelta
299
- };
300
- continue;
301
- }
302
- if (event.type === "tool-call-end" && event.toolCall.name === toolName) {
303
- validatedObject = validateStructuredToolArguments(
304
- schema,
305
- event.toolCall.arguments,
306
- provider
307
- );
308
- yield {
309
- type: "object",
310
- object: validatedObject
311
- };
312
- continue;
313
- }
314
- if (event.type === "finish") {
315
- if (validatedObject === void 0) {
316
- const fallbackPayload = getFallbackStructuredPayload(
317
- contentBuffer,
318
- toolArgumentDeltas
319
- );
320
- if (!fallbackPayload) {
321
- throw new StructuredOutputNoObjectGeneratedError(
322
- "structured output stream ended without an object payload",
323
- provider
324
- );
325
- }
326
- validatedObject = parseAndValidateStructuredPayload(
327
- schema,
328
- fallbackPayload,
329
- provider
330
- );
331
- yield {
332
- type: "object",
333
- object: validatedObject
334
- };
335
- }
336
- yield {
337
- type: "finish",
338
- finishReason: event.finishReason,
339
- usage: event.usage
340
- };
341
- }
342
- }
343
- }
344
- function getFallbackStructuredPayload(contentBuffer, toolArgumentDeltas) {
345
- for (const delta of toolArgumentDeltas.values()) {
346
- const trimmed = delta.trim();
347
- if (trimmed.length > 0) {
348
- return trimmed;
349
- }
350
- }
351
- const trimmedContent = contentBuffer.trim();
352
- if (trimmedContent.length > 0) {
353
- return trimmedContent;
354
- }
355
- return void 0;
356
- }
357
- function validateStructuredToolArguments(schema, toolArguments, provider) {
358
- return validateStructuredObject(
359
- schema,
360
- toolArguments,
361
- provider,
362
- JSON.stringify(toolArguments)
363
- );
364
- }
365
- function parseAndValidateStructuredPayload(schema, rawPayload, provider) {
366
- const parsedPayload = parseJson(rawPayload, provider);
367
- return validateStructuredObject(
368
- schema,
369
- parsedPayload,
370
- provider,
371
- rawPayload
372
- );
373
- }
374
- function parseJson(rawOutput, provider) {
375
- try {
376
- return JSON.parse(rawOutput);
377
- } catch (error) {
378
- throw new StructuredOutputParseError(
379
- "failed to parse structured output as JSON",
380
- provider,
381
- {
382
- rawOutput,
383
- cause: error
384
- }
385
- );
386
- }
387
- }
388
- function validateStructuredObject(schema, value, provider, rawOutput) {
389
- const parsed = schema.safeParse(value);
390
- if (parsed.success) {
391
- return parsed.data;
392
- }
393
- throw new StructuredOutputValidationError(
394
- "structured output does not match schema",
395
- provider,
396
- formatZodIssues(parsed.error.issues),
397
- {
398
- rawOutput
399
- }
400
- );
401
- }
402
- function formatZodIssues(issues) {
403
- return issues.map((issue) => {
404
- const path = issue.path.length > 0 ? issue.path.map((segment) => String(segment)).join(".") : "<root>";
405
- return `${path}: ${issue.message}`;
406
- });
407
- }
408
-
409
- // src/shared/provider-factory.ts
410
- import OpenAI from "openai";
411
-
412
- // src/embedding-model.ts
413
- function createOpenAIEmbeddingModel(client, modelId) {
414
- return {
415
- provider: "openai",
416
- modelId,
417
- async embed(options) {
418
- try {
419
- const openaiOptions = parseOpenAIEmbedProviderOptions(
420
- options.providerOptions
421
- );
422
- const response = await client.embeddings.create({
423
- model: modelId,
424
- input: options.input,
425
- ...options.dimensions !== void 0 ? { dimensions: options.dimensions } : {},
426
- ...mapOpenAIEmbedProviderOptionsToRequestFields(
427
- openaiOptions
428
- )
429
- });
430
- return {
431
- embeddings: response.data.slice().sort((a, b) => a.index - b.index).map((item) => item.embedding),
432
- usage: {
433
- inputTokens: response.usage.prompt_tokens
434
- }
435
- };
436
- } catch (error) {
437
- throw wrapOpenAIError(error);
438
- }
439
- }
440
- };
441
- }
442
- function mapOpenAIEmbedProviderOptionsToRequestFields(options) {
443
- return {
444
- ...options?.encodingFormat !== void 0 ? { encoding_format: options.encodingFormat } : {},
445
- ...options?.user !== void 0 ? { user: options.user } : {}
446
- };
447
- }
448
-
449
- // src/image-model.ts
450
- function createOpenAIImageModel(client, modelId) {
451
- return {
452
- provider: "openai",
453
- modelId,
454
- async generate(options) {
455
- try {
456
- const openaiOptions = parseOpenAIImageProviderOptions(
457
- options.providerOptions
458
- );
459
- const request = {
460
- model: modelId,
461
- prompt: options.prompt,
462
- ...options.n !== void 0 ? { n: options.n } : {},
463
- ...options.size !== void 0 ? { size: options.size } : {},
464
- ...mapOpenAIImageProviderOptionsToRequestFields(
465
- openaiOptions
466
- )
467
- };
468
- const response = await client.images.generate(
469
- request
470
- );
471
- return {
472
- images: (response.data ?? []).map((image) => ({
473
- base64: image.b64_json ?? void 0,
474
- url: image.url ?? void 0,
475
- revisedPrompt: image.revised_prompt ?? void 0
476
- }))
477
- };
478
- } catch (error) {
479
- throw wrapOpenAIError(error);
480
- }
481
- }
482
- };
483
- }
484
- function mapOpenAIImageProviderOptionsToRequestFields(options) {
485
- return {
486
- ...options?.background !== void 0 ? { background: options.background } : {},
487
- ...options?.moderation !== void 0 ? { moderation: options.moderation } : {},
488
- ...options?.outputCompression !== void 0 ? { output_compression: options.outputCompression } : {},
489
- ...options?.outputFormat !== void 0 ? { output_format: options.outputFormat } : {},
490
- ...options?.quality !== void 0 ? { quality: options.quality } : {},
491
- ...options?.responseFormat !== void 0 ? { response_format: options.responseFormat } : {},
492
- ...options?.style !== void 0 ? { style: options.style } : {},
493
- ...options?.user !== void 0 ? { user: options.user } : {}
494
- };
495
- }
496
-
497
- // src/shared/provider-factory.ts
498
- function createOpenAIProvider(options, createChatModel) {
499
- const client = options.client ?? new OpenAI({
500
- apiKey: options.apiKey,
501
- baseURL: options.baseURL
502
- });
503
- return {
504
- chatModel: (modelId) => createChatModel(client, modelId),
505
- embeddingModel: (modelId) => createOpenAIEmbeddingModel(client, modelId),
506
- imageModel: (modelId) => createOpenAIImageModel(client, modelId)
507
- };
508
- }
509
-
510
- // src/shared/utils.ts
511
- import { ValidationError } from "@core-ai/core-ai";
512
- function safeParseJsonObject(json) {
513
- try {
514
- const parsed = JSON.parse(json);
515
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
516
- return parsed;
517
- }
518
- return {};
519
- } catch {
520
- return {};
521
- }
522
- }
523
- function validateOpenAIReasoningConfig(modelId, options) {
524
- if (!options.reasoning) {
525
- return;
526
- }
527
- const capabilities = getOpenAIModelCapabilities(modelId);
528
- if (!capabilities.reasoning.restrictsSamplingParams) {
529
- return;
530
- }
531
- const restrictedSamplingParams = [
532
- { name: "temperature", value: options.temperature },
533
- { name: "topP", value: options.topP }
534
- ];
535
- for (const { name, value } of restrictedSamplingParams) {
536
- if (value === void 0) {
537
- continue;
538
- }
539
- throw new ValidationError(
540
- `OpenAI model "${modelId}" does not support ${name} when reasoning is enabled`,
541
- void 0,
542
- "openai"
543
- );
544
- }
545
- }
546
-
547
- export {
548
- getOpenAIModelCapabilities,
549
- toOpenAIReasoningEffort,
550
- convertTools,
551
- convertToolChoice,
552
- getStructuredOutputToolName,
553
- createStructuredOutputOptions,
554
- safeParseJsonObject,
555
- validateOpenAIReasoningConfig,
556
- openaiResponsesGenerateProviderOptionsSchema,
557
- openaiCompatGenerateProviderOptionsSchema,
558
- openaiEmbedProviderOptionsSchema,
559
- openaiImageProviderOptionsSchema,
560
- parseOpenAIResponsesGenerateProviderOptions,
561
- parseOpenAICompatGenerateProviderOptions,
562
- openaiResponsesProviderOptionsSchema,
563
- openaiCompatProviderOptionsSchema,
564
- wrapOpenAIError,
565
- extractStructuredObject,
566
- transformStructuredOutputStream,
567
- createOpenAIProvider
568
- };