@prestyj/ai 5.16.2 → 5.17.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/dist/index.cjs +145 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +145 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -572,6 +572,108 @@ function normalizeRootForAnthropic(schema) {
|
|
|
572
572
|
return out;
|
|
573
573
|
}
|
|
574
574
|
|
|
575
|
+
// src/utils/strict-tool-schema.ts
|
|
576
|
+
var UnsupportedStrictSchemaError = class extends Error {
|
|
577
|
+
};
|
|
578
|
+
var UNSUPPORTED_KEYS = [
|
|
579
|
+
"$ref",
|
|
580
|
+
"$defs",
|
|
581
|
+
"definitions",
|
|
582
|
+
"allOf",
|
|
583
|
+
"oneOf",
|
|
584
|
+
"patternProperties",
|
|
585
|
+
"dependentSchemas",
|
|
586
|
+
"dependencies",
|
|
587
|
+
"unevaluatedProperties",
|
|
588
|
+
"propertyNames",
|
|
589
|
+
"contains",
|
|
590
|
+
"prefixItems",
|
|
591
|
+
"not",
|
|
592
|
+
"if",
|
|
593
|
+
"then",
|
|
594
|
+
"else"
|
|
595
|
+
];
|
|
596
|
+
function isSchemaObject(value) {
|
|
597
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
598
|
+
}
|
|
599
|
+
function isStructured(value) {
|
|
600
|
+
if (!isSchemaObject(value)) return false;
|
|
601
|
+
const types = typeof value.type === "string" ? [value.type] : Array.isArray(value.type) ? value.type : [];
|
|
602
|
+
return types.includes("object") || types.includes("array") || value.properties !== void 0 || value.items !== void 0;
|
|
603
|
+
}
|
|
604
|
+
function allowsNull(schema) {
|
|
605
|
+
if (!isSchemaObject(schema)) return false;
|
|
606
|
+
if (schema.type === "null" || Array.isArray(schema.type) && schema.type.includes("null"))
|
|
607
|
+
return true;
|
|
608
|
+
if (schema.const === null || Array.isArray(schema.enum) && schema.enum.includes(null))
|
|
609
|
+
return true;
|
|
610
|
+
return Array.isArray(schema.anyOf) && schema.anyOf.some((variant) => allowsNull(variant));
|
|
611
|
+
}
|
|
612
|
+
function makeNodeStrict(schema) {
|
|
613
|
+
if (!isSchemaObject(schema)) {
|
|
614
|
+
throw new UnsupportedStrictSchemaError("boolean schemas are unsupported");
|
|
615
|
+
}
|
|
616
|
+
for (const key of UNSUPPORTED_KEYS) {
|
|
617
|
+
if (schema[key] !== void 0) {
|
|
618
|
+
throw new UnsupportedStrictSchemaError(`${key} schemas are unsupported`);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (schema.anyOf !== void 0) {
|
|
622
|
+
if (!Array.isArray(schema.anyOf) || schema.anyOf.length === 0) {
|
|
623
|
+
throw new UnsupportedStrictSchemaError("anyOf must contain at least one schema");
|
|
624
|
+
}
|
|
625
|
+
for (const variant of schema.anyOf) {
|
|
626
|
+
if (isStructured(variant)) {
|
|
627
|
+
throw new UnsupportedStrictSchemaError("object and array unions are unsupported");
|
|
628
|
+
}
|
|
629
|
+
makeNodeStrict(variant);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
if (schema.items !== void 0) {
|
|
633
|
+
if (Array.isArray(schema.items)) {
|
|
634
|
+
throw new UnsupportedStrictSchemaError("tuple schemas are unsupported");
|
|
635
|
+
}
|
|
636
|
+
makeNodeStrict(schema.items);
|
|
637
|
+
}
|
|
638
|
+
const isObjectSchema = schema.type === "object";
|
|
639
|
+
if (schema.properties !== void 0 && !isObjectSchema) {
|
|
640
|
+
throw new UnsupportedStrictSchemaError("properties require type object");
|
|
641
|
+
}
|
|
642
|
+
if (!isObjectSchema) return;
|
|
643
|
+
if (schema.additionalProperties !== void 0 && schema.additionalProperties !== false) {
|
|
644
|
+
throw new UnsupportedStrictSchemaError(
|
|
645
|
+
"schema-valued or true additionalProperties is unsupported"
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
if (schema.properties !== void 0 && !isSchemaObject(schema.properties)) {
|
|
649
|
+
throw new UnsupportedStrictSchemaError("object properties must be a schema map");
|
|
650
|
+
}
|
|
651
|
+
const properties = schema.properties ?? {};
|
|
652
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
653
|
+
for (const [key, property] of Object.entries(properties)) {
|
|
654
|
+
makeNodeStrict(property);
|
|
655
|
+
if (!required.has(key) && !allowsNull(property)) {
|
|
656
|
+
properties[key] = { anyOf: [property, { type: "null" }] };
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
schema.required = Object.keys(properties);
|
|
660
|
+
schema.additionalProperties = false;
|
|
661
|
+
}
|
|
662
|
+
function supportsStrictToolSampling(provider) {
|
|
663
|
+
return provider === "openai";
|
|
664
|
+
}
|
|
665
|
+
function makeStrictToolSchema(schema) {
|
|
666
|
+
const cloned = structuredClone(schema);
|
|
667
|
+
if (!isSchemaObject(cloned)) {
|
|
668
|
+
throw new UnsupportedStrictSchemaError("root schema must be an object");
|
|
669
|
+
}
|
|
670
|
+
makeNodeStrict(cloned);
|
|
671
|
+
if (cloned.type !== "object") {
|
|
672
|
+
throw new UnsupportedStrictSchemaError("root schema must have type object");
|
|
673
|
+
}
|
|
674
|
+
return cloned;
|
|
675
|
+
}
|
|
676
|
+
|
|
575
677
|
// src/providers/reasoning-field.ts
|
|
576
678
|
var REASONING_FIELD_ALIASES = [
|
|
577
679
|
"reasoning_content",
|
|
@@ -1156,15 +1258,28 @@ function toOpenAIMessages(messages, options) {
|
|
|
1156
1258
|
}
|
|
1157
1259
|
return out;
|
|
1158
1260
|
}
|
|
1159
|
-
function toOpenAITools(tools) {
|
|
1160
|
-
return tools.map((tool) =>
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1261
|
+
function toOpenAITools(tools, opts) {
|
|
1262
|
+
return tools.map((tool) => {
|
|
1263
|
+
let parameters = resolveToolSchema(tool);
|
|
1264
|
+
let strict;
|
|
1265
|
+
if (opts?.strict) {
|
|
1266
|
+
try {
|
|
1267
|
+
parameters = makeStrictToolSchema(parameters);
|
|
1268
|
+
strict = true;
|
|
1269
|
+
} catch (error) {
|
|
1270
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
1271
|
+
}
|
|
1166
1272
|
}
|
|
1167
|
-
|
|
1273
|
+
return {
|
|
1274
|
+
type: "function",
|
|
1275
|
+
function: {
|
|
1276
|
+
name: tool.name,
|
|
1277
|
+
description: tool.description,
|
|
1278
|
+
parameters,
|
|
1279
|
+
...strict ? { strict } : {}
|
|
1280
|
+
}
|
|
1281
|
+
};
|
|
1282
|
+
});
|
|
1168
1283
|
}
|
|
1169
1284
|
function toOpenAIToolChoice(choice) {
|
|
1170
1285
|
if (choice === "auto") return "auto";
|
|
@@ -2022,7 +2137,11 @@ async function* runStream2(options) {
|
|
|
2022
2137
|
...options.topP != null && !hasFixedKimiSampling ? { top_p: options.topP } : {},
|
|
2023
2138
|
...options.stop ? { stop: options.stop } : {},
|
|
2024
2139
|
...options.thinking && !usesThinkingParam && !isKimiK3 && !isKimiK27 && !isLocal ? { reasoning_effort: toOpenAIReasoningEffort(options.thinking, options.model) } : {},
|
|
2025
|
-
...options.tools?.length ? {
|
|
2140
|
+
...options.tools?.length ? {
|
|
2141
|
+
tools: toOpenAITools(options.tools, {
|
|
2142
|
+
strict: supportsStrictToolSampling(options.provider)
|
|
2143
|
+
})
|
|
2144
|
+
} : {},
|
|
2026
2145
|
...options.toolChoice && options.tools?.length ? { tool_choice: toOpenAIToolChoice(options.toolChoice) } : {},
|
|
2027
2146
|
...useStreaming ? { stream_options: { include_usage: true } } : {}
|
|
2028
2147
|
};
|
|
@@ -2980,13 +3099,23 @@ function toCodexInput(messages, options) {
|
|
|
2980
3099
|
return { system, input };
|
|
2981
3100
|
}
|
|
2982
3101
|
function toCodexTools(tools) {
|
|
2983
|
-
return tools.map((tool) =>
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
3102
|
+
return tools.map((tool) => {
|
|
3103
|
+
let parameters = resolveToolSchema(tool);
|
|
3104
|
+
let strict = null;
|
|
3105
|
+
try {
|
|
3106
|
+
parameters = makeStrictToolSchema(parameters);
|
|
3107
|
+
strict = true;
|
|
3108
|
+
} catch (error) {
|
|
3109
|
+
if (!(error instanceof UnsupportedStrictSchemaError)) throw error;
|
|
3110
|
+
}
|
|
3111
|
+
return {
|
|
3112
|
+
type: "function",
|
|
3113
|
+
name: tool.name,
|
|
3114
|
+
description: tool.description,
|
|
3115
|
+
parameters,
|
|
3116
|
+
strict
|
|
3117
|
+
};
|
|
3118
|
+
});
|
|
2990
3119
|
}
|
|
2991
3120
|
function parseCodexErrorBody(text, statusCode) {
|
|
2992
3121
|
if (!text) return {};
|