openai 6.47.0 → 6.49.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 +52 -0
- package/azure.d.mts.map +1 -1
- package/azure.d.ts.map +1 -1
- package/azure.js +5 -1
- package/azure.js.map +1 -1
- package/azure.mjs +5 -1
- package/azure.mjs.map +1 -1
- package/helpers/standard-schema.d.mts +104 -0
- package/helpers/standard-schema.d.mts.map +1 -0
- package/helpers/standard-schema.d.ts +104 -0
- package/helpers/standard-schema.d.ts.map +1 -0
- package/helpers/standard-schema.js +320 -0
- package/helpers/standard-schema.js.map +1 -0
- package/helpers/standard-schema.mjs +314 -0
- package/helpers/standard-schema.mjs.map +1 -0
- package/helpers/zod.d.mts +26 -3
- package/helpers/zod.d.mts.map +1 -1
- package/helpers/zod.d.ts +26 -3
- package/helpers/zod.d.ts.map +1 -1
- package/helpers/zod.js +97 -7
- package/helpers/zod.js.map +1 -1
- package/helpers/zod.mjs +96 -7
- package/helpers/zod.mjs.map +1 -1
- package/internal/headers.d.mts.map +1 -1
- package/internal/headers.d.ts.map +1 -1
- package/internal/headers.js +7 -3
- package/internal/headers.js.map +1 -1
- package/internal/headers.mjs +7 -3
- package/internal/headers.mjs.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.mts.map +1 -1
- package/lib/AbstractChatCompletionRunner.d.ts.map +1 -1
- package/lib/AbstractChatCompletionRunner.js +43 -1
- package/lib/AbstractChatCompletionRunner.js.map +1 -1
- package/lib/AbstractChatCompletionRunner.mjs +43 -1
- package/lib/AbstractChatCompletionRunner.mjs.map +1 -1
- package/lib/ChatCompletionStream.d.mts +2 -1
- package/lib/ChatCompletionStream.d.mts.map +1 -1
- package/lib/ChatCompletionStream.d.ts +2 -1
- package/lib/ChatCompletionStream.d.ts.map +1 -1
- package/lib/ChatCompletionStream.js +53 -14
- package/lib/ChatCompletionStream.js.map +1 -1
- package/lib/ChatCompletionStream.mjs +53 -14
- package/lib/ChatCompletionStream.mjs.map +1 -1
- package/lib/ResponsesParser.d.mts.map +1 -1
- package/lib/ResponsesParser.d.ts.map +1 -1
- package/lib/ResponsesParser.js +3 -5
- package/lib/ResponsesParser.js.map +1 -1
- package/lib/ResponsesParser.mjs +3 -5
- package/lib/ResponsesParser.mjs.map +1 -1
- package/lib/jsonschema.d.mts +3 -0
- package/lib/jsonschema.d.mts.map +1 -1
- package/lib/jsonschema.d.ts +3 -0
- package/lib/jsonschema.d.ts.map +1 -1
- package/lib/transform.d.mts +25 -1
- package/lib/transform.d.mts.map +1 -1
- package/lib/transform.d.ts +25 -1
- package/lib/transform.d.ts.map +1 -1
- package/lib/transform.js +1521 -82
- package/lib/transform.js.map +1 -1
- package/lib/transform.mjs +1515 -82
- package/lib/transform.mjs.map +1 -1
- package/package.json +1 -1
- package/resources/admin/organization/audit-logs.d.mts +2 -2
- package/resources/admin/organization/audit-logs.d.mts.map +1 -1
- package/resources/admin/organization/audit-logs.d.ts +2 -2
- package/resources/admin/organization/audit-logs.d.ts.map +1 -1
- package/resources/admin/organization/index.d.mts +1 -0
- package/resources/admin/organization/index.d.mts.map +1 -1
- package/resources/admin/organization/index.d.ts +1 -0
- package/resources/admin/organization/index.d.ts.map +1 -1
- package/resources/admin/organization/index.js +3 -1
- package/resources/admin/organization/index.js.map +1 -1
- package/resources/admin/organization/index.mjs +1 -0
- package/resources/admin/organization/index.mjs.map +1 -1
- package/resources/admin/organization/organization.d.mts +4 -0
- package/resources/admin/organization/organization.d.mts.map +1 -1
- package/resources/admin/organization/organization.d.ts +4 -0
- package/resources/admin/organization/organization.d.ts.map +1 -1
- package/resources/admin/organization/organization.js +4 -0
- package/resources/admin/organization/organization.js.map +1 -1
- package/resources/admin/organization/organization.mjs +4 -0
- package/resources/admin/organization/organization.mjs.map +1 -1
- package/resources/admin/organization/projects/index.d.mts +2 -1
- package/resources/admin/organization/projects/index.d.mts.map +1 -1
- package/resources/admin/organization/projects/index.d.ts +2 -1
- package/resources/admin/organization/projects/index.d.ts.map +1 -1
- package/resources/admin/organization/projects/index.js +7 -5
- package/resources/admin/organization/projects/index.js.map +1 -1
- package/resources/admin/organization/projects/index.mjs +2 -1
- package/resources/admin/organization/projects/index.mjs.map +1 -1
- package/resources/admin/organization/projects/projects.d.mts +6 -2
- package/resources/admin/organization/projects/projects.d.mts.map +1 -1
- package/resources/admin/organization/projects/projects.d.ts +6 -2
- package/resources/admin/organization/projects/projects.d.ts.map +1 -1
- package/resources/admin/organization/projects/projects.js +6 -2
- package/resources/admin/organization/projects/projects.js.map +1 -1
- package/resources/admin/organization/projects/projects.mjs +6 -2
- package/resources/admin/organization/projects/projects.mjs.map +1 -1
- package/resources/admin/organization/projects/service-accounts/api-keys.d.mts +58 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.ts +58 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.js +26 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.mjs +22 -0
- package/resources/admin/organization/projects/service-accounts/api-keys.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.d.mts +3 -0
- package/resources/admin/organization/projects/service-accounts/index.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.d.ts +3 -0
- package/resources/admin/organization/projects/service-accounts/index.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.js +9 -0
- package/resources/admin/organization/projects/service-accounts/index.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/index.mjs +4 -0
- package/resources/admin/organization/projects/service-accounts/index.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.mts +177 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.mts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.ts +177 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.d.ts.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.js +109 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.js.map +1 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.mjs +104 -0
- package/resources/admin/organization/projects/service-accounts/service-accounts.mjs.map +1 -0
- package/resources/admin/organization/projects/service-accounts.d.mts +1 -167
- package/resources/admin/organization/projects/service-accounts.d.mts.map +1 -1
- package/resources/admin/organization/projects/service-accounts.d.ts +1 -167
- package/resources/admin/organization/projects/service-accounts.d.ts.map +1 -1
- package/resources/admin/organization/projects/service-accounts.js +2 -97
- package/resources/admin/organization/projects/service-accounts.js.map +1 -1
- package/resources/admin/organization/projects/service-accounts.mjs +1 -95
- package/resources/admin/organization/projects/service-accounts.mjs.map +1 -1
- package/resources/admin/organization/projects/spend-limit.d.mts +115 -0
- package/resources/admin/organization/projects/spend-limit.d.mts.map +1 -0
- package/resources/admin/organization/projects/spend-limit.d.ts +115 -0
- package/resources/admin/organization/projects/spend-limit.d.ts.map +1 -0
- package/resources/admin/organization/projects/spend-limit.js +67 -0
- package/resources/admin/organization/projects/spend-limit.js.map +1 -0
- package/resources/admin/organization/projects/spend-limit.mjs +63 -0
- package/resources/admin/organization/projects/spend-limit.mjs.map +1 -0
- package/resources/admin/organization/spend-limit.d.mts +108 -0
- package/resources/admin/organization/spend-limit.d.mts.map +1 -0
- package/resources/admin/organization/spend-limit.d.ts +108 -0
- package/resources/admin/organization/spend-limit.d.ts.map +1 -0
- package/resources/admin/organization/spend-limit.js +59 -0
- package/resources/admin/organization/spend-limit.js.map +1 -0
- package/resources/admin/organization/spend-limit.mjs +55 -0
- package/resources/admin/organization/spend-limit.mjs.map +1 -0
- package/resources/admin/organization/usage.d.mts +517 -88
- package/resources/admin/organization/usage.d.mts.map +1 -1
- package/resources/admin/organization/usage.d.ts +517 -88
- package/resources/admin/organization/usage.d.ts.map +1 -1
- package/resources/beta/responses/input-tokens.d.mts +6 -2
- package/resources/beta/responses/input-tokens.d.mts.map +1 -1
- package/resources/beta/responses/input-tokens.d.ts +6 -2
- package/resources/beta/responses/input-tokens.d.ts.map +1 -1
- package/resources/beta/responses/responses.d.mts +25 -15
- package/resources/beta/responses/responses.d.mts.map +1 -1
- package/resources/beta/responses/responses.d.ts +25 -15
- package/resources/beta/responses/responses.d.ts.map +1 -1
- package/resources/beta/responses/responses.js.map +1 -1
- package/resources/beta/responses/responses.mjs.map +1 -1
- package/resources/chat/completions/completions.d.mts +4 -3
- package/resources/chat/completions/completions.d.mts.map +1 -1
- package/resources/chat/completions/completions.d.ts +4 -3
- package/resources/chat/completions/completions.d.ts.map +1 -1
- package/resources/chat/completions/completions.js.map +1 -1
- package/resources/chat/completions/completions.mjs.map +1 -1
- package/resources/responses/input-tokens.d.mts +2 -1
- package/resources/responses/input-tokens.d.mts.map +1 -1
- package/resources/responses/input-tokens.d.ts +2 -1
- package/resources/responses/input-tokens.d.ts.map +1 -1
- package/resources/responses/responses.d.mts +9 -8
- package/resources/responses/responses.d.mts.map +1 -1
- package/resources/responses/responses.d.ts +9 -8
- package/resources/responses/responses.d.ts.map +1 -1
- package/resources/responses/responses.js.map +1 -1
- package/resources/responses/responses.mjs.map +1 -1
- package/resources/shared.d.mts +4 -1
- package/resources/shared.d.mts.map +1 -1
- package/resources/shared.d.ts +4 -1
- package/resources/shared.d.ts.map +1 -1
- package/src/azure.ts +5 -1
- package/src/helpers/standard-schema.ts +570 -0
- package/src/helpers/zod.ts +158 -29
- package/src/internal/headers.ts +7 -3
- package/src/lib/AbstractChatCompletionRunner.ts +43 -1
- package/src/lib/ChatCompletionStream.ts +56 -8
- package/src/lib/ResponsesParser.ts +7 -5
- package/src/lib/jsonschema.ts +3 -0
- package/src/lib/transform.ts +1930 -103
- package/src/resources/admin/organization/audit-logs.ts +169 -1
- package/src/resources/admin/organization/index.ts +6 -0
- package/src/resources/admin/organization/organization.ts +16 -0
- package/src/resources/admin/organization/projects/index.ts +7 -1
- package/src/resources/admin/organization/projects/projects.ts +29 -13
- package/src/resources/admin/organization/projects/service-accounts/api-keys.ts +80 -0
- package/src/resources/admin/organization/projects/service-accounts/index.ts +15 -0
- package/src/resources/admin/organization/projects/service-accounts/service-accounts.ts +284 -0
- package/src/resources/admin/organization/projects/service-accounts.ts +1 -264
- package/src/resources/admin/organization/projects/spend-limit.ts +156 -0
- package/src/resources/admin/organization/spend-limit.ts +144 -0
- package/src/resources/admin/organization/usage.ts +616 -88
- package/src/resources/beta/responses/input-tokens.ts +6 -2
- package/src/resources/beta/responses/responses.ts +25 -14
- package/src/resources/chat/completions/completions.ts +4 -3
- package/src/resources/responses/input-tokens.ts +2 -1
- package/src/resources/responses/responses.ts +9 -7
- package/src/resources/shared.ts +4 -1
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
package/src/helpers/zod.ts
CHANGED
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
import { zodToJsonSchema as _zodToJsonSchema } from '../_vendor/zod-to-json-schema';
|
|
14
14
|
import { AutoParseableResponseTool, makeParseableResponseTool } from '../lib/ResponsesParser';
|
|
15
15
|
import { type ResponseFormatTextJSONSchemaConfig } from '../resources/responses/responses';
|
|
16
|
+
import { type RealtimeFunctionTool } from '../resources/realtime/realtime';
|
|
16
17
|
import { toStrictJsonSchema } from '../lib/transform';
|
|
17
18
|
import { JSONSchema } from '../lib/jsonschema';
|
|
18
19
|
|
|
@@ -37,38 +38,134 @@ type InferZodType<T extends ZodTypeLike> =
|
|
|
37
38
|
: T extends { _zod: { output: infer Output } } ? Output
|
|
38
39
|
: never;
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
type ZodSchemaDefinitions = Record<string, ZodTypeLike>;
|
|
42
|
+
|
|
43
|
+
type ZodResponseFormatProps = Omit<ResponseFormatJSONSchema.JSONSchema, 'schema' | 'strict' | 'name'> & {
|
|
44
|
+
/**
|
|
45
|
+
* Schemas to extract into the generated JSON Schema definitions.
|
|
46
|
+
* Use this to reuse large shared schemas instead of inlining them at every occurrence.
|
|
47
|
+
*/
|
|
48
|
+
schemaDefinitions?: ZodSchemaDefinitions | undefined;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
function encodeSchemaDefinitionRefToken(token: string): string {
|
|
52
|
+
return encodeURIComponent(token.replace(/~/g, '~0').replace(/\//g, '~1'));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function validateSchemaDefinitions(schemaDefinitions: ZodSchemaDefinitions | undefined): void {
|
|
56
|
+
if (schemaDefinitions && Object.prototype.hasOwnProperty.call(schemaDefinitions, '__proto__')) {
|
|
57
|
+
throw new Error('schemaDefinitions cannot include "__proto__" as a definition name');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function escapeSchemaDefinitionRefs<T extends object>(
|
|
62
|
+
schema: T,
|
|
63
|
+
schemaDefinitions: ZodSchemaDefinitions | undefined,
|
|
64
|
+
): T {
|
|
65
|
+
const refReplacements = new Map(
|
|
66
|
+
Object.keys(schemaDefinitions ?? {}).map((name) => [
|
|
67
|
+
`#/definitions/${name}`,
|
|
68
|
+
`#/definitions/${encodeSchemaDefinitionRefToken(name)}`,
|
|
69
|
+
]),
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const visit = (value: unknown): void => {
|
|
73
|
+
if (!value || typeof value !== 'object') return;
|
|
74
|
+
|
|
75
|
+
if (Array.isArray(value)) {
|
|
76
|
+
for (const child of value) visit(child);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const record = value as Record<string, unknown>;
|
|
81
|
+
const ref = record['$ref'];
|
|
82
|
+
if (typeof ref === 'string') {
|
|
83
|
+
record['$ref'] = refReplacements.get(ref) ?? ref;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
for (const child of Object.values(record)) visit(child);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
visit(schema);
|
|
90
|
+
return schema;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function getZodV3RootName(name: string, schemaDefinitions: ZodSchemaDefinitions | undefined): string {
|
|
94
|
+
let rootName = name;
|
|
95
|
+
while (schemaDefinitions && Object.prototype.hasOwnProperty.call(schemaDefinitions, rootName)) {
|
|
96
|
+
rootName = `${rootName}_root`;
|
|
97
|
+
}
|
|
98
|
+
return rootName;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function zodV3ToJsonSchema(
|
|
102
|
+
schema: z3.ZodType,
|
|
103
|
+
options: { name: string; schemaDefinitions?: ZodSchemaDefinitions | undefined },
|
|
104
|
+
): Record<string, unknown> {
|
|
105
|
+
const rootName = getZodV3RootName(options.name, options.schemaDefinitions);
|
|
106
|
+
const jsonSchema = _zodToJsonSchema(schema, {
|
|
42
107
|
openaiStrictMode: true,
|
|
43
|
-
name:
|
|
108
|
+
name: rootName,
|
|
44
109
|
nameStrategy: 'duplicate-ref',
|
|
45
110
|
$refStrategy: 'extract-to-root',
|
|
46
111
|
nullableStrategy: 'property',
|
|
112
|
+
...(options.schemaDefinitions ?
|
|
113
|
+
{ definitions: options.schemaDefinitions as unknown as Record<string, z3.ZodType> }
|
|
114
|
+
: undefined),
|
|
47
115
|
});
|
|
116
|
+
|
|
117
|
+
return escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
|
|
48
118
|
}
|
|
49
119
|
|
|
50
|
-
function zodV4ToJsonSchema(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
120
|
+
function zodV4ToJsonSchema(
|
|
121
|
+
schema: ZodV4Schema,
|
|
122
|
+
options: { schemaDefinitions?: ZodSchemaDefinitions | undefined } = {},
|
|
123
|
+
): Record<string, unknown> {
|
|
124
|
+
const metadata = options.schemaDefinitions ? z4.registry<Record<string, unknown>>() : undefined;
|
|
125
|
+
for (const [name, definition] of Object.entries(options.schemaDefinitions ?? {})) {
|
|
126
|
+
metadata?.add(definition as unknown as z4.ZodType, { id: name });
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const jsonSchema = z4.toJSONSchema(schema, {
|
|
130
|
+
target: 'draft-7',
|
|
131
|
+
...(metadata ? { metadata } : undefined),
|
|
132
|
+
override: ({ zodSchema, jsonSchema }) => {
|
|
133
|
+
const def = zodSchema._zod.def;
|
|
134
|
+
|
|
135
|
+
if (def.type === 'union' && 'discriminator' in def && Array.isArray(jsonSchema.oneOf)) {
|
|
136
|
+
if (jsonSchema.anyOf !== undefined) {
|
|
137
|
+
throw new Error(
|
|
138
|
+
'Zod discriminated union generated both `anyOf` and `oneOf`, which cannot be represented in an OpenAI strict schema',
|
|
139
|
+
);
|
|
68
140
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
141
|
+
|
|
142
|
+
// Discriminator values are mutually exclusive, so anyOf preserves the
|
|
143
|
+
// union while staying inside the API's supported JSON Schema subset.
|
|
144
|
+
jsonSchema.anyOf = jsonSchema.oneOf;
|
|
145
|
+
delete jsonSchema.oneOf;
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
}) as JSONSchema;
|
|
149
|
+
|
|
150
|
+
const escapedSchema = escapeSchemaDefinitionRefs(jsonSchema, options.schemaDefinitions);
|
|
151
|
+
|
|
152
|
+
return toStrictJsonSchema(escapedSchema) as Record<string, unknown>;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function zodV3ToNonStrictJsonSchema(schema: z3.ZodType, options: { name: string }): Record<string, unknown> {
|
|
156
|
+
return _zodToJsonSchema(schema, {
|
|
157
|
+
name: options.name,
|
|
158
|
+
nameStrategy: 'duplicate-ref',
|
|
159
|
+
$refStrategy: 'extract-to-root',
|
|
160
|
+
pipeStrategy: 'input',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function zodV4ToNonStrictJsonSchema(schema: ZodV4Schema): Record<string, unknown> {
|
|
165
|
+
return z4.toJSONSchema(schema, {
|
|
166
|
+
target: 'draft-7',
|
|
167
|
+
io: 'input',
|
|
168
|
+
}) as Record<string, unknown>;
|
|
72
169
|
}
|
|
73
170
|
|
|
74
171
|
function isZodV4(zodObject: ZodSchema): zodObject is ZodV4Schema {
|
|
@@ -129,18 +226,23 @@ function parseZodObject<ZodInput extends ZodTypeLike>(
|
|
|
129
226
|
export function zodResponseFormat<ZodInput extends ZodTypeLike>(
|
|
130
227
|
zodObject: ZodInput,
|
|
131
228
|
name: string,
|
|
132
|
-
props?:
|
|
229
|
+
props?: ZodResponseFormatProps,
|
|
133
230
|
): AutoParseableResponseFormat<InferZodType<ZodInput>> {
|
|
134
231
|
const zodSchema = zodObject as unknown as ZodSchema;
|
|
232
|
+
const { schemaDefinitions, ...responseFormatProps } = props ?? {};
|
|
233
|
+
validateSchemaDefinitions(schemaDefinitions);
|
|
135
234
|
|
|
136
235
|
return makeParseableResponseFormat<InferZodType<ZodInput>>(
|
|
137
236
|
{
|
|
138
237
|
type: 'json_schema',
|
|
139
238
|
json_schema: {
|
|
140
|
-
...
|
|
239
|
+
...responseFormatProps,
|
|
141
240
|
name,
|
|
142
241
|
strict: true,
|
|
143
|
-
schema:
|
|
242
|
+
schema:
|
|
243
|
+
isZodV4(zodSchema) ?
|
|
244
|
+
zodV4ToJsonSchema(zodSchema, { schemaDefinitions })
|
|
245
|
+
: zodV3ToJsonSchema(zodSchema, { name, schemaDefinitions }),
|
|
144
246
|
},
|
|
145
247
|
},
|
|
146
248
|
(content) => parseZodObject(zodObject, content),
|
|
@@ -177,7 +279,7 @@ export function zodFunction<Parameters extends ZodTypeLike>(options: {
|
|
|
177
279
|
function?: ((args: InferZodType<Parameters>) => unknown | Promise<unknown>) | undefined;
|
|
178
280
|
description?: string | undefined;
|
|
179
281
|
}): AutoParseableTool<{
|
|
180
|
-
arguments: Parameters
|
|
282
|
+
arguments: InferZodType<Parameters>;
|
|
181
283
|
name: string;
|
|
182
284
|
function: (args: InferZodType<Parameters>) => unknown;
|
|
183
285
|
}> {
|
|
@@ -210,7 +312,7 @@ export function zodResponsesFunction<Parameters extends ZodTypeLike>(options: {
|
|
|
210
312
|
function?: ((args: InferZodType<Parameters>) => unknown | Promise<unknown>) | undefined;
|
|
211
313
|
description?: string | undefined;
|
|
212
314
|
}): AutoParseableResponseTool<{
|
|
213
|
-
arguments: Parameters
|
|
315
|
+
arguments: InferZodType<Parameters>;
|
|
214
316
|
name: string;
|
|
215
317
|
function: (args: InferZodType<Parameters>) => unknown;
|
|
216
318
|
}> {
|
|
@@ -233,3 +335,30 @@ export function zodResponsesFunction<Parameters extends ZodTypeLike>(options: {
|
|
|
233
335
|
},
|
|
234
336
|
);
|
|
235
337
|
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Creates a Realtime API `function` tool definition from the given Zod schema.
|
|
341
|
+
*
|
|
342
|
+
* Unlike {@link zodResponsesFunction}, this helper does not add `strict`
|
|
343
|
+
* because Realtime function tools do not support that field.
|
|
344
|
+
*
|
|
345
|
+
* This helper only creates the tool definition. Parse function-call arguments
|
|
346
|
+
* from Realtime events with the original Zod schema.
|
|
347
|
+
*/
|
|
348
|
+
export function zodRealtimeFunction<Parameters extends ZodTypeLike>(options: {
|
|
349
|
+
name: string;
|
|
350
|
+
parameters: Parameters;
|
|
351
|
+
description?: string | undefined;
|
|
352
|
+
}): RealtimeFunctionTool {
|
|
353
|
+
const zodSchema = options.parameters as unknown as ZodSchema;
|
|
354
|
+
|
|
355
|
+
return {
|
|
356
|
+
type: 'function',
|
|
357
|
+
name: options.name,
|
|
358
|
+
parameters:
|
|
359
|
+
isZodV4(zodSchema) ?
|
|
360
|
+
zodV4ToNonStrictJsonSchema(zodSchema)
|
|
361
|
+
: zodV3ToNonStrictJsonSchema(zodSchema, { name: options.name }),
|
|
362
|
+
...(options.description ? { description: options.description } : undefined),
|
|
363
|
+
};
|
|
364
|
+
}
|
package/src/internal/headers.ts
CHANGED
|
@@ -12,6 +12,7 @@ export type HeadersLike =
|
|
|
12
12
|
| NullableHeaders;
|
|
13
13
|
|
|
14
14
|
const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
|
|
15
|
+
const httpTokenHeaderName = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* @internal
|
|
@@ -74,16 +75,19 @@ export const buildHeaders = (newHeaders: HeadersLike[]): NullableHeaders => {
|
|
|
74
75
|
for (const headers of newHeaders) {
|
|
75
76
|
const seenHeaders = new Set<string>();
|
|
76
77
|
for (const [name, value] of iterateHeaders(headers)) {
|
|
78
|
+
if (!httpTokenHeaderName.test(name)) {
|
|
79
|
+
throw new TypeError(`Header name must be a valid HTTP token ["${name}"]`);
|
|
80
|
+
}
|
|
77
81
|
const lowerName = name.toLowerCase();
|
|
78
82
|
if (!seenHeaders.has(lowerName)) {
|
|
79
|
-
targetHeaders.delete(
|
|
83
|
+
targetHeaders.delete(lowerName);
|
|
80
84
|
seenHeaders.add(lowerName);
|
|
81
85
|
}
|
|
82
86
|
if (value === null) {
|
|
83
|
-
targetHeaders.delete(
|
|
87
|
+
targetHeaders.delete(lowerName);
|
|
84
88
|
nullHeaders.add(lowerName);
|
|
85
89
|
} else {
|
|
86
|
-
targetHeaders.append(
|
|
90
|
+
targetHeaders.append(lowerName, value);
|
|
87
91
|
nullHeaders.delete(lowerName);
|
|
88
92
|
}
|
|
89
93
|
}
|
|
@@ -5,6 +5,7 @@ import { uuid4 } from '../internal/utils/uuid';
|
|
|
5
5
|
import { isAutoParsableTool, parseChatCompletion } from '../lib/parser';
|
|
6
6
|
import type {
|
|
7
7
|
ChatCompletion,
|
|
8
|
+
ChatCompletionAssistantMessageParam,
|
|
8
9
|
ChatCompletionCreateParams,
|
|
9
10
|
ChatCompletionMessage,
|
|
10
11
|
ChatCompletionMessageFunctionToolCall,
|
|
@@ -49,6 +50,47 @@ function normalizeToolCallIds(chatCompletion: ChatCompletion): void {
|
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Parsed completions contain response-only and helper-only fields. Keep those
|
|
55
|
+
* on runner.messages for callers, but only replay valid request fields.
|
|
56
|
+
*/
|
|
57
|
+
function toRequestMessage(message: ChatCompletionMessageParam): ChatCompletionMessageParam {
|
|
58
|
+
if (!isAssistantMessage(message)) return message;
|
|
59
|
+
|
|
60
|
+
const requestMessage: ChatCompletionAssistantMessageParam = { role: 'assistant' };
|
|
61
|
+
|
|
62
|
+
if (message.audio != null) requestMessage.audio = { id: message.audio.id };
|
|
63
|
+
if (message.content !== undefined) requestMessage.content = message.content;
|
|
64
|
+
if (message.function_call != null) requestMessage.function_call = message.function_call;
|
|
65
|
+
if (message.name !== undefined) requestMessage.name = message.name;
|
|
66
|
+
if (message.refusal != null) requestMessage.refusal = message.refusal;
|
|
67
|
+
if (message.tool_calls !== undefined) {
|
|
68
|
+
requestMessage.tool_calls = message.tool_calls.map((toolCall) => {
|
|
69
|
+
if (toolCall.type === 'custom') {
|
|
70
|
+
return {
|
|
71
|
+
id: toolCall.id,
|
|
72
|
+
type: toolCall.type,
|
|
73
|
+
custom: {
|
|
74
|
+
input: toolCall.custom.input,
|
|
75
|
+
name: toolCall.custom.name,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
id: toolCall.id,
|
|
82
|
+
type: toolCall.type,
|
|
83
|
+
function: {
|
|
84
|
+
arguments: toolCall.function.arguments,
|
|
85
|
+
name: toolCall.function.name,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return requestMessage;
|
|
92
|
+
}
|
|
93
|
+
|
|
52
94
|
export interface ChatCompletionRunnerContext {
|
|
53
95
|
messages: ChatCompletionMessageParam[];
|
|
54
96
|
abort(): void;
|
|
@@ -413,7 +455,7 @@ export class AbstractChatCompletionRunner<
|
|
|
413
455
|
...restParams,
|
|
414
456
|
tool_choice,
|
|
415
457
|
tools,
|
|
416
|
-
messages:
|
|
458
|
+
messages: this.messages.map(toRequestMessage),
|
|
417
459
|
},
|
|
418
460
|
options,
|
|
419
461
|
);
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
} from '../lib/parser';
|
|
21
21
|
import { ChatCompletionFunctionTool, ParsedChatCompletion } from '../resources/chat/completions';
|
|
22
22
|
import {
|
|
23
|
+
type ChatCompletionAudio,
|
|
23
24
|
ChatCompletionTokenLogprob,
|
|
24
25
|
type ChatCompletion,
|
|
25
26
|
type ChatCompletionChunk,
|
|
@@ -196,12 +197,14 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
196
197
|
implements AsyncIterable<ChatCompletionChunk>
|
|
197
198
|
{
|
|
198
199
|
#params: ChatCompletionCreateParams | null;
|
|
200
|
+
#audioDoneChoiceIndexes: Set<number>;
|
|
199
201
|
#choiceEventStates: ChoiceEventState[];
|
|
200
202
|
#currentChatCompletionSnapshot: ChatCompletionSnapshot | undefined;
|
|
201
203
|
|
|
202
204
|
constructor(params: ChatCompletionCreateParams | null) {
|
|
203
205
|
super();
|
|
204
206
|
this.#params = params;
|
|
207
|
+
this.#audioDoneChoiceIndexes = new Set();
|
|
205
208
|
this.#choiceEventStates = [];
|
|
206
209
|
}
|
|
207
210
|
|
|
@@ -240,6 +243,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
240
243
|
|
|
241
244
|
#beginRequest() {
|
|
242
245
|
if (this.ended) return;
|
|
246
|
+
this.#audioDoneChoiceIndexes = new Set();
|
|
243
247
|
this.#currentChatCompletionSnapshot = undefined;
|
|
244
248
|
}
|
|
245
249
|
|
|
@@ -428,9 +432,11 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
428
432
|
if (!snapshot) {
|
|
429
433
|
throw new OpenAIError(`request ended without sending any chunks`);
|
|
430
434
|
}
|
|
435
|
+
const audioDoneChoiceIndexes = this.#audioDoneChoiceIndexes;
|
|
436
|
+
this.#audioDoneChoiceIndexes = new Set();
|
|
431
437
|
this.#currentChatCompletionSnapshot = undefined;
|
|
432
438
|
this.#choiceEventStates = [];
|
|
433
|
-
return finalizeChatCompletion(snapshot, this.#params);
|
|
439
|
+
return finalizeChatCompletion(snapshot, this.#params, audioDoneChoiceIndexes);
|
|
434
440
|
}
|
|
435
441
|
|
|
436
442
|
protected override async _createChatCompletion(
|
|
@@ -575,15 +581,41 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
575
581
|
|
|
576
582
|
if (!delta) continue; // Shouldn't happen; just in case.
|
|
577
583
|
|
|
578
|
-
|
|
584
|
+
this.#audioDoneChoiceIndexes.delete(index);
|
|
585
|
+
const { audio, content, refusal, function_call, role, tool_calls, ...rest } = delta as typeof delta & {
|
|
586
|
+
audio?: Partial<ChatCompletionAudio> | null;
|
|
587
|
+
};
|
|
579
588
|
assertIsEmpty(rest);
|
|
580
589
|
Object.assign(choice.message, rest);
|
|
590
|
+
if (
|
|
591
|
+
audio?.expires_at != null &&
|
|
592
|
+
audio.id == null &&
|
|
593
|
+
audio.data == null &&
|
|
594
|
+
audio.transcript == null &&
|
|
595
|
+
content == null &&
|
|
596
|
+
refusal == null &&
|
|
597
|
+
function_call == null &&
|
|
598
|
+
role == null &&
|
|
599
|
+
tool_calls == null &&
|
|
600
|
+
Object.keys(rest).length === 0
|
|
601
|
+
) {
|
|
602
|
+
this.#audioDoneChoiceIndexes.add(index);
|
|
603
|
+
}
|
|
581
604
|
|
|
582
605
|
if (refusal) {
|
|
583
606
|
choice.message.refusal = (choice.message.refusal || '') + refusal;
|
|
584
607
|
}
|
|
585
608
|
|
|
586
609
|
if (role) choice.message.role = role;
|
|
610
|
+
if (audio) {
|
|
611
|
+
const audioSnapshot = (choice.message.audio ??= {});
|
|
612
|
+
if (audio.id != null) audioSnapshot.id = audio.id;
|
|
613
|
+
if (audio.data != null) audioSnapshot.data = (audioSnapshot.data ?? '') + audio.data;
|
|
614
|
+
if (audio.transcript != null) {
|
|
615
|
+
audioSnapshot.transcript = (audioSnapshot.transcript ?? '') + audio.transcript;
|
|
616
|
+
}
|
|
617
|
+
if (audio.expires_at != null) audioSnapshot.expires_at = audio.expires_at;
|
|
618
|
+
}
|
|
587
619
|
if (function_call) {
|
|
588
620
|
if (!choice.message.function_call) {
|
|
589
621
|
choice.message.function_call = function_call;
|
|
@@ -698,6 +730,7 @@ export class ChatCompletionStream<ParsedT = null>
|
|
|
698
730
|
function finalizeChatCompletion<ParsedT>(
|
|
699
731
|
snapshot: ChatCompletionSnapshot,
|
|
700
732
|
params: ChatCompletionCreateParams | null,
|
|
733
|
+
audioDoneChoiceIndexes: ReadonlySet<number>,
|
|
701
734
|
): ParsedChatCompletion<ParsedT> {
|
|
702
735
|
const { id, choices, created, model, system_fingerprint, ...rest } = snapshot;
|
|
703
736
|
const completion: ChatCompletion = {
|
|
@@ -705,11 +738,16 @@ function finalizeChatCompletion<ParsedT>(
|
|
|
705
738
|
id,
|
|
706
739
|
choices: choices.map(
|
|
707
740
|
({ message, finish_reason, index, logprobs, ...choiceRest }): ChatCompletion.Choice => {
|
|
708
|
-
|
|
741
|
+
const { content = null, function_call, tool_calls, audio, ...messageRest } = message;
|
|
742
|
+
// Audio streams can end with an expires_at-only chunk after the
|
|
743
|
+
// generated audio, without a separate finish_reason.
|
|
744
|
+
const finishReason =
|
|
745
|
+
finish_reason ?? (audioDoneChoiceIndexes.has(index) && isCompleteAudio(audio) ? 'stop' : null);
|
|
746
|
+
if (!finishReason) {
|
|
709
747
|
throw new OpenAIError(`missing finish_reason for choice ${index}`);
|
|
710
748
|
}
|
|
711
749
|
|
|
712
|
-
const
|
|
750
|
+
const audioResponse = audio ? { audio: audio as ChatCompletionAudio } : {};
|
|
713
751
|
const role = message.role as 'assistant'; // this is what we expect; in theory it could be different which would make our types a slight lie but would be fine.
|
|
714
752
|
if (!role) {
|
|
715
753
|
throw new OpenAIError(`missing role for choice ${index}`);
|
|
@@ -728,12 +766,13 @@ function finalizeChatCompletion<ParsedT>(
|
|
|
728
766
|
return {
|
|
729
767
|
...choiceRest,
|
|
730
768
|
message: {
|
|
769
|
+
...audioResponse,
|
|
731
770
|
content,
|
|
732
771
|
function_call: { arguments: args, name },
|
|
733
772
|
role,
|
|
734
773
|
refusal: message.refusal ?? null,
|
|
735
774
|
},
|
|
736
|
-
finish_reason,
|
|
775
|
+
finish_reason: finishReason,
|
|
737
776
|
index,
|
|
738
777
|
logprobs,
|
|
739
778
|
};
|
|
@@ -743,10 +782,11 @@ function finalizeChatCompletion<ParsedT>(
|
|
|
743
782
|
return {
|
|
744
783
|
...choiceRest,
|
|
745
784
|
index,
|
|
746
|
-
finish_reason,
|
|
785
|
+
finish_reason: finishReason,
|
|
747
786
|
logprobs,
|
|
748
787
|
message: {
|
|
749
788
|
...messageRest,
|
|
789
|
+
...audioResponse,
|
|
750
790
|
role,
|
|
751
791
|
content,
|
|
752
792
|
refusal: message.refusal ?? null,
|
|
@@ -779,8 +819,8 @@ function finalizeChatCompletion<ParsedT>(
|
|
|
779
819
|
}
|
|
780
820
|
return {
|
|
781
821
|
...choiceRest,
|
|
782
|
-
message: { ...messageRest, content, role, refusal: message.refusal ?? null },
|
|
783
|
-
finish_reason,
|
|
822
|
+
message: { ...messageRest, ...audioResponse, content, role, refusal: message.refusal ?? null },
|
|
823
|
+
finish_reason: finishReason,
|
|
784
824
|
index,
|
|
785
825
|
logprobs,
|
|
786
826
|
};
|
|
@@ -795,6 +835,12 @@ function finalizeChatCompletion<ParsedT>(
|
|
|
795
835
|
return maybeParseChatCompletion(completion, params);
|
|
796
836
|
}
|
|
797
837
|
|
|
838
|
+
function isCompleteAudio(
|
|
839
|
+
audio: Partial<ChatCompletionAudio> | null | undefined,
|
|
840
|
+
): audio is ChatCompletionAudio {
|
|
841
|
+
return audio?.id != null && audio.data != null && audio.transcript != null && audio.expires_at != null;
|
|
842
|
+
}
|
|
843
|
+
|
|
798
844
|
function str(x: unknown) {
|
|
799
845
|
return JSON.stringify(x);
|
|
800
846
|
}
|
|
@@ -875,6 +921,8 @@ export namespace ChatCompletionSnapshot {
|
|
|
875
921
|
*/
|
|
876
922
|
content?: string | null;
|
|
877
923
|
|
|
924
|
+
audio?: Partial<ChatCompletionAudio> | null;
|
|
925
|
+
|
|
878
926
|
refusal?: string | null;
|
|
879
927
|
|
|
880
928
|
parsed?: unknown | null;
|
|
@@ -74,10 +74,7 @@ export function parseResponse<
|
|
|
74
74
|
const output: Array<ParsedResponseOutputItem<ParsedT>> = response.output.map(
|
|
75
75
|
(item): ParsedResponseOutputItem<ParsedT> => {
|
|
76
76
|
if (item.type === 'function_call') {
|
|
77
|
-
return {
|
|
78
|
-
...item,
|
|
79
|
-
parsed_arguments: shouldParse ? parseToolCall(params, item) : null,
|
|
80
|
-
};
|
|
77
|
+
return shouldParse ? parseToolCall(params, item) : { ...item, parsed_arguments: null };
|
|
81
78
|
}
|
|
82
79
|
if (item.type === 'message') {
|
|
83
80
|
const content: Array<ParsedContent<ParsedT>> = item.content.map((content) => {
|
|
@@ -149,7 +146,12 @@ export function hasAutoParseableInput(params: ResponseCreateParamsWithTools): bo
|
|
|
149
146
|
return true;
|
|
150
147
|
}
|
|
151
148
|
|
|
152
|
-
return
|
|
149
|
+
return (
|
|
150
|
+
Array.isArray(params.tools) &&
|
|
151
|
+
params.tools.some(
|
|
152
|
+
(tool) => isAutoParsableTool(tool) || (tool.type === 'function' && tool.strict === true),
|
|
153
|
+
)
|
|
154
|
+
);
|
|
153
155
|
}
|
|
154
156
|
|
|
155
157
|
type ToolOptions = {
|
package/src/lib/jsonschema.ts
CHANGED
|
@@ -61,6 +61,7 @@ export type JSONSchemaVersion = string;
|
|
|
61
61
|
*/
|
|
62
62
|
export type JSONSchemaDefinition = JSONSchema | boolean;
|
|
63
63
|
export interface JSONSchema {
|
|
64
|
+
$schema?: JSONSchemaVersion | undefined;
|
|
64
65
|
$id?: string | undefined;
|
|
65
66
|
$comment?: string | undefined;
|
|
66
67
|
|
|
@@ -86,6 +87,8 @@ export interface JSONSchema {
|
|
|
86
87
|
maxLength?: number | undefined;
|
|
87
88
|
minLength?: number | undefined;
|
|
88
89
|
pattern?: string | undefined;
|
|
90
|
+
contentEncoding?: string | undefined;
|
|
91
|
+
contentMediaType?: string | undefined;
|
|
89
92
|
|
|
90
93
|
/**
|
|
91
94
|
* @see https://tools.ietf.org/html/draft-handrews-json-schema-validation-01#section-6.4
|