@aigne/openai 0.14.2 → 0.15.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.15.0](https://github.com/AIGNE-io/aigne-framework/compare/openai-v0.14.3...openai-v0.15.0) (2025-09-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* support custom prefer input file type ([#469](https://github.com/AIGNE-io/aigne-framework/issues/469)) ([db0161b](https://github.com/AIGNE-io/aigne-framework/commit/db0161bbac52542c771ee2f40f361636b0668075))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @aigne/core bumped to 1.59.0
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @aigne/test-utils bumped to 0.5.48
|
|
18
|
+
|
|
19
|
+
## [0.14.3](https://github.com/AIGNE-io/aigne-framework/compare/openai-v0.14.2...openai-v0.14.3) (2025-09-08)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Bug Fixes
|
|
23
|
+
|
|
24
|
+
* support optional field sturectured output for gemini ([#468](https://github.com/AIGNE-io/aigne-framework/issues/468)) ([70c6279](https://github.com/AIGNE-io/aigne-framework/commit/70c62795039a2862e3333f26707329489bf938de))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Dependencies
|
|
28
|
+
|
|
29
|
+
* The following workspace dependencies were updated
|
|
30
|
+
* dependencies
|
|
31
|
+
* @aigne/core bumped to 1.58.3
|
|
32
|
+
* devDependencies
|
|
33
|
+
* @aigne/test-utils bumped to 0.5.47
|
|
34
|
+
|
|
3
35
|
## [0.14.2](https://github.com/AIGNE-io/aigne-framework/compare/openai-v0.14.1...openai-v0.14.2) (2025-09-05)
|
|
4
36
|
|
|
5
37
|
|
|
@@ -15,7 +15,7 @@ export interface OpenAIChatModelCapabilities {
|
|
|
15
15
|
/**
|
|
16
16
|
* Configuration options for OpenAI Chat Model
|
|
17
17
|
*/
|
|
18
|
-
export interface OpenAIChatModelOptions {
|
|
18
|
+
export interface OpenAIChatModelOptions extends ChatModelOptions {
|
|
19
19
|
/**
|
|
20
20
|
* API key for OpenAI API
|
|
21
21
|
*
|
|
@@ -28,16 +28,6 @@ export interface OpenAIChatModelOptions {
|
|
|
28
28
|
* Useful for proxies or alternate endpoints
|
|
29
29
|
*/
|
|
30
30
|
baseURL?: string;
|
|
31
|
-
/**
|
|
32
|
-
* OpenAI model to use
|
|
33
|
-
*
|
|
34
|
-
* Defaults to 'gpt-4o-mini'
|
|
35
|
-
*/
|
|
36
|
-
model?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Additional model options to control behavior
|
|
39
|
-
*/
|
|
40
|
-
modelOptions?: ChatModelOptions;
|
|
41
31
|
/**
|
|
42
32
|
* Client options for OpenAI API
|
|
43
33
|
*/
|
|
@@ -137,7 +127,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
137
127
|
apiKey: string | undefined;
|
|
138
128
|
model: string;
|
|
139
129
|
};
|
|
140
|
-
get modelOptions():
|
|
130
|
+
get modelOptions(): Omit<import("@aigne/core").ModelOptions, "model"> | undefined;
|
|
141
131
|
/**
|
|
142
132
|
* Process the input and generate a response
|
|
143
133
|
* @param input The input to process
|
|
@@ -151,6 +141,13 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
151
141
|
private getRunResponseFormat;
|
|
152
142
|
private requestStructuredOutput;
|
|
153
143
|
private extractResultFromStream;
|
|
144
|
+
/**
|
|
145
|
+
* Controls how optional fields are handled in JSON schema conversion
|
|
146
|
+
* - "anyOf": All fields are required but can be null (default)
|
|
147
|
+
* - "optional": Fields marked as optional in schema remain optional
|
|
148
|
+
*/
|
|
149
|
+
protected optionalFieldMode?: "anyOf" | "optional";
|
|
150
|
+
protected jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
154
151
|
}
|
|
155
152
|
/**
|
|
156
153
|
* @hidden
|
|
@@ -162,7 +159,3 @@ export declare function contentsFromInputMessages(messages: ChatModelInputMessag
|
|
|
162
159
|
export declare function toolsFromInputTools(tools?: ChatModelInputTool[], options?: {
|
|
163
160
|
addTypeToEmptyParameters?: boolean;
|
|
164
161
|
}): ChatCompletionTool[] | undefined;
|
|
165
|
-
/**
|
|
166
|
-
* @hidden
|
|
167
|
-
*/
|
|
168
|
-
export declare function jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OpenAIChatModel = exports.openAIChatModelOptionsSchema = void 0;
|
|
4
4
|
exports.contentsFromInputMessages = contentsFromInputMessages;
|
|
5
5
|
exports.toolsFromInputTools = toolsFromInputTools;
|
|
6
|
-
exports.jsonSchemaToOpenAIJsonSchema = jsonSchemaToOpenAIJsonSchema;
|
|
7
6
|
const core_1 = require("@aigne/core");
|
|
8
7
|
const logger_js_1 = require("@aigne/core/utils/logger.js");
|
|
9
8
|
const model_utils_js_1 = require("@aigne/core/utils/model-utils.js");
|
|
@@ -196,7 +195,7 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
196
195
|
type: "json_schema",
|
|
197
196
|
json_schema: {
|
|
198
197
|
...input.responseFormat.jsonSchema,
|
|
199
|
-
schema: jsonSchemaToOpenAIJsonSchema(input.responseFormat.jsonSchema.schema),
|
|
198
|
+
schema: this.jsonSchemaToOpenAIJsonSchema(input.responseFormat.jsonSchema.schema),
|
|
200
199
|
},
|
|
201
200
|
},
|
|
202
201
|
};
|
|
@@ -312,6 +311,40 @@ class OpenAIChatModel extends core_1.ChatModel {
|
|
|
312
311
|
});
|
|
313
312
|
return streaming ? result : await (0, stream_utils_js_1.agentResponseStreamToObject)(result);
|
|
314
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Controls how optional fields are handled in JSON schema conversion
|
|
316
|
+
* - "anyOf": All fields are required but can be null (default)
|
|
317
|
+
* - "optional": Fields marked as optional in schema remain optional
|
|
318
|
+
*/
|
|
319
|
+
optionalFieldMode = "anyOf";
|
|
320
|
+
jsonSchemaToOpenAIJsonSchema(schema) {
|
|
321
|
+
if (schema?.type === "object") {
|
|
322
|
+
const s = schema;
|
|
323
|
+
const required = this.optionalFieldMode === "anyOf" ? Object.keys(s.properties) : s.required;
|
|
324
|
+
return {
|
|
325
|
+
...schema,
|
|
326
|
+
properties: Object.fromEntries(Object.entries(s.properties).map(([key, value]) => {
|
|
327
|
+
const valueSchema = this.jsonSchemaToOpenAIJsonSchema(value);
|
|
328
|
+
// NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
|
|
329
|
+
return [
|
|
330
|
+
key,
|
|
331
|
+
this.optionalFieldMode === "optional" || s.required?.includes(key)
|
|
332
|
+
? valueSchema
|
|
333
|
+
: { anyOf: [valueSchema, { type: ["null"] }] },
|
|
334
|
+
];
|
|
335
|
+
})),
|
|
336
|
+
required,
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
if (schema?.type === "array") {
|
|
340
|
+
const { items } = schema;
|
|
341
|
+
return {
|
|
342
|
+
...schema,
|
|
343
|
+
items: this.jsonSchemaToOpenAIJsonSchema(items),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
return schema;
|
|
347
|
+
}
|
|
315
348
|
}
|
|
316
349
|
exports.OpenAIChatModel = OpenAIChatModel;
|
|
317
350
|
// Create role mapper for OpenAI (uses standard mapping)
|
|
@@ -373,34 +406,6 @@ function toolsFromInputTools(tools, options) {
|
|
|
373
406
|
})
|
|
374
407
|
: undefined;
|
|
375
408
|
}
|
|
376
|
-
/**
|
|
377
|
-
* @hidden
|
|
378
|
-
*/
|
|
379
|
-
function jsonSchemaToOpenAIJsonSchema(schema) {
|
|
380
|
-
if (schema?.type === "object") {
|
|
381
|
-
const { required, properties } = schema;
|
|
382
|
-
return {
|
|
383
|
-
...schema,
|
|
384
|
-
properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => {
|
|
385
|
-
const valueSchema = jsonSchemaToOpenAIJsonSchema(value);
|
|
386
|
-
// NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
|
|
387
|
-
return [
|
|
388
|
-
key,
|
|
389
|
-
required?.includes(key) ? valueSchema : { anyOf: [valueSchema, { type: ["null"] }] },
|
|
390
|
-
];
|
|
391
|
-
})),
|
|
392
|
-
required: Object.keys(properties),
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
if (schema?.type === "array") {
|
|
396
|
-
const { items } = schema;
|
|
397
|
-
return {
|
|
398
|
-
...schema,
|
|
399
|
-
items: jsonSchemaToOpenAIJsonSchema(items),
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
|
-
return schema;
|
|
403
|
-
}
|
|
404
409
|
function handleToolCallDelta(toolCalls, call) {
|
|
405
410
|
toolCalls[call.index] ??= {
|
|
406
411
|
id: call.id || (0, uuid_1.v7)(),
|
|
@@ -15,7 +15,7 @@ export interface OpenAIChatModelCapabilities {
|
|
|
15
15
|
/**
|
|
16
16
|
* Configuration options for OpenAI Chat Model
|
|
17
17
|
*/
|
|
18
|
-
export interface OpenAIChatModelOptions {
|
|
18
|
+
export interface OpenAIChatModelOptions extends ChatModelOptions {
|
|
19
19
|
/**
|
|
20
20
|
* API key for OpenAI API
|
|
21
21
|
*
|
|
@@ -28,16 +28,6 @@ export interface OpenAIChatModelOptions {
|
|
|
28
28
|
* Useful for proxies or alternate endpoints
|
|
29
29
|
*/
|
|
30
30
|
baseURL?: string;
|
|
31
|
-
/**
|
|
32
|
-
* OpenAI model to use
|
|
33
|
-
*
|
|
34
|
-
* Defaults to 'gpt-4o-mini'
|
|
35
|
-
*/
|
|
36
|
-
model?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Additional model options to control behavior
|
|
39
|
-
*/
|
|
40
|
-
modelOptions?: ChatModelOptions;
|
|
41
31
|
/**
|
|
42
32
|
* Client options for OpenAI API
|
|
43
33
|
*/
|
|
@@ -137,7 +127,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
137
127
|
apiKey: string | undefined;
|
|
138
128
|
model: string;
|
|
139
129
|
};
|
|
140
|
-
get modelOptions():
|
|
130
|
+
get modelOptions(): Omit<import("@aigne/core").ModelOptions, "model"> | undefined;
|
|
141
131
|
/**
|
|
142
132
|
* Process the input and generate a response
|
|
143
133
|
* @param input The input to process
|
|
@@ -151,6 +141,13 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
151
141
|
private getRunResponseFormat;
|
|
152
142
|
private requestStructuredOutput;
|
|
153
143
|
private extractResultFromStream;
|
|
144
|
+
/**
|
|
145
|
+
* Controls how optional fields are handled in JSON schema conversion
|
|
146
|
+
* - "anyOf": All fields are required but can be null (default)
|
|
147
|
+
* - "optional": Fields marked as optional in schema remain optional
|
|
148
|
+
*/
|
|
149
|
+
protected optionalFieldMode?: "anyOf" | "optional";
|
|
150
|
+
protected jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
154
151
|
}
|
|
155
152
|
/**
|
|
156
153
|
* @hidden
|
|
@@ -162,7 +159,3 @@ export declare function contentsFromInputMessages(messages: ChatModelInputMessag
|
|
|
162
159
|
export declare function toolsFromInputTools(tools?: ChatModelInputTool[], options?: {
|
|
163
160
|
addTypeToEmptyParameters?: boolean;
|
|
164
161
|
}): ChatCompletionTool[] | undefined;
|
|
165
|
-
/**
|
|
166
|
-
* @hidden
|
|
167
|
-
*/
|
|
168
|
-
export declare function jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -15,7 +15,7 @@ export interface OpenAIChatModelCapabilities {
|
|
|
15
15
|
/**
|
|
16
16
|
* Configuration options for OpenAI Chat Model
|
|
17
17
|
*/
|
|
18
|
-
export interface OpenAIChatModelOptions {
|
|
18
|
+
export interface OpenAIChatModelOptions extends ChatModelOptions {
|
|
19
19
|
/**
|
|
20
20
|
* API key for OpenAI API
|
|
21
21
|
*
|
|
@@ -28,16 +28,6 @@ export interface OpenAIChatModelOptions {
|
|
|
28
28
|
* Useful for proxies or alternate endpoints
|
|
29
29
|
*/
|
|
30
30
|
baseURL?: string;
|
|
31
|
-
/**
|
|
32
|
-
* OpenAI model to use
|
|
33
|
-
*
|
|
34
|
-
* Defaults to 'gpt-4o-mini'
|
|
35
|
-
*/
|
|
36
|
-
model?: string;
|
|
37
|
-
/**
|
|
38
|
-
* Additional model options to control behavior
|
|
39
|
-
*/
|
|
40
|
-
modelOptions?: ChatModelOptions;
|
|
41
31
|
/**
|
|
42
32
|
* Client options for OpenAI API
|
|
43
33
|
*/
|
|
@@ -137,7 +127,7 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
137
127
|
apiKey: string | undefined;
|
|
138
128
|
model: string;
|
|
139
129
|
};
|
|
140
|
-
get modelOptions():
|
|
130
|
+
get modelOptions(): Omit<import("@aigne/core").ModelOptions, "model"> | undefined;
|
|
141
131
|
/**
|
|
142
132
|
* Process the input and generate a response
|
|
143
133
|
* @param input The input to process
|
|
@@ -151,6 +141,13 @@ export declare class OpenAIChatModel extends ChatModel {
|
|
|
151
141
|
private getRunResponseFormat;
|
|
152
142
|
private requestStructuredOutput;
|
|
153
143
|
private extractResultFromStream;
|
|
144
|
+
/**
|
|
145
|
+
* Controls how optional fields are handled in JSON schema conversion
|
|
146
|
+
* - "anyOf": All fields are required but can be null (default)
|
|
147
|
+
* - "optional": Fields marked as optional in schema remain optional
|
|
148
|
+
*/
|
|
149
|
+
protected optionalFieldMode?: "anyOf" | "optional";
|
|
150
|
+
protected jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
154
151
|
}
|
|
155
152
|
/**
|
|
156
153
|
* @hidden
|
|
@@ -162,7 +159,3 @@ export declare function contentsFromInputMessages(messages: ChatModelInputMessag
|
|
|
162
159
|
export declare function toolsFromInputTools(tools?: ChatModelInputTool[], options?: {
|
|
163
160
|
addTypeToEmptyParameters?: boolean;
|
|
164
161
|
}): ChatCompletionTool[] | undefined;
|
|
165
|
-
/**
|
|
166
|
-
* @hidden
|
|
167
|
-
*/
|
|
168
|
-
export declare function jsonSchemaToOpenAIJsonSchema(schema: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -190,7 +190,7 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
190
190
|
type: "json_schema",
|
|
191
191
|
json_schema: {
|
|
192
192
|
...input.responseFormat.jsonSchema,
|
|
193
|
-
schema: jsonSchemaToOpenAIJsonSchema(input.responseFormat.jsonSchema.schema),
|
|
193
|
+
schema: this.jsonSchemaToOpenAIJsonSchema(input.responseFormat.jsonSchema.schema),
|
|
194
194
|
},
|
|
195
195
|
},
|
|
196
196
|
};
|
|
@@ -306,6 +306,40 @@ export class OpenAIChatModel extends ChatModel {
|
|
|
306
306
|
});
|
|
307
307
|
return streaming ? result : await agentResponseStreamToObject(result);
|
|
308
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Controls how optional fields are handled in JSON schema conversion
|
|
311
|
+
* - "anyOf": All fields are required but can be null (default)
|
|
312
|
+
* - "optional": Fields marked as optional in schema remain optional
|
|
313
|
+
*/
|
|
314
|
+
optionalFieldMode = "anyOf";
|
|
315
|
+
jsonSchemaToOpenAIJsonSchema(schema) {
|
|
316
|
+
if (schema?.type === "object") {
|
|
317
|
+
const s = schema;
|
|
318
|
+
const required = this.optionalFieldMode === "anyOf" ? Object.keys(s.properties) : s.required;
|
|
319
|
+
return {
|
|
320
|
+
...schema,
|
|
321
|
+
properties: Object.fromEntries(Object.entries(s.properties).map(([key, value]) => {
|
|
322
|
+
const valueSchema = this.jsonSchemaToOpenAIJsonSchema(value);
|
|
323
|
+
// NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
|
|
324
|
+
return [
|
|
325
|
+
key,
|
|
326
|
+
this.optionalFieldMode === "optional" || s.required?.includes(key)
|
|
327
|
+
? valueSchema
|
|
328
|
+
: { anyOf: [valueSchema, { type: ["null"] }] },
|
|
329
|
+
];
|
|
330
|
+
})),
|
|
331
|
+
required,
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (schema?.type === "array") {
|
|
335
|
+
const { items } = schema;
|
|
336
|
+
return {
|
|
337
|
+
...schema,
|
|
338
|
+
items: this.jsonSchemaToOpenAIJsonSchema(items),
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
return schema;
|
|
342
|
+
}
|
|
309
343
|
}
|
|
310
344
|
// Create role mapper for OpenAI (uses standard mapping)
|
|
311
345
|
const mapRole = createRoleMapper(STANDARD_ROLE_MAP);
|
|
@@ -366,34 +400,6 @@ export function toolsFromInputTools(tools, options) {
|
|
|
366
400
|
})
|
|
367
401
|
: undefined;
|
|
368
402
|
}
|
|
369
|
-
/**
|
|
370
|
-
* @hidden
|
|
371
|
-
*/
|
|
372
|
-
export function jsonSchemaToOpenAIJsonSchema(schema) {
|
|
373
|
-
if (schema?.type === "object") {
|
|
374
|
-
const { required, properties } = schema;
|
|
375
|
-
return {
|
|
376
|
-
...schema,
|
|
377
|
-
properties: Object.fromEntries(Object.entries(properties).map(([key, value]) => {
|
|
378
|
-
const valueSchema = jsonSchemaToOpenAIJsonSchema(value);
|
|
379
|
-
// NOTE: All fields must be required https://platform.openai.com/docs/guides/structured-outputs/all-fields-must-be-required
|
|
380
|
-
return [
|
|
381
|
-
key,
|
|
382
|
-
required?.includes(key) ? valueSchema : { anyOf: [valueSchema, { type: ["null"] }] },
|
|
383
|
-
];
|
|
384
|
-
})),
|
|
385
|
-
required: Object.keys(properties),
|
|
386
|
-
};
|
|
387
|
-
}
|
|
388
|
-
if (schema?.type === "array") {
|
|
389
|
-
const { items } = schema;
|
|
390
|
-
return {
|
|
391
|
-
...schema,
|
|
392
|
-
items: jsonSchemaToOpenAIJsonSchema(items),
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
return schema;
|
|
396
|
-
}
|
|
397
403
|
function handleToolCallDelta(toolCalls, call) {
|
|
398
404
|
toolCalls[call.index] ??= {
|
|
399
405
|
id: call.id || v7(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/openai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "AIGNE OpenAI SDK for integrating with OpenAI's GPT models and API services",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"openai": "^5.8.3",
|
|
40
40
|
"uuid": "^11.1.0",
|
|
41
41
|
"zod": "^3.25.67",
|
|
42
|
-
"@aigne/core": "^1.
|
|
42
|
+
"@aigne/core": "^1.59.0",
|
|
43
43
|
"@aigne/platform-helpers": "^0.6.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"npm-run-all": "^4.1.5",
|
|
49
49
|
"rimraf": "^6.0.1",
|
|
50
50
|
"typescript": "^5.8.3",
|
|
51
|
-
"@aigne/test-utils": "^0.5.
|
|
51
|
+
"@aigne/test-utils": "^0.5.48"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"lint": "tsc --noEmit",
|