@ai-sdk-tool/parser 3.3.2 → 3.3.3
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/{chunk-OUGMLYAW.js → chunk-2KK5BDZF.js} +373 -8
- package/dist/chunk-2KK5BDZF.js.map +1 -0
- package/dist/{chunk-ZDBNJWLY.js → chunk-CXWS24JX.js} +2 -2
- package/dist/{chunk-5WKXBBCU.js → chunk-NAQSTPDQ.js} +696 -97
- package/dist/chunk-NAQSTPDQ.js.map +1 -0
- package/dist/community.cjs +1075 -113
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +3 -3
- package/dist/index.cjs +1075 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -8
- package/dist/index.d.ts +14 -8
- package/dist/index.js +3 -3
- package/dist/rxml.cjs +377 -12
- package/dist/rxml.cjs.map +1 -1
- package/dist/rxml.js +2 -2
- package/dist/schema-coerce.cjs +372 -7
- package/dist/schema-coerce.cjs.map +1 -1
- package/dist/schema-coerce.js +1 -1
- package/package.json +8 -8
- package/dist/chunk-5WKXBBCU.js.map +0 -1
- package/dist/chunk-OUGMLYAW.js.map +0 -1
- /package/dist/{chunk-ZDBNJWLY.js.map → chunk-CXWS24JX.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -1577,6 +1577,13 @@ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
|
|
|
1577
1577
|
var NEWLINE_SPLIT_REGEX = /\n+/;
|
|
1578
1578
|
var COMMA_SPLIT_REGEX = /,\s*/;
|
|
1579
1579
|
var DIGIT_KEY_REGEX = /^\d+$/;
|
|
1580
|
+
var WHITESPACE_REGEX2 = /\s+/g;
|
|
1581
|
+
var HAS_WHITESPACE_REGEX = /\s/;
|
|
1582
|
+
var SINGLE_QUOTE = "'";
|
|
1583
|
+
var DOUBLE_QUOTE = '"';
|
|
1584
|
+
var SNAKE_SEGMENT_REGEX = /_([a-zA-Z0-9])/g;
|
|
1585
|
+
var CAMEL_BOUNDARY_REGEX = /([a-z0-9])([A-Z])/g;
|
|
1586
|
+
var LEADING_UNDERSCORES_REGEX = /^_+/;
|
|
1580
1587
|
function unwrapJsonSchema(schema) {
|
|
1581
1588
|
if (!schema || typeof schema !== "object") {
|
|
1582
1589
|
return schema;
|
|
@@ -1825,9 +1832,158 @@ function coerceStringToArray(s, unwrapped) {
|
|
|
1825
1832
|
}
|
|
1826
1833
|
return null;
|
|
1827
1834
|
}
|
|
1835
|
+
function getStrictObjectSchemaInfo(unwrapped) {
|
|
1836
|
+
if (getSchemaType(unwrapped) !== "object") {
|
|
1837
|
+
return null;
|
|
1838
|
+
}
|
|
1839
|
+
if (unwrapped.additionalProperties !== false) {
|
|
1840
|
+
return null;
|
|
1841
|
+
}
|
|
1842
|
+
const properties = unwrapped.properties;
|
|
1843
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) {
|
|
1844
|
+
return null;
|
|
1845
|
+
}
|
|
1846
|
+
const propertyMap = properties;
|
|
1847
|
+
const required = Array.isArray(unwrapped.required) ? unwrapped.required.filter(
|
|
1848
|
+
(value) => typeof value === "string" && value.length > 0
|
|
1849
|
+
) : [];
|
|
1850
|
+
const patternProps = unwrapped.patternProperties;
|
|
1851
|
+
const patternProperties = patternProps && typeof patternProps === "object" && !Array.isArray(patternProps) ? patternProps : void 0;
|
|
1852
|
+
return {
|
|
1853
|
+
properties: propertyMap,
|
|
1854
|
+
required,
|
|
1855
|
+
patternProperties
|
|
1856
|
+
};
|
|
1857
|
+
}
|
|
1858
|
+
function isSingularPluralPair(left, right) {
|
|
1859
|
+
return left.length > 1 && right.length > 1 && (left === `${right}s` || right === `${left}s`);
|
|
1860
|
+
}
|
|
1861
|
+
function snakeToCamel(value) {
|
|
1862
|
+
const trimmed = value.replace(LEADING_UNDERSCORES_REGEX, "");
|
|
1863
|
+
if (trimmed.length === 0) {
|
|
1864
|
+
return value;
|
|
1865
|
+
}
|
|
1866
|
+
const camelized = trimmed.replace(
|
|
1867
|
+
SNAKE_SEGMENT_REGEX,
|
|
1868
|
+
(_, c) => c.toUpperCase()
|
|
1869
|
+
);
|
|
1870
|
+
return camelized.charAt(0).toLowerCase() + camelized.slice(1);
|
|
1871
|
+
}
|
|
1872
|
+
function camelToSnake(value) {
|
|
1873
|
+
return value.replace(CAMEL_BOUNDARY_REGEX, "$1_$2").toLowerCase();
|
|
1874
|
+
}
|
|
1875
|
+
function isCaseStylePair(targetKey, sourceKey) {
|
|
1876
|
+
if (targetKey === sourceKey) {
|
|
1877
|
+
return false;
|
|
1878
|
+
}
|
|
1879
|
+
const sourceLooksSnake = sourceKey.includes("_");
|
|
1880
|
+
const targetLooksSnake = targetKey.includes("_");
|
|
1881
|
+
if (sourceLooksSnake && snakeToCamel(sourceKey) === targetKey) {
|
|
1882
|
+
return true;
|
|
1883
|
+
}
|
|
1884
|
+
if (!sourceLooksSnake && targetLooksSnake && camelToSnake(sourceKey) === targetKey) {
|
|
1885
|
+
return true;
|
|
1886
|
+
}
|
|
1887
|
+
return false;
|
|
1888
|
+
}
|
|
1889
|
+
function isUnexpectedKey(key, schemaInfo) {
|
|
1890
|
+
if (Object.hasOwn(schemaInfo.properties, key)) {
|
|
1891
|
+
return false;
|
|
1892
|
+
}
|
|
1893
|
+
const patternSchemas = getPatternSchemasForKey(
|
|
1894
|
+
schemaInfo.patternProperties,
|
|
1895
|
+
key
|
|
1896
|
+
);
|
|
1897
|
+
if (patternSchemas.length > 0) {
|
|
1898
|
+
return patternSchemas.every((schema) => schema === false);
|
|
1899
|
+
}
|
|
1900
|
+
return true;
|
|
1901
|
+
}
|
|
1902
|
+
function computeMissingAndUnexpectedKeys(input, schemaInfo) {
|
|
1903
|
+
const missingRequired = schemaInfo.required.filter(
|
|
1904
|
+
(key) => !Object.hasOwn(input, key)
|
|
1905
|
+
);
|
|
1906
|
+
const unexpectedKeys = Object.keys(input).filter(
|
|
1907
|
+
(key) => isUnexpectedKey(key, schemaInfo)
|
|
1908
|
+
);
|
|
1909
|
+
return { missingRequired, unexpectedKeys };
|
|
1910
|
+
}
|
|
1911
|
+
function applySingularPluralRequiredKeyRename(input, schemaInfo) {
|
|
1912
|
+
const { missingRequired, unexpectedKeys } = computeMissingAndUnexpectedKeys(
|
|
1913
|
+
input,
|
|
1914
|
+
schemaInfo
|
|
1915
|
+
);
|
|
1916
|
+
if (missingRequired.length !== 1 || unexpectedKeys.length !== 1) {
|
|
1917
|
+
return null;
|
|
1918
|
+
}
|
|
1919
|
+
const targetKey = missingRequired[0];
|
|
1920
|
+
const sourceKey = unexpectedKeys[0];
|
|
1921
|
+
if (!Object.hasOwn(schemaInfo.properties, targetKey)) {
|
|
1922
|
+
return null;
|
|
1923
|
+
}
|
|
1924
|
+
if (!isSingularPluralPair(targetKey, sourceKey)) {
|
|
1925
|
+
return null;
|
|
1926
|
+
}
|
|
1927
|
+
if (getSchemaType(schemaInfo.properties[targetKey]) !== "array") {
|
|
1928
|
+
return null;
|
|
1929
|
+
}
|
|
1930
|
+
if (!Array.isArray(input[sourceKey])) {
|
|
1931
|
+
return null;
|
|
1932
|
+
}
|
|
1933
|
+
if (!Object.hasOwn(input, sourceKey) || Object.hasOwn(input, targetKey)) {
|
|
1934
|
+
return null;
|
|
1935
|
+
}
|
|
1936
|
+
const output = { ...input };
|
|
1937
|
+
output[targetKey] = output[sourceKey];
|
|
1938
|
+
delete output[sourceKey];
|
|
1939
|
+
return output;
|
|
1940
|
+
}
|
|
1941
|
+
function applyCaseStyleRequiredKeyRename(input, schemaInfo) {
|
|
1942
|
+
const { missingRequired, unexpectedKeys } = computeMissingAndUnexpectedKeys(
|
|
1943
|
+
input,
|
|
1944
|
+
schemaInfo
|
|
1945
|
+
);
|
|
1946
|
+
if (missingRequired.length !== 1 || unexpectedKeys.length !== 1) {
|
|
1947
|
+
return null;
|
|
1948
|
+
}
|
|
1949
|
+
const targetKey = missingRequired[0];
|
|
1950
|
+
const sourceKey = unexpectedKeys[0];
|
|
1951
|
+
if (!Object.hasOwn(schemaInfo.properties, targetKey)) {
|
|
1952
|
+
return null;
|
|
1953
|
+
}
|
|
1954
|
+
if (!isCaseStylePair(targetKey, sourceKey)) {
|
|
1955
|
+
return null;
|
|
1956
|
+
}
|
|
1957
|
+
if (!Object.hasOwn(input, sourceKey) || Object.hasOwn(input, targetKey)) {
|
|
1958
|
+
return null;
|
|
1959
|
+
}
|
|
1960
|
+
const output = { ...input };
|
|
1961
|
+
output[targetKey] = output[sourceKey];
|
|
1962
|
+
delete output[sourceKey];
|
|
1963
|
+
return output;
|
|
1964
|
+
}
|
|
1965
|
+
function applyStrictRequiredKeyRename(input, unwrapped) {
|
|
1966
|
+
const schemaInfo = getStrictObjectSchemaInfo(unwrapped);
|
|
1967
|
+
if (!schemaInfo) {
|
|
1968
|
+
return input;
|
|
1969
|
+
}
|
|
1970
|
+
const singularPlural = applySingularPluralRequiredKeyRename(
|
|
1971
|
+
input,
|
|
1972
|
+
schemaInfo
|
|
1973
|
+
);
|
|
1974
|
+
if (singularPlural) {
|
|
1975
|
+
return singularPlural;
|
|
1976
|
+
}
|
|
1977
|
+
const caseStyle = applyCaseStyleRequiredKeyRename(input, schemaInfo);
|
|
1978
|
+
if (caseStyle) {
|
|
1979
|
+
return caseStyle;
|
|
1980
|
+
}
|
|
1981
|
+
return input;
|
|
1982
|
+
}
|
|
1828
1983
|
function coerceObjectToObject(value, unwrapped) {
|
|
1984
|
+
const normalizedInput = applyStrictRequiredKeyRename(value, unwrapped);
|
|
1829
1985
|
const out = {};
|
|
1830
|
-
for (const [k, v] of Object.entries(
|
|
1986
|
+
for (const [k, v] of Object.entries(normalizedInput)) {
|
|
1831
1987
|
out[k] = coerceValueForKey(v, k, unwrapped);
|
|
1832
1988
|
}
|
|
1833
1989
|
return out;
|
|
@@ -1838,6 +1994,109 @@ function coerceArrayToArray(value, prefixItems, itemsSchema) {
|
|
|
1838
1994
|
}
|
|
1839
1995
|
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
1840
1996
|
}
|
|
1997
|
+
function isPrimitiveSchemaType(schemaType) {
|
|
1998
|
+
return schemaType === "string" || schemaType === "number" || schemaType === "integer" || schemaType === "boolean";
|
|
1999
|
+
}
|
|
2000
|
+
function isPrimitiveMatchForSchemaType(value, schemaType) {
|
|
2001
|
+
if (schemaType === "string") {
|
|
2002
|
+
return typeof value === "string";
|
|
2003
|
+
}
|
|
2004
|
+
if (schemaType === "number") {
|
|
2005
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
2006
|
+
}
|
|
2007
|
+
if (schemaType === "integer") {
|
|
2008
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value);
|
|
2009
|
+
}
|
|
2010
|
+
return typeof value === "boolean";
|
|
2011
|
+
}
|
|
2012
|
+
function coercePrimitiveWrappedObject(value, itemsSchema) {
|
|
2013
|
+
const schemaType = getSchemaType(itemsSchema);
|
|
2014
|
+
if (!isPrimitiveSchemaType(schemaType)) {
|
|
2015
|
+
return null;
|
|
2016
|
+
}
|
|
2017
|
+
const keys = Object.keys(value);
|
|
2018
|
+
if (keys.length !== 1) {
|
|
2019
|
+
return null;
|
|
2020
|
+
}
|
|
2021
|
+
const singleValue = value[keys[0]];
|
|
2022
|
+
if (singleValue && typeof singleValue === "object") {
|
|
2023
|
+
return null;
|
|
2024
|
+
}
|
|
2025
|
+
const coerced = coerceBySchema(singleValue, itemsSchema);
|
|
2026
|
+
return isPrimitiveMatchForSchemaType(coerced, schemaType) ? coerced : null;
|
|
2027
|
+
}
|
|
2028
|
+
function coerceParallelArraysObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
2029
|
+
if (prefixItems && prefixItems.length > 0) {
|
|
2030
|
+
return null;
|
|
2031
|
+
}
|
|
2032
|
+
const unwrappedItems = unwrapJsonSchema(itemsSchema);
|
|
2033
|
+
if (!unwrappedItems || typeof unwrappedItems !== "object" || Array.isArray(unwrappedItems)) {
|
|
2034
|
+
return null;
|
|
2035
|
+
}
|
|
2036
|
+
const itemSchema = unwrappedItems;
|
|
2037
|
+
if (getSchemaType(itemSchema) !== "object") {
|
|
2038
|
+
return null;
|
|
2039
|
+
}
|
|
2040
|
+
if (itemSchema.additionalProperties !== false) {
|
|
2041
|
+
return null;
|
|
2042
|
+
}
|
|
2043
|
+
const properties = itemSchema.properties;
|
|
2044
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) {
|
|
2045
|
+
return null;
|
|
2046
|
+
}
|
|
2047
|
+
const propertyMap = properties;
|
|
2048
|
+
const entries = Object.entries(maybe);
|
|
2049
|
+
if (entries.length < 2) {
|
|
2050
|
+
return null;
|
|
2051
|
+
}
|
|
2052
|
+
if (!entries.every(([, value]) => Array.isArray(value))) {
|
|
2053
|
+
return null;
|
|
2054
|
+
}
|
|
2055
|
+
if (!entries.every(([key]) => Object.hasOwn(propertyMap, key))) {
|
|
2056
|
+
return null;
|
|
2057
|
+
}
|
|
2058
|
+
if (!entries.every(([key]) => {
|
|
2059
|
+
const schemaType = getSchemaType(propertyMap[key]);
|
|
2060
|
+
return schemaType !== "array" && schemaType !== "object";
|
|
2061
|
+
})) {
|
|
2062
|
+
return null;
|
|
2063
|
+
}
|
|
2064
|
+
const lengths = [
|
|
2065
|
+
...new Set(entries.map(([, value]) => value.length))
|
|
2066
|
+
];
|
|
2067
|
+
if (lengths.length !== 1) {
|
|
2068
|
+
return null;
|
|
2069
|
+
}
|
|
2070
|
+
const length = lengths[0];
|
|
2071
|
+
if (length < 2) {
|
|
2072
|
+
return null;
|
|
2073
|
+
}
|
|
2074
|
+
const zipped = [];
|
|
2075
|
+
for (let index = 0; index < length; index += 1) {
|
|
2076
|
+
const item = {};
|
|
2077
|
+
for (const [key, value] of entries) {
|
|
2078
|
+
item[key] = value[index];
|
|
2079
|
+
}
|
|
2080
|
+
zipped.push(item);
|
|
2081
|
+
}
|
|
2082
|
+
return coerceArrayToArray(zipped, prefixItems, itemsSchema);
|
|
2083
|
+
}
|
|
2084
|
+
function coerceSingleKeyObjectToArray(singleValue, itemsSchema) {
|
|
2085
|
+
if (Array.isArray(singleValue)) {
|
|
2086
|
+
return singleValue.map((v) => coerceBySchema(v, itemsSchema));
|
|
2087
|
+
}
|
|
2088
|
+
if (singleValue && typeof singleValue === "object") {
|
|
2089
|
+
const primitiveWrapped = coercePrimitiveWrappedObject(
|
|
2090
|
+
singleValue,
|
|
2091
|
+
itemsSchema
|
|
2092
|
+
);
|
|
2093
|
+
if (primitiveWrapped !== null) {
|
|
2094
|
+
return [primitiveWrapped];
|
|
2095
|
+
}
|
|
2096
|
+
return [coerceBySchema(singleValue, itemsSchema)];
|
|
2097
|
+
}
|
|
2098
|
+
return null;
|
|
2099
|
+
}
|
|
1841
2100
|
function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
1842
2101
|
if (Object.hasOwn(maybe, "item")) {
|
|
1843
2102
|
const items = maybe.item;
|
|
@@ -1849,15 +2108,23 @@ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
|
1849
2108
|
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
1850
2109
|
return coerceArrayToArray(arr, prefixItems, itemsSchema);
|
|
1851
2110
|
}
|
|
2111
|
+
const parallelArrays = coerceParallelArraysObjectToArray(
|
|
2112
|
+
maybe,
|
|
2113
|
+
prefixItems,
|
|
2114
|
+
itemsSchema
|
|
2115
|
+
);
|
|
2116
|
+
if (parallelArrays !== null) {
|
|
2117
|
+
return parallelArrays;
|
|
2118
|
+
}
|
|
1852
2119
|
if (keys.length === 1) {
|
|
1853
2120
|
const singleKey = keys[0];
|
|
1854
2121
|
if (!(schemaIsUnconstrained(itemsSchema) || schemaHasProperty(itemsSchema, singleKey))) {
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
if (
|
|
1860
|
-
return
|
|
2122
|
+
const result = coerceSingleKeyObjectToArray(
|
|
2123
|
+
maybe[singleKey],
|
|
2124
|
+
itemsSchema
|
|
2125
|
+
);
|
|
2126
|
+
if (result !== null) {
|
|
2127
|
+
return result;
|
|
1861
2128
|
}
|
|
1862
2129
|
}
|
|
1863
2130
|
}
|
|
@@ -1887,6 +2154,86 @@ function coerceStringToPrimitive(s, schemaType) {
|
|
|
1887
2154
|
}
|
|
1888
2155
|
return null;
|
|
1889
2156
|
}
|
|
2157
|
+
function coercePrimitiveToString(value, schemaType) {
|
|
2158
|
+
if (schemaType !== "string") {
|
|
2159
|
+
return null;
|
|
2160
|
+
}
|
|
2161
|
+
if (typeof value === "boolean") {
|
|
2162
|
+
return value ? "true" : "false";
|
|
2163
|
+
}
|
|
2164
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2165
|
+
return String(value);
|
|
2166
|
+
}
|
|
2167
|
+
return null;
|
|
2168
|
+
}
|
|
2169
|
+
function coerceStringByEnumWhitespace(rawValue, unwrapped) {
|
|
2170
|
+
const enumValues = unwrapped.enum;
|
|
2171
|
+
if (!Array.isArray(enumValues) || enumValues.length === 0) {
|
|
2172
|
+
return null;
|
|
2173
|
+
}
|
|
2174
|
+
if (!enumValues.every((item) => typeof item === "string")) {
|
|
2175
|
+
return null;
|
|
2176
|
+
}
|
|
2177
|
+
const normalizedEnumValues = enumValues;
|
|
2178
|
+
if (normalizedEnumValues.includes(rawValue)) {
|
|
2179
|
+
return null;
|
|
2180
|
+
}
|
|
2181
|
+
const unquoted = unwrapMatchingQuotes(rawValue);
|
|
2182
|
+
if (unquoted !== null) {
|
|
2183
|
+
const exactMatches = normalizedEnumValues.filter(
|
|
2184
|
+
(item) => item === unquoted
|
|
2185
|
+
);
|
|
2186
|
+
if (exactMatches.length === 1) {
|
|
2187
|
+
return exactMatches[0];
|
|
2188
|
+
}
|
|
2189
|
+
}
|
|
2190
|
+
const candidates = [rawValue, unquoted].filter(
|
|
2191
|
+
(item) => item !== null
|
|
2192
|
+
);
|
|
2193
|
+
for (const candidate of candidates) {
|
|
2194
|
+
if (!HAS_WHITESPACE_REGEX.test(candidate)) {
|
|
2195
|
+
continue;
|
|
2196
|
+
}
|
|
2197
|
+
const normalizedInput = candidate.replace(WHITESPACE_REGEX2, "");
|
|
2198
|
+
const matches = normalizedEnumValues.filter(
|
|
2199
|
+
(item) => item.replace(WHITESPACE_REGEX2, "") === normalizedInput
|
|
2200
|
+
);
|
|
2201
|
+
if (matches.length === 1) {
|
|
2202
|
+
return matches[0];
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
return null;
|
|
2206
|
+
}
|
|
2207
|
+
function unwrapMatchingQuotes(value) {
|
|
2208
|
+
if (value.length < 2) {
|
|
2209
|
+
return null;
|
|
2210
|
+
}
|
|
2211
|
+
const first = value[0];
|
|
2212
|
+
const last = value.at(-1);
|
|
2213
|
+
const isQuote = (first === SINGLE_QUOTE || first === DOUBLE_QUOTE) && first === last;
|
|
2214
|
+
if (!isQuote) {
|
|
2215
|
+
return null;
|
|
2216
|
+
}
|
|
2217
|
+
return value.slice(1, -1);
|
|
2218
|
+
}
|
|
2219
|
+
function coerceObjectToPrimitive(value, schemaType, fullSchema) {
|
|
2220
|
+
if (!isPrimitiveSchemaType(schemaType)) {
|
|
2221
|
+
return null;
|
|
2222
|
+
}
|
|
2223
|
+
const keys = Object.keys(value);
|
|
2224
|
+
if (keys.length !== 1) {
|
|
2225
|
+
return null;
|
|
2226
|
+
}
|
|
2227
|
+
const singleValue = value[keys[0]];
|
|
2228
|
+
if (singleValue && typeof singleValue === "object") {
|
|
2229
|
+
return null;
|
|
2230
|
+
}
|
|
2231
|
+
const coerced = coerceBySchema(
|
|
2232
|
+
singleValue,
|
|
2233
|
+
fullSchema != null ? fullSchema : { type: schemaType }
|
|
2234
|
+
);
|
|
2235
|
+
return isPrimitiveMatchForSchemaType(coerced, schemaType) ? coerced : null;
|
|
2236
|
+
}
|
|
1890
2237
|
function coerceStringValue(value, schemaType, u) {
|
|
1891
2238
|
const s = value.trim();
|
|
1892
2239
|
if (schemaType === "object") {
|
|
@@ -1905,6 +2252,10 @@ function coerceStringValue(value, schemaType, u) {
|
|
|
1905
2252
|
if (primitiveResult !== null) {
|
|
1906
2253
|
return primitiveResult;
|
|
1907
2254
|
}
|
|
2255
|
+
const enumWhitespaceCanonical = coerceStringByEnumWhitespace(s, u);
|
|
2256
|
+
if (enumWhitespaceCanonical !== null) {
|
|
2257
|
+
return enumWhitespaceCanonical;
|
|
2258
|
+
}
|
|
1908
2259
|
return value;
|
|
1909
2260
|
}
|
|
1910
2261
|
function coerceArrayValue(value, prefixItems, itemsSchema) {
|
|
@@ -1943,9 +2294,23 @@ function coerceBySchema(value, schema) {
|
|
|
1943
2294
|
if (typeof value === "string") {
|
|
1944
2295
|
return coerceStringValue(value, schemaType, u);
|
|
1945
2296
|
}
|
|
2297
|
+
const primitiveString = coercePrimitiveToString(value, schemaType);
|
|
2298
|
+
if (primitiveString !== null) {
|
|
2299
|
+
return primitiveString;
|
|
2300
|
+
}
|
|
1946
2301
|
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
1947
2302
|
return coerceObjectToObject(value, u);
|
|
1948
2303
|
}
|
|
2304
|
+
if (value && typeof value === "object" && !Array.isArray(value) && isPrimitiveSchemaType(schemaType)) {
|
|
2305
|
+
const primitiveResult = coerceObjectToPrimitive(
|
|
2306
|
+
value,
|
|
2307
|
+
schemaType,
|
|
2308
|
+
u
|
|
2309
|
+
);
|
|
2310
|
+
if (primitiveResult !== null) {
|
|
2311
|
+
return primitiveResult;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
1949
2314
|
if (schemaType === "array") {
|
|
1950
2315
|
const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
|
|
1951
2316
|
const itemsSchema = u.items;
|
|
@@ -2960,7 +3325,7 @@ var XMLTokenizer = class {
|
|
|
2960
3325
|
};
|
|
2961
3326
|
|
|
2962
3327
|
// src/rxml/core/parser.ts
|
|
2963
|
-
var
|
|
3328
|
+
var WHITESPACE_REGEX3 = /\s/;
|
|
2964
3329
|
var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2965
3330
|
var DIGIT_KEY_REGEX2 = /^\d+$/;
|
|
2966
3331
|
function getTopLevelStringProps(s) {
|
|
@@ -3130,7 +3495,7 @@ function parse2(xmlInner, schema, options = {}) {
|
|
|
3130
3495
|
const closeHead = s.indexOf(`</${rootName}`, range.end);
|
|
3131
3496
|
if (closeHead === range.end) {
|
|
3132
3497
|
let p = closeHead + 2 + rootName.length;
|
|
3133
|
-
while (p < s.length &&
|
|
3498
|
+
while (p < s.length && WHITESPACE_REGEX3.test(s[p])) {
|
|
3134
3499
|
p += 1;
|
|
3135
3500
|
}
|
|
3136
3501
|
if (s[p] === ">") {
|
|
@@ -3468,7 +3833,7 @@ function createIntermediateCall(toolName, rawSegment, schema) {
|
|
|
3468
3833
|
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
3469
3834
|
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
3470
3835
|
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
3471
|
-
var
|
|
3836
|
+
var WHITESPACE_REGEX4 = /\s/;
|
|
3472
3837
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
3473
3838
|
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
3474
3839
|
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
@@ -3609,7 +3974,7 @@ function balanceTags(xml) {
|
|
|
3609
3974
|
}
|
|
3610
3975
|
function skipWs(s, p, len) {
|
|
3611
3976
|
let idx = p;
|
|
3612
|
-
while (idx < len &&
|
|
3977
|
+
while (idx < len && WHITESPACE_REGEX4.test(s[idx])) {
|
|
3613
3978
|
idx += 1;
|
|
3614
3979
|
}
|
|
3615
3980
|
return idx;
|
|
@@ -3662,7 +4027,7 @@ function handleOpeningTagSegment(src, lt, out, stack) {
|
|
|
3662
4027
|
return len;
|
|
3663
4028
|
}
|
|
3664
4029
|
let r = q - 1;
|
|
3665
|
-
while (r >= nameStart &&
|
|
4030
|
+
while (r >= nameStart && WHITESPACE_REGEX4.test(src[r])) {
|
|
3666
4031
|
r -= 1;
|
|
3667
4032
|
}
|
|
3668
4033
|
const selfClosing = src[r] === "/";
|
|
@@ -3826,7 +4191,31 @@ function parse3(xml, schema, options = {}) {
|
|
|
3826
4191
|
|
|
3827
4192
|
// src/core/utils/regex-constants.ts
|
|
3828
4193
|
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
3829
|
-
var
|
|
4194
|
+
var WHITESPACE_REGEX5 = /\s/;
|
|
4195
|
+
|
|
4196
|
+
// src/core/utils/xml-root-repair.ts
|
|
4197
|
+
var XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX = /^<([A-Za-z_][A-Za-z0-9_-]*)\s*\r?\n([\s\S]+?)\r?\n\s*\/>\s*$/;
|
|
4198
|
+
function tryRepairXmlSelfClosingRootWithBody(rawText, toolNames) {
|
|
4199
|
+
const trimmed = rawText.trim();
|
|
4200
|
+
if (trimmed.length === 0) {
|
|
4201
|
+
return null;
|
|
4202
|
+
}
|
|
4203
|
+
const match = trimmed.match(XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX);
|
|
4204
|
+
if (!match) {
|
|
4205
|
+
return null;
|
|
4206
|
+
}
|
|
4207
|
+
const rootTag = match[1];
|
|
4208
|
+
if (!toolNames.includes(rootTag)) {
|
|
4209
|
+
return null;
|
|
4210
|
+
}
|
|
4211
|
+
const body = match[2].trimEnd();
|
|
4212
|
+
if (body.trim().length === 0 || body.includes(`</${rootTag}>`)) {
|
|
4213
|
+
return null;
|
|
4214
|
+
}
|
|
4215
|
+
return `<${rootTag}>
|
|
4216
|
+
${body}
|
|
4217
|
+
</${rootTag}>`;
|
|
4218
|
+
}
|
|
3830
4219
|
|
|
3831
4220
|
// src/core/protocols/xml-protocol.ts
|
|
3832
4221
|
function getToolSchema(tools, toolName) {
|
|
@@ -3930,7 +4319,7 @@ function consumeClosingTag(text, lt) {
|
|
|
3930
4319
|
}
|
|
3931
4320
|
function consumeOpenTag(text, lt) {
|
|
3932
4321
|
let p = lt + 1;
|
|
3933
|
-
while (p < text.length &&
|
|
4322
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3934
4323
|
p += 1;
|
|
3935
4324
|
}
|
|
3936
4325
|
const nameStart = p;
|
|
@@ -3943,7 +4332,7 @@ function consumeOpenTag(text, lt) {
|
|
|
3943
4332
|
return null;
|
|
3944
4333
|
}
|
|
3945
4334
|
let r = q - 1;
|
|
3946
|
-
while (r >= nameStart &&
|
|
4335
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
3947
4336
|
r -= 1;
|
|
3948
4337
|
}
|
|
3949
4338
|
const selfClosing = text[r] === "/";
|
|
@@ -3972,7 +4361,7 @@ function nextTagToken(text, fromPos) {
|
|
|
3972
4361
|
if (next === "/") {
|
|
3973
4362
|
const closing = consumeClosingTag(text, lt);
|
|
3974
4363
|
let p = lt + 2;
|
|
3975
|
-
while (p < text.length &&
|
|
4364
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3976
4365
|
p += 1;
|
|
3977
4366
|
}
|
|
3978
4367
|
const nameStart = p;
|
|
@@ -4109,6 +4498,102 @@ function findToolCalls(text, toolNames) {
|
|
|
4109
4498
|
}
|
|
4110
4499
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4111
4500
|
}
|
|
4501
|
+
function handleSpecialToken(depth) {
|
|
4502
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: false };
|
|
4503
|
+
}
|
|
4504
|
+
function handleOpenToken(token, depth, lastCompleteEnd) {
|
|
4505
|
+
if (token.selfClosing) {
|
|
4506
|
+
return {
|
|
4507
|
+
depth,
|
|
4508
|
+
lastCompleteEnd: depth === 0 ? token.nextPos : lastCompleteEnd,
|
|
4509
|
+
shouldBreak: false
|
|
4510
|
+
};
|
|
4511
|
+
}
|
|
4512
|
+
return { depth: depth + 1, lastCompleteEnd, shouldBreak: false };
|
|
4513
|
+
}
|
|
4514
|
+
function handleCloseToken(token, depth) {
|
|
4515
|
+
if (depth <= 0) {
|
|
4516
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: true };
|
|
4517
|
+
}
|
|
4518
|
+
const newDepth = depth - 1;
|
|
4519
|
+
return {
|
|
4520
|
+
depth: newDepth,
|
|
4521
|
+
lastCompleteEnd: newDepth === 0 ? token.nextPos : -1,
|
|
4522
|
+
shouldBreak: false
|
|
4523
|
+
};
|
|
4524
|
+
}
|
|
4525
|
+
function findLinePrefixedXmlBodyEnd(text, bodyStartIndex) {
|
|
4526
|
+
let cursor = bodyStartIndex;
|
|
4527
|
+
let depth = 0;
|
|
4528
|
+
let lastCompleteEnd = -1;
|
|
4529
|
+
while (cursor < text.length) {
|
|
4530
|
+
if (depth === 0) {
|
|
4531
|
+
cursor = consumeWhitespace(text, cursor);
|
|
4532
|
+
if (cursor >= text.length || text.charAt(cursor) !== "<") {
|
|
4533
|
+
break;
|
|
4534
|
+
}
|
|
4535
|
+
}
|
|
4536
|
+
const token = nextTagToken(text, cursor);
|
|
4537
|
+
if (token.kind === "eof") {
|
|
4538
|
+
break;
|
|
4539
|
+
}
|
|
4540
|
+
let result;
|
|
4541
|
+
if (token.kind === "special") {
|
|
4542
|
+
result = handleSpecialToken(depth);
|
|
4543
|
+
} else if (token.kind === "open") {
|
|
4544
|
+
result = handleOpenToken(token, depth, lastCompleteEnd);
|
|
4545
|
+
} else {
|
|
4546
|
+
result = handleCloseToken(token, depth);
|
|
4547
|
+
}
|
|
4548
|
+
depth = result.depth;
|
|
4549
|
+
if (result.lastCompleteEnd !== -1) {
|
|
4550
|
+
lastCompleteEnd = result.lastCompleteEnd;
|
|
4551
|
+
}
|
|
4552
|
+
if (result.shouldBreak) {
|
|
4553
|
+
break;
|
|
4554
|
+
}
|
|
4555
|
+
cursor = token.nextPos;
|
|
4556
|
+
}
|
|
4557
|
+
return lastCompleteEnd;
|
|
4558
|
+
}
|
|
4559
|
+
function findLinePrefixedToolCall(text, toolNames) {
|
|
4560
|
+
var _a;
|
|
4561
|
+
let best = null;
|
|
4562
|
+
for (const toolName of toolNames) {
|
|
4563
|
+
const linePattern = new RegExp(
|
|
4564
|
+
`(^|\\n)[\\t ]*${escapeRegExp(toolName)}[\\t ]*:?[\\t ]*(?:\\r?\\n|$)`,
|
|
4565
|
+
"g"
|
|
4566
|
+
);
|
|
4567
|
+
let match = linePattern.exec(text);
|
|
4568
|
+
while (match !== null) {
|
|
4569
|
+
const prefix = (_a = match[1]) != null ? _a : "";
|
|
4570
|
+
const startIndex = match.index + prefix.length;
|
|
4571
|
+
const contentStart = consumeWhitespace(text, linePattern.lastIndex);
|
|
4572
|
+
if (contentStart >= text.length || text.charAt(contentStart) !== "<") {
|
|
4573
|
+
match = linePattern.exec(text);
|
|
4574
|
+
continue;
|
|
4575
|
+
}
|
|
4576
|
+
const contentEnd = findLinePrefixedXmlBodyEnd(text, contentStart);
|
|
4577
|
+
if (contentEnd === -1 || contentEnd <= contentStart) {
|
|
4578
|
+
match = linePattern.exec(text);
|
|
4579
|
+
continue;
|
|
4580
|
+
}
|
|
4581
|
+
const content = text.slice(contentStart, contentEnd);
|
|
4582
|
+
const candidate = {
|
|
4583
|
+
toolName,
|
|
4584
|
+
startIndex,
|
|
4585
|
+
endIndex: contentEnd,
|
|
4586
|
+
content,
|
|
4587
|
+
segment: text.slice(startIndex, contentEnd)
|
|
4588
|
+
};
|
|
4589
|
+
if (best === null || candidate.startIndex < best.startIndex) {
|
|
4590
|
+
best = candidate;
|
|
4591
|
+
}
|
|
4592
|
+
break;
|
|
4593
|
+
}
|
|
4594
|
+
}
|
|
4595
|
+
return best;
|
|
4596
|
+
}
|
|
4112
4597
|
function findEarliestToolTag(buffer, toolNames) {
|
|
4113
4598
|
var _a, _b;
|
|
4114
4599
|
let bestIndex = -1;
|
|
@@ -4147,7 +4632,7 @@ function isOpenTagPrefix(suffix, toolName) {
|
|
|
4147
4632
|
}
|
|
4148
4633
|
function consumeWhitespace(text, index) {
|
|
4149
4634
|
let i = index;
|
|
4150
|
-
while (i < text.length &&
|
|
4635
|
+
while (i < text.length && WHITESPACE_REGEX5.test(text.charAt(i))) {
|
|
4151
4636
|
i += 1;
|
|
4152
4637
|
}
|
|
4153
4638
|
return i;
|
|
@@ -4398,6 +4883,27 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
4398
4883
|
}
|
|
4399
4884
|
};
|
|
4400
4885
|
}
|
|
4886
|
+
function findToolCallsWithFallbacks(text, toolNames) {
|
|
4887
|
+
let parseText = text;
|
|
4888
|
+
let toolCalls = findToolCalls(parseText, toolNames);
|
|
4889
|
+
if (toolCalls.length === 0) {
|
|
4890
|
+
const fallbackToolCall = findLinePrefixedToolCall(parseText, toolNames);
|
|
4891
|
+
if (fallbackToolCall !== null) {
|
|
4892
|
+
toolCalls.push(fallbackToolCall);
|
|
4893
|
+
}
|
|
4894
|
+
}
|
|
4895
|
+
if (toolCalls.length === 0) {
|
|
4896
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(parseText, toolNames);
|
|
4897
|
+
if (repaired) {
|
|
4898
|
+
const repairedCalls = findToolCalls(repaired, toolNames);
|
|
4899
|
+
if (repairedCalls.length > 0) {
|
|
4900
|
+
parseText = repaired;
|
|
4901
|
+
toolCalls = repairedCalls;
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
}
|
|
4905
|
+
return { parseText, toolCalls };
|
|
4906
|
+
}
|
|
4401
4907
|
var xmlProtocol = (protocolOptions) => {
|
|
4402
4908
|
var _a;
|
|
4403
4909
|
const parseOptions = {
|
|
@@ -4431,28 +4937,31 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4431
4937
|
}
|
|
4432
4938
|
const processedElements = [];
|
|
4433
4939
|
let currentIndex = 0;
|
|
4434
|
-
const toolCalls =
|
|
4940
|
+
const { parseText, toolCalls } = findToolCallsWithFallbacks(
|
|
4941
|
+
text,
|
|
4942
|
+
toolNames
|
|
4943
|
+
);
|
|
4435
4944
|
for (const tc of toolCalls) {
|
|
4436
4945
|
if (tc.startIndex > currentIndex) {
|
|
4437
4946
|
processedElements.push({
|
|
4438
4947
|
type: "text",
|
|
4439
|
-
text:
|
|
4948
|
+
text: parseText.substring(currentIndex, tc.startIndex)
|
|
4440
4949
|
});
|
|
4441
4950
|
}
|
|
4442
4951
|
processToolCall({
|
|
4443
4952
|
toolCall: tc,
|
|
4444
4953
|
tools,
|
|
4445
4954
|
options,
|
|
4446
|
-
text,
|
|
4955
|
+
text: parseText,
|
|
4447
4956
|
processedElements,
|
|
4448
4957
|
parseOptions
|
|
4449
4958
|
});
|
|
4450
4959
|
currentIndex = tc.endIndex;
|
|
4451
4960
|
}
|
|
4452
|
-
if (currentIndex <
|
|
4961
|
+
if (currentIndex < parseText.length) {
|
|
4453
4962
|
processedElements.push({
|
|
4454
4963
|
type: "text",
|
|
4455
|
-
text:
|
|
4964
|
+
text: parseText.substring(currentIndex)
|
|
4456
4965
|
});
|
|
4457
4966
|
}
|
|
4458
4967
|
return processedElements;
|
|
@@ -4491,6 +5000,20 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4491
5000
|
return new TransformStream({
|
|
4492
5001
|
transform(chunk, controller) {
|
|
4493
5002
|
var _a2;
|
|
5003
|
+
if (chunk.type === "finish") {
|
|
5004
|
+
if (currentToolCall) {
|
|
5005
|
+
const unfinishedContent = `<${currentToolCall.name}>${currentToolCall.content}${buffer}`;
|
|
5006
|
+
flushText(controller, unfinishedContent);
|
|
5007
|
+
buffer = "";
|
|
5008
|
+
currentToolCall = null;
|
|
5009
|
+
} else if (buffer) {
|
|
5010
|
+
flushText(controller, buffer);
|
|
5011
|
+
buffer = "";
|
|
5012
|
+
}
|
|
5013
|
+
flushText(controller);
|
|
5014
|
+
controller.enqueue(chunk);
|
|
5015
|
+
return;
|
|
5016
|
+
}
|
|
4494
5017
|
if (chunk.type !== "text-delta") {
|
|
4495
5018
|
if (buffer) {
|
|
4496
5019
|
flushText(controller, buffer);
|
|
@@ -4552,7 +5075,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4552
5075
|
break;
|
|
4553
5076
|
}
|
|
4554
5077
|
let p = ltIdx + 2;
|
|
4555
|
-
while (p < gtIdx &&
|
|
5078
|
+
while (p < gtIdx && WHITESPACE_REGEX5.test(text[p])) {
|
|
4556
5079
|
p++;
|
|
4557
5080
|
}
|
|
4558
5081
|
const nameStart = p;
|
|
@@ -4572,7 +5095,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4572
5095
|
pos = gtIdx === -1 ? text.length : gtIdx + 1;
|
|
4573
5096
|
} else {
|
|
4574
5097
|
let p = ltIdx + 1;
|
|
4575
|
-
while (p < text.length &&
|
|
5098
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
4576
5099
|
p++;
|
|
4577
5100
|
}
|
|
4578
5101
|
const nameStart = p;
|
|
@@ -4585,7 +5108,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4585
5108
|
break;
|
|
4586
5109
|
}
|
|
4587
5110
|
let r = gtIdx - 1;
|
|
4588
|
-
while (r >= nameStart &&
|
|
5111
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
4589
5112
|
r--;
|
|
4590
5113
|
}
|
|
4591
5114
|
const selfClosing = text[r] === "/";
|
|
@@ -4817,18 +5340,32 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4817
5340
|
}
|
|
4818
5341
|
const processedElements = [];
|
|
4819
5342
|
let currentIndex = 0;
|
|
4820
|
-
|
|
5343
|
+
let parseText = text;
|
|
5344
|
+
let toolCalls = findToolCalls2(parseText, toolNames);
|
|
5345
|
+
if (toolCalls.length === 0) {
|
|
5346
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(
|
|
5347
|
+
parseText,
|
|
5348
|
+
toolNames
|
|
5349
|
+
);
|
|
5350
|
+
if (repaired) {
|
|
5351
|
+
const repairedCalls = findToolCalls2(repaired, toolNames);
|
|
5352
|
+
if (repairedCalls.length > 0) {
|
|
5353
|
+
parseText = repaired;
|
|
5354
|
+
toolCalls = repairedCalls;
|
|
5355
|
+
}
|
|
5356
|
+
}
|
|
5357
|
+
}
|
|
4821
5358
|
for (const tc of toolCalls) {
|
|
4822
5359
|
currentIndex = processToolCallMatch(
|
|
4823
|
-
|
|
5360
|
+
parseText,
|
|
4824
5361
|
tc,
|
|
4825
5362
|
currentIndex,
|
|
4826
5363
|
processedElements,
|
|
4827
5364
|
options
|
|
4828
5365
|
);
|
|
4829
5366
|
}
|
|
4830
|
-
if (currentIndex <
|
|
4831
|
-
addTextSegment(
|
|
5367
|
+
if (currentIndex < parseText.length) {
|
|
5368
|
+
addTextSegment(parseText.substring(currentIndex), processedElements);
|
|
4832
5369
|
}
|
|
4833
5370
|
return processedElements;
|
|
4834
5371
|
},
|
|
@@ -4924,6 +5461,20 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4924
5461
|
return new TransformStream({
|
|
4925
5462
|
transform(chunk, controller) {
|
|
4926
5463
|
var _a;
|
|
5464
|
+
if (chunk.type === "finish") {
|
|
5465
|
+
if (currentToolCall) {
|
|
5466
|
+
const unfinishedContent = `<${currentToolCall.name}>${buffer}`;
|
|
5467
|
+
flushText(controller, unfinishedContent);
|
|
5468
|
+
buffer = "";
|
|
5469
|
+
currentToolCall = null;
|
|
5470
|
+
} else if (buffer) {
|
|
5471
|
+
flushText(controller, buffer);
|
|
5472
|
+
buffer = "";
|
|
5473
|
+
}
|
|
5474
|
+
flushText(controller);
|
|
5475
|
+
controller.enqueue(chunk);
|
|
5476
|
+
return;
|
|
5477
|
+
}
|
|
4927
5478
|
if (chunk.type !== "text-delta") {
|
|
4928
5479
|
if (buffer) {
|
|
4929
5480
|
flushText(controller, buffer);
|
|
@@ -5047,17 +5598,56 @@ function encodeOriginalTools(tools) {
|
|
|
5047
5598
|
inputSchema: JSON.stringify(t.inputSchema)
|
|
5048
5599
|
}))) || [];
|
|
5049
5600
|
}
|
|
5050
|
-
function decodeOriginalTools(originalTools) {
|
|
5601
|
+
function decodeOriginalTools(originalTools, options) {
|
|
5602
|
+
var _a, _b, _c;
|
|
5051
5603
|
if (!originalTools) {
|
|
5052
5604
|
return [];
|
|
5053
5605
|
}
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
|
-
|
|
5606
|
+
const decodedTools = [];
|
|
5607
|
+
for (const [index, tool] of originalTools.entries()) {
|
|
5608
|
+
if (!tool || typeof tool.name !== "string") {
|
|
5609
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Invalid originalTools entry: missing tool name", {
|
|
5610
|
+
index,
|
|
5611
|
+
tool
|
|
5612
|
+
});
|
|
5613
|
+
continue;
|
|
5614
|
+
}
|
|
5615
|
+
if (typeof tool.inputSchema !== "string") {
|
|
5616
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
5617
|
+
options,
|
|
5618
|
+
"Invalid originalTools entry: inputSchema must be a string",
|
|
5619
|
+
{
|
|
5620
|
+
index,
|
|
5621
|
+
toolName: tool.name
|
|
5622
|
+
}
|
|
5623
|
+
);
|
|
5624
|
+
continue;
|
|
5625
|
+
}
|
|
5626
|
+
try {
|
|
5627
|
+
decodedTools.push({
|
|
5628
|
+
type: "function",
|
|
5629
|
+
name: tool.name,
|
|
5630
|
+
inputSchema: JSON.parse(tool.inputSchema)
|
|
5631
|
+
});
|
|
5632
|
+
} catch (error) {
|
|
5633
|
+
(_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(
|
|
5634
|
+
options,
|
|
5635
|
+
"Failed to decode originalTools input schema, using permissive fallback schema",
|
|
5636
|
+
{
|
|
5637
|
+
index,
|
|
5638
|
+
toolName: tool.name,
|
|
5639
|
+
inputSchema: tool.inputSchema,
|
|
5640
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5641
|
+
}
|
|
5642
|
+
);
|
|
5643
|
+
decodedTools.push({
|
|
5644
|
+
type: "function",
|
|
5645
|
+
name: tool.name,
|
|
5646
|
+
inputSchema: { type: "object" }
|
|
5647
|
+
});
|
|
5648
|
+
}
|
|
5649
|
+
}
|
|
5650
|
+
return decodedTools;
|
|
5061
5651
|
}
|
|
5062
5652
|
function extractToolNamesFromOriginalTools(originalTools) {
|
|
5063
5653
|
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
@@ -5082,23 +5672,337 @@ function hasInputProperty(obj) {
|
|
|
5082
5672
|
|
|
5083
5673
|
// src/generate-handler.ts
|
|
5084
5674
|
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
5085
|
-
|
|
5675
|
+
|
|
5676
|
+
// src/core/utils/generated-text-json-recovery.ts
|
|
5677
|
+
function isRecord(value) {
|
|
5678
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5679
|
+
}
|
|
5680
|
+
function safeStringify2(value) {
|
|
5681
|
+
try {
|
|
5682
|
+
return JSON.stringify(value != null ? value : {});
|
|
5683
|
+
} catch (e) {
|
|
5684
|
+
return "{}";
|
|
5685
|
+
}
|
|
5686
|
+
}
|
|
5687
|
+
function parseJsonCandidate(candidateText) {
|
|
5688
|
+
try {
|
|
5689
|
+
return parse(candidateText);
|
|
5690
|
+
} catch (e) {
|
|
5691
|
+
return void 0;
|
|
5692
|
+
}
|
|
5693
|
+
}
|
|
5694
|
+
function extractCodeBlockCandidates(text) {
|
|
5695
|
+
var _a, _b;
|
|
5696
|
+
const codeBlockRegex = /```(?:json|yaml|xml)?\s*([\s\S]*?)```/gi;
|
|
5697
|
+
const candidates = [];
|
|
5698
|
+
let match;
|
|
5699
|
+
while (true) {
|
|
5700
|
+
match = codeBlockRegex.exec(text);
|
|
5701
|
+
if (!match) {
|
|
5702
|
+
break;
|
|
5703
|
+
}
|
|
5704
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
5705
|
+
if (body) {
|
|
5706
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
5707
|
+
const endIndex = startIndex + match[0].length;
|
|
5708
|
+
candidates.push({
|
|
5709
|
+
text: body,
|
|
5710
|
+
startIndex,
|
|
5711
|
+
endIndex
|
|
5712
|
+
});
|
|
5713
|
+
}
|
|
5714
|
+
}
|
|
5715
|
+
return candidates;
|
|
5716
|
+
}
|
|
5717
|
+
function scanJsonChar(state, char) {
|
|
5718
|
+
if (state.inString) {
|
|
5719
|
+
if (state.escaping) {
|
|
5720
|
+
return { ...state, escaping: false };
|
|
5721
|
+
}
|
|
5722
|
+
if (char === "\\") {
|
|
5723
|
+
return { ...state, escaping: true };
|
|
5724
|
+
}
|
|
5725
|
+
if (char === '"') {
|
|
5726
|
+
return { ...state, inString: false };
|
|
5727
|
+
}
|
|
5728
|
+
return state;
|
|
5729
|
+
}
|
|
5730
|
+
if (char === '"') {
|
|
5731
|
+
return { ...state, inString: true };
|
|
5732
|
+
}
|
|
5733
|
+
if (char === "{") {
|
|
5734
|
+
return { ...state, depth: state.depth + 1 };
|
|
5735
|
+
}
|
|
5736
|
+
if (char === "}") {
|
|
5737
|
+
return { ...state, depth: Math.max(0, state.depth - 1) };
|
|
5738
|
+
}
|
|
5739
|
+
return state;
|
|
5740
|
+
}
|
|
5741
|
+
function extractBalancedJsonObjects(text) {
|
|
5742
|
+
const maxCandidateLength = 1e4;
|
|
5743
|
+
const candidates = [];
|
|
5744
|
+
let state = { depth: 0, inString: false, escaping: false };
|
|
5745
|
+
let currentStart = null;
|
|
5746
|
+
let ignoreCurrent = false;
|
|
5747
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
5748
|
+
const char = text[index];
|
|
5749
|
+
if (!state.inString && char === "{" && state.depth === 0) {
|
|
5750
|
+
currentStart = index;
|
|
5751
|
+
ignoreCurrent = false;
|
|
5752
|
+
}
|
|
5753
|
+
state = scanJsonChar(state, char);
|
|
5754
|
+
if (currentStart !== null && !ignoreCurrent && index - currentStart + 1 > maxCandidateLength) {
|
|
5755
|
+
ignoreCurrent = true;
|
|
5756
|
+
}
|
|
5757
|
+
if (!state.inString && char === "}" && state.depth === 0) {
|
|
5758
|
+
if (currentStart !== null && !ignoreCurrent) {
|
|
5759
|
+
const endIndex = index + 1;
|
|
5760
|
+
const candidate = text.slice(currentStart, endIndex);
|
|
5761
|
+
if (candidate.length > 1) {
|
|
5762
|
+
candidates.push({
|
|
5763
|
+
text: candidate,
|
|
5764
|
+
startIndex: currentStart,
|
|
5765
|
+
endIndex
|
|
5766
|
+
});
|
|
5767
|
+
}
|
|
5768
|
+
}
|
|
5769
|
+
currentStart = null;
|
|
5770
|
+
ignoreCurrent = false;
|
|
5771
|
+
}
|
|
5772
|
+
}
|
|
5773
|
+
return candidates;
|
|
5774
|
+
}
|
|
5775
|
+
function extractTaggedToolCallCandidates(rawText) {
|
|
5776
|
+
var _a, _b;
|
|
5777
|
+
const toolCallRegex = /<tool_call>([\s\S]*?)<\/tool_call>/gi;
|
|
5778
|
+
const candidates = [];
|
|
5779
|
+
let match;
|
|
5780
|
+
while (true) {
|
|
5781
|
+
match = toolCallRegex.exec(rawText);
|
|
5782
|
+
if (!match) {
|
|
5783
|
+
break;
|
|
5784
|
+
}
|
|
5785
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
5786
|
+
if (!body) {
|
|
5787
|
+
continue;
|
|
5788
|
+
}
|
|
5789
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
5790
|
+
const endIndex = startIndex + match[0].length;
|
|
5791
|
+
candidates.push({
|
|
5792
|
+
text: body,
|
|
5793
|
+
startIndex,
|
|
5794
|
+
endIndex
|
|
5795
|
+
});
|
|
5796
|
+
}
|
|
5797
|
+
return candidates;
|
|
5798
|
+
}
|
|
5799
|
+
function extractJsonLikeCandidates(rawText) {
|
|
5800
|
+
return mergeJsonCandidatesByStart(
|
|
5801
|
+
extractTaggedToolCallCandidates(rawText),
|
|
5802
|
+
extractCodeBlockCandidates(rawText),
|
|
5803
|
+
extractBalancedJsonObjects(rawText)
|
|
5804
|
+
);
|
|
5805
|
+
}
|
|
5806
|
+
function mergeJsonCandidatesByStart(tagged, codeBlocks, balanced) {
|
|
5807
|
+
return [...tagged, ...codeBlocks, ...balanced].sort(
|
|
5808
|
+
(a, b) => a.startIndex !== b.startIndex ? a.startIndex - b.startIndex : b.endIndex - a.endIndex
|
|
5809
|
+
);
|
|
5810
|
+
}
|
|
5811
|
+
function toToolCallPart(candidate) {
|
|
5812
|
+
return {
|
|
5813
|
+
type: "tool-call",
|
|
5814
|
+
toolCallId: generateId(),
|
|
5815
|
+
toolName: candidate.toolName,
|
|
5816
|
+
input: candidate.input
|
|
5817
|
+
};
|
|
5818
|
+
}
|
|
5819
|
+
function toRecoveredParts(text, candidate, toolCallPart) {
|
|
5820
|
+
const out = [];
|
|
5821
|
+
const prefix = text.slice(0, candidate.startIndex);
|
|
5822
|
+
if (prefix.length > 0) {
|
|
5823
|
+
out.push({ type: "text", text: prefix });
|
|
5824
|
+
}
|
|
5825
|
+
out.push(toolCallPart);
|
|
5826
|
+
const suffix = text.slice(candidate.endIndex);
|
|
5827
|
+
if (suffix.length > 0) {
|
|
5828
|
+
out.push({ type: "text", text: suffix });
|
|
5829
|
+
}
|
|
5830
|
+
return out;
|
|
5831
|
+
}
|
|
5832
|
+
function parseAsToolPayload(payload, tools) {
|
|
5833
|
+
if (!isRecord(payload)) {
|
|
5834
|
+
return null;
|
|
5835
|
+
}
|
|
5836
|
+
const toolName = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : null;
|
|
5837
|
+
if (!toolName) {
|
|
5838
|
+
return null;
|
|
5839
|
+
}
|
|
5840
|
+
if (!tools.some((tool) => tool.name === toolName)) {
|
|
5841
|
+
return null;
|
|
5842
|
+
}
|
|
5843
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
5844
|
+
if (!isRecord(rawArgs)) {
|
|
5845
|
+
return null;
|
|
5846
|
+
}
|
|
5847
|
+
return {
|
|
5848
|
+
toolName,
|
|
5849
|
+
input: safeStringify2(rawArgs)
|
|
5850
|
+
};
|
|
5851
|
+
}
|
|
5852
|
+
function isLikelyArgumentsShapeForTool(args, tool) {
|
|
5853
|
+
const unwrapped = unwrapJsonSchema(tool.inputSchema);
|
|
5854
|
+
if (!isRecord(unwrapped)) {
|
|
5855
|
+
return false;
|
|
5856
|
+
}
|
|
5857
|
+
if (getSchemaType(unwrapped) !== "object") {
|
|
5858
|
+
return false;
|
|
5859
|
+
}
|
|
5860
|
+
const properties = unwrapped.properties;
|
|
5861
|
+
if (!isRecord(properties)) {
|
|
5862
|
+
return false;
|
|
5863
|
+
}
|
|
5864
|
+
const keys = Object.keys(args);
|
|
5865
|
+
if (keys.length === 0) {
|
|
5866
|
+
return false;
|
|
5867
|
+
}
|
|
5868
|
+
const knownKeys = keys.filter((key) => Object.hasOwn(properties, key));
|
|
5869
|
+
if (knownKeys.length === 0) {
|
|
5870
|
+
return false;
|
|
5871
|
+
}
|
|
5872
|
+
if (unwrapped.additionalProperties === false && knownKeys.length !== keys.length) {
|
|
5873
|
+
return false;
|
|
5874
|
+
}
|
|
5875
|
+
return true;
|
|
5876
|
+
}
|
|
5877
|
+
function parseAsArgumentsOnly(payload, tools) {
|
|
5878
|
+
if (tools.length !== 1) {
|
|
5879
|
+
return null;
|
|
5880
|
+
}
|
|
5881
|
+
if (!isRecord(payload)) {
|
|
5882
|
+
return null;
|
|
5883
|
+
}
|
|
5884
|
+
const hasNameEnvelope = Object.hasOwn(payload, "name") && typeof payload.name === "string" && payload.name.length > 0;
|
|
5885
|
+
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" || isRecord(payload.arguments));
|
|
5886
|
+
if (hasNameEnvelope || hasArgumentsEnvelope) {
|
|
5887
|
+
return null;
|
|
5888
|
+
}
|
|
5889
|
+
const tool = tools[0];
|
|
5890
|
+
if (!isLikelyArgumentsShapeForTool(payload, tool)) {
|
|
5891
|
+
return null;
|
|
5892
|
+
}
|
|
5893
|
+
return {
|
|
5894
|
+
toolName: tool.name,
|
|
5895
|
+
input: safeStringify2(payload)
|
|
5896
|
+
};
|
|
5897
|
+
}
|
|
5898
|
+
function recoverToolCallFromJsonCandidates(text, tools) {
|
|
5899
|
+
if (tools.length === 0) {
|
|
5900
|
+
return null;
|
|
5901
|
+
}
|
|
5902
|
+
const jsonCandidates = extractJsonLikeCandidates(text);
|
|
5903
|
+
for (const jsonCandidate of jsonCandidates) {
|
|
5904
|
+
const parsed = parseJsonCandidate(jsonCandidate.text);
|
|
5905
|
+
if (parsed === void 0) {
|
|
5906
|
+
continue;
|
|
5907
|
+
}
|
|
5908
|
+
const toolPayload = parseAsToolPayload(parsed, tools);
|
|
5909
|
+
if (toolPayload) {
|
|
5910
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(toolPayload));
|
|
5911
|
+
}
|
|
5912
|
+
const argsPayload = parseAsArgumentsOnly(parsed, tools);
|
|
5913
|
+
if (argsPayload) {
|
|
5914
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(argsPayload));
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
return null;
|
|
5918
|
+
}
|
|
5919
|
+
|
|
5920
|
+
// src/core/utils/tool-call-coercion.ts
|
|
5921
|
+
function coerceToolCallInput(toolName, input, tools) {
|
|
5086
5922
|
var _a;
|
|
5923
|
+
let args = {};
|
|
5924
|
+
if (typeof input === "string") {
|
|
5925
|
+
try {
|
|
5926
|
+
args = JSON.parse(input);
|
|
5927
|
+
} catch (e) {
|
|
5928
|
+
return;
|
|
5929
|
+
}
|
|
5930
|
+
} else if (input && typeof input === "object") {
|
|
5931
|
+
args = input;
|
|
5932
|
+
} else {
|
|
5933
|
+
return;
|
|
5934
|
+
}
|
|
5935
|
+
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
5936
|
+
const coerced = coerceBySchema(args, schema);
|
|
5937
|
+
return JSON.stringify(coerced != null ? coerced : {});
|
|
5938
|
+
}
|
|
5939
|
+
function coerceToolCallPart(part, tools) {
|
|
5940
|
+
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
5941
|
+
if (coercedInput === void 0) {
|
|
5942
|
+
return part;
|
|
5943
|
+
}
|
|
5944
|
+
return {
|
|
5945
|
+
...part,
|
|
5946
|
+
input: coercedInput
|
|
5947
|
+
};
|
|
5948
|
+
}
|
|
5949
|
+
|
|
5950
|
+
// src/core/utils/tool-choice.ts
|
|
5951
|
+
function ensureNonEmptyToolName(name) {
|
|
5952
|
+
if (typeof name !== "string") {
|
|
5953
|
+
return "unknown";
|
|
5954
|
+
}
|
|
5955
|
+
const trimmed = name.trim();
|
|
5956
|
+
return trimmed.length > 0 ? trimmed : "unknown";
|
|
5957
|
+
}
|
|
5958
|
+
function safeStringify3(value) {
|
|
5959
|
+
try {
|
|
5960
|
+
return JSON.stringify(value != null ? value : {});
|
|
5961
|
+
} catch (e) {
|
|
5962
|
+
return "{}";
|
|
5963
|
+
}
|
|
5964
|
+
}
|
|
5965
|
+
function parseToolChoicePayload({
|
|
5966
|
+
text,
|
|
5967
|
+
tools,
|
|
5968
|
+
onError,
|
|
5969
|
+
errorMessage
|
|
5970
|
+
}) {
|
|
5971
|
+
let parsed;
|
|
5087
5972
|
try {
|
|
5088
|
-
|
|
5973
|
+
parsed = JSON.parse(text);
|
|
5089
5974
|
} catch (error) {
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5096
|
-
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
|
|
5975
|
+
onError == null ? void 0 : onError(errorMessage, {
|
|
5976
|
+
text,
|
|
5977
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5978
|
+
});
|
|
5979
|
+
return { toolName: "unknown", input: "{}" };
|
|
5980
|
+
}
|
|
5981
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
5982
|
+
onError == null ? void 0 : onError("toolChoice JSON payload must be an object", {
|
|
5983
|
+
parsedType: typeof parsed,
|
|
5984
|
+
parsed
|
|
5985
|
+
});
|
|
5986
|
+
return { toolName: "unknown", input: "{}" };
|
|
5100
5987
|
}
|
|
5988
|
+
const payload = parsed;
|
|
5989
|
+
const toolName = ensureNonEmptyToolName(payload.name);
|
|
5990
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
5991
|
+
if (rawArgs == null || typeof rawArgs !== "object" || Array.isArray(rawArgs)) {
|
|
5992
|
+
onError == null ? void 0 : onError("toolChoice arguments must be a JSON object", {
|
|
5993
|
+
toolName,
|
|
5994
|
+
arguments: rawArgs
|
|
5995
|
+
});
|
|
5996
|
+
return { toolName, input: "{}" };
|
|
5997
|
+
}
|
|
5998
|
+
const coercedInput = coerceToolCallInput(toolName, rawArgs, tools);
|
|
5999
|
+
return {
|
|
6000
|
+
toolName,
|
|
6001
|
+
input: coercedInput != null ? coercedInput : safeStringify3(rawArgs)
|
|
6002
|
+
};
|
|
5101
6003
|
}
|
|
6004
|
+
|
|
6005
|
+
// src/generate-handler.ts
|
|
5102
6006
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
5103
6007
|
if (debugSummary) {
|
|
5104
6008
|
debugSummary.originalText = originText;
|
|
@@ -5112,25 +6016,34 @@ function logDebugSummary(debugSummary, toolCall, originText) {
|
|
|
5112
6016
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
5113
6017
|
}
|
|
5114
6018
|
}
|
|
5115
|
-
async function handleToolChoice(doGenerate, params) {
|
|
5116
|
-
var _a, _b, _c;
|
|
6019
|
+
async function handleToolChoice(doGenerate, params, tools) {
|
|
6020
|
+
var _a, _b, _c, _d;
|
|
5117
6021
|
const result = await doGenerate();
|
|
5118
6022
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
5119
|
-
|
|
6023
|
+
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
6024
|
+
let toolName = "unknown";
|
|
6025
|
+
let input = "{}";
|
|
5120
6026
|
if (first && first.type === "text") {
|
|
5121
6027
|
if (getDebugLevel() === "parse") {
|
|
5122
6028
|
logRawChunk(first.text);
|
|
5123
6029
|
}
|
|
5124
|
-
parsed =
|
|
6030
|
+
const parsed = parseToolChoicePayload({
|
|
6031
|
+
text: first.text,
|
|
6032
|
+
tools,
|
|
6033
|
+
onError,
|
|
6034
|
+
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
6035
|
+
});
|
|
6036
|
+
toolName = parsed.toolName;
|
|
6037
|
+
input = parsed.input;
|
|
5125
6038
|
}
|
|
5126
6039
|
const toolCall = {
|
|
5127
6040
|
type: "tool-call",
|
|
5128
6041
|
toolCallId: (0, import_provider_utils.generateId)(),
|
|
5129
|
-
toolName
|
|
5130
|
-
input
|
|
6042
|
+
toolName,
|
|
6043
|
+
input
|
|
5131
6044
|
};
|
|
5132
6045
|
const originText = first && first.type === "text" ? first.text : "";
|
|
5133
|
-
const debugSummary = (
|
|
6046
|
+
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
5134
6047
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
5135
6048
|
return {
|
|
5136
6049
|
...result,
|
|
@@ -5145,7 +6058,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5145
6058
|
if (getDebugLevel() === "stream") {
|
|
5146
6059
|
logRawChunk(contentItem.text);
|
|
5147
6060
|
}
|
|
5148
|
-
|
|
6061
|
+
const parsedByProtocol = protocol.parseGeneratedText({
|
|
5149
6062
|
text: contentItem.text,
|
|
5150
6063
|
tools,
|
|
5151
6064
|
options: {
|
|
@@ -5153,9 +6066,20 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5153
6066
|
...providerOptions == null ? void 0 : providerOptions.toolCallMiddleware
|
|
5154
6067
|
}
|
|
5155
6068
|
});
|
|
6069
|
+
const hasToolCall = parsedByProtocol.some(
|
|
6070
|
+
(part) => part.type === "tool-call"
|
|
6071
|
+
);
|
|
6072
|
+
if (hasToolCall) {
|
|
6073
|
+
return parsedByProtocol;
|
|
6074
|
+
}
|
|
6075
|
+
const recoveredFromJson = recoverToolCallFromJsonCandidates(
|
|
6076
|
+
contentItem.text,
|
|
6077
|
+
tools
|
|
6078
|
+
);
|
|
6079
|
+
return recoveredFromJson != null ? recoveredFromJson : parsedByProtocol;
|
|
5156
6080
|
});
|
|
5157
6081
|
return parsed.map(
|
|
5158
|
-
(part) =>
|
|
6082
|
+
(part) => part.type === "tool-call" ? coerceToolCallPart(part, tools) : part
|
|
5159
6083
|
);
|
|
5160
6084
|
}
|
|
5161
6085
|
function logParsedContent(content) {
|
|
@@ -5198,12 +6122,14 @@ async function wrapGenerate({
|
|
|
5198
6122
|
params
|
|
5199
6123
|
}) {
|
|
5200
6124
|
var _a, _b;
|
|
5201
|
-
|
|
5202
|
-
return handleToolChoice(doGenerate, params);
|
|
5203
|
-
}
|
|
6125
|
+
const onError = extractOnErrorOption(params.providerOptions);
|
|
5204
6126
|
const tools = originalToolsSchema.decode(
|
|
5205
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
6127
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
6128
|
+
onError
|
|
5206
6129
|
);
|
|
6130
|
+
if (isToolChoiceActive(params)) {
|
|
6131
|
+
return handleToolChoice(doGenerate, params, tools);
|
|
6132
|
+
}
|
|
5207
6133
|
const result = await doGenerate();
|
|
5208
6134
|
if (result.content.length === 0) {
|
|
5209
6135
|
return result;
|
|
@@ -5227,28 +6153,6 @@ async function wrapGenerate({
|
|
|
5227
6153
|
content: newContent
|
|
5228
6154
|
};
|
|
5229
6155
|
}
|
|
5230
|
-
function fixToolCallWithSchema(part, tools) {
|
|
5231
|
-
var _a;
|
|
5232
|
-
if (part.type !== "tool-call") {
|
|
5233
|
-
return part;
|
|
5234
|
-
}
|
|
5235
|
-
let args = {};
|
|
5236
|
-
if (typeof part.input === "string") {
|
|
5237
|
-
try {
|
|
5238
|
-
args = JSON.parse(part.input);
|
|
5239
|
-
} catch (e) {
|
|
5240
|
-
return part;
|
|
5241
|
-
}
|
|
5242
|
-
} else if (part.input && typeof part.input === "object") {
|
|
5243
|
-
args = part.input;
|
|
5244
|
-
}
|
|
5245
|
-
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
5246
|
-
const coerced = coerceBySchema(args, schema);
|
|
5247
|
-
return {
|
|
5248
|
-
...part,
|
|
5249
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
5250
|
-
};
|
|
5251
|
-
}
|
|
5252
6156
|
|
|
5253
6157
|
// src/core/prompts/hermes-system-prompt.ts
|
|
5254
6158
|
function hermesSystemPromptTemplate(tools) {
|
|
@@ -5652,19 +6556,22 @@ async function wrapStream({
|
|
|
5652
6556
|
params
|
|
5653
6557
|
}) {
|
|
5654
6558
|
var _a, _b, _c;
|
|
6559
|
+
const onErrorOptions = extractOnErrorOption(params.providerOptions);
|
|
6560
|
+
const tools = originalToolsSchema.decode(
|
|
6561
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
6562
|
+
onErrorOptions
|
|
6563
|
+
);
|
|
5655
6564
|
if (isToolChoiceActive(params)) {
|
|
5656
6565
|
return toolChoiceStream({
|
|
5657
6566
|
doGenerate,
|
|
5658
|
-
|
|
6567
|
+
tools,
|
|
6568
|
+
options: onErrorOptions
|
|
5659
6569
|
});
|
|
5660
6570
|
}
|
|
5661
6571
|
const { stream, ...rest } = await doStream();
|
|
5662
6572
|
const debugLevel = getDebugLevel();
|
|
5663
|
-
const tools = originalToolsSchema.decode(
|
|
5664
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
5665
|
-
);
|
|
5666
6573
|
const options = {
|
|
5667
|
-
...
|
|
6574
|
+
...onErrorOptions,
|
|
5668
6575
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
5669
6576
|
};
|
|
5670
6577
|
const coreStream = stream.pipeThrough(
|
|
@@ -5682,10 +6589,11 @@ async function wrapStream({
|
|
|
5682
6589
|
const v3Stream = coreStream.pipeThrough(
|
|
5683
6590
|
new TransformStream({
|
|
5684
6591
|
transform(part, controller) {
|
|
6592
|
+
const normalizedPart = part.type === "tool-call" ? coerceToolCallPart(part, tools) : part;
|
|
5685
6593
|
if (debugLevel === "stream") {
|
|
5686
|
-
logParsedChunk(
|
|
6594
|
+
logParsedChunk(normalizedPart);
|
|
5687
6595
|
}
|
|
5688
|
-
controller.enqueue(
|
|
6596
|
+
controller.enqueue(normalizedPart);
|
|
5689
6597
|
}
|
|
5690
6598
|
})
|
|
5691
6599
|
);
|
|
@@ -5696,41 +6604,36 @@ async function wrapStream({
|
|
|
5696
6604
|
}
|
|
5697
6605
|
async function toolChoiceStream({
|
|
5698
6606
|
doGenerate,
|
|
6607
|
+
tools,
|
|
5699
6608
|
options
|
|
5700
6609
|
}) {
|
|
5701
|
-
var _a
|
|
6610
|
+
var _a;
|
|
6611
|
+
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
5702
6612
|
const result = await doGenerate();
|
|
5703
|
-
let
|
|
6613
|
+
let toolName = "unknown";
|
|
6614
|
+
let input = "{}";
|
|
5704
6615
|
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
5705
|
-
|
|
5706
|
-
|
|
5707
|
-
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5714
|
-
}
|
|
5715
|
-
);
|
|
5716
|
-
toolJson = {};
|
|
5717
|
-
}
|
|
6616
|
+
const parsed = parseToolChoicePayload({
|
|
6617
|
+
text: result.content[0].text,
|
|
6618
|
+
tools: normalizedTools,
|
|
6619
|
+
onError: options == null ? void 0 : options.onError,
|
|
6620
|
+
errorMessage: "Failed to parse toolChoice JSON from streamed model output"
|
|
6621
|
+
});
|
|
6622
|
+
toolName = parsed.toolName;
|
|
6623
|
+
input = parsed.input;
|
|
5718
6624
|
}
|
|
5719
6625
|
const stream = new ReadableStream({
|
|
5720
6626
|
start(controller) {
|
|
5721
6627
|
controller.enqueue({
|
|
5722
6628
|
type: "tool-call",
|
|
5723
6629
|
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
5724
|
-
toolName
|
|
5725
|
-
input
|
|
6630
|
+
toolName,
|
|
6631
|
+
input
|
|
5726
6632
|
});
|
|
5727
6633
|
controller.enqueue({
|
|
5728
6634
|
type: "finish",
|
|
5729
|
-
usage: (result == null ? void 0 : result.usage)
|
|
5730
|
-
|
|
5731
|
-
outputTokens: 0
|
|
5732
|
-
},
|
|
5733
|
-
finishReason: "tool-calls"
|
|
6635
|
+
usage: normalizeUsage(result == null ? void 0 : result.usage),
|
|
6636
|
+
finishReason: normalizeToolCallsFinishReason(result == null ? void 0 : result.finishReason)
|
|
5734
6637
|
});
|
|
5735
6638
|
controller.close();
|
|
5736
6639
|
}
|
|
@@ -5741,6 +6644,60 @@ async function toolChoiceStream({
|
|
|
5741
6644
|
stream
|
|
5742
6645
|
};
|
|
5743
6646
|
}
|
|
6647
|
+
var ZERO_USAGE = {
|
|
6648
|
+
inputTokens: {
|
|
6649
|
+
total: 0,
|
|
6650
|
+
noCache: void 0,
|
|
6651
|
+
cacheRead: void 0,
|
|
6652
|
+
cacheWrite: void 0
|
|
6653
|
+
},
|
|
6654
|
+
outputTokens: {
|
|
6655
|
+
total: 0,
|
|
6656
|
+
text: void 0,
|
|
6657
|
+
reasoning: void 0
|
|
6658
|
+
}
|
|
6659
|
+
};
|
|
6660
|
+
function normalizeToolCallsFinishReason(finishReason) {
|
|
6661
|
+
let raw = "tool-calls";
|
|
6662
|
+
if (typeof finishReason === "string") {
|
|
6663
|
+
raw = finishReason;
|
|
6664
|
+
} else if (finishReason && typeof finishReason === "object" && "raw" in finishReason && typeof finishReason.raw === "string") {
|
|
6665
|
+
raw = finishReason.raw;
|
|
6666
|
+
} else if (finishReason && typeof finishReason === "object" && "unified" in finishReason && typeof finishReason.unified === "string") {
|
|
6667
|
+
raw = finishReason.unified;
|
|
6668
|
+
}
|
|
6669
|
+
return {
|
|
6670
|
+
unified: "tool-calls",
|
|
6671
|
+
raw
|
|
6672
|
+
};
|
|
6673
|
+
}
|
|
6674
|
+
function normalizeUsage(usage) {
|
|
6675
|
+
if (!usage || typeof usage !== "object") {
|
|
6676
|
+
return ZERO_USAGE;
|
|
6677
|
+
}
|
|
6678
|
+
const usageRecord = usage;
|
|
6679
|
+
const input = usageRecord.inputTokens;
|
|
6680
|
+
const output = usageRecord.outputTokens;
|
|
6681
|
+
if (input && typeof input === "object" && output && typeof output === "object") {
|
|
6682
|
+
return usage;
|
|
6683
|
+
}
|
|
6684
|
+
if (typeof input === "number" && typeof output === "number") {
|
|
6685
|
+
return {
|
|
6686
|
+
inputTokens: {
|
|
6687
|
+
total: input,
|
|
6688
|
+
noCache: void 0,
|
|
6689
|
+
cacheRead: void 0,
|
|
6690
|
+
cacheWrite: void 0
|
|
6691
|
+
},
|
|
6692
|
+
outputTokens: {
|
|
6693
|
+
total: output,
|
|
6694
|
+
text: void 0,
|
|
6695
|
+
reasoning: void 0
|
|
6696
|
+
}
|
|
6697
|
+
};
|
|
6698
|
+
}
|
|
6699
|
+
return ZERO_USAGE;
|
|
6700
|
+
}
|
|
5744
6701
|
|
|
5745
6702
|
// src/transform-handler.ts
|
|
5746
6703
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
@@ -5866,6 +6823,11 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
5866
6823
|
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
5867
6824
|
);
|
|
5868
6825
|
}
|
|
6826
|
+
if (functionTools.length === 0) {
|
|
6827
|
+
throw new Error(
|
|
6828
|
+
"Tool choice type 'required' is set, but no function tools are provided. Provider-defined tools are not supported by this middleware."
|
|
6829
|
+
);
|
|
6830
|
+
}
|
|
5869
6831
|
return {
|
|
5870
6832
|
...baseReturnParams,
|
|
5871
6833
|
responseFormat: {
|