@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/community.cjs
CHANGED
|
@@ -1516,6 +1516,13 @@ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
|
|
|
1516
1516
|
var NEWLINE_SPLIT_REGEX = /\n+/;
|
|
1517
1517
|
var COMMA_SPLIT_REGEX = /,\s*/;
|
|
1518
1518
|
var DIGIT_KEY_REGEX = /^\d+$/;
|
|
1519
|
+
var WHITESPACE_REGEX2 = /\s+/g;
|
|
1520
|
+
var HAS_WHITESPACE_REGEX = /\s/;
|
|
1521
|
+
var SINGLE_QUOTE = "'";
|
|
1522
|
+
var DOUBLE_QUOTE = '"';
|
|
1523
|
+
var SNAKE_SEGMENT_REGEX = /_([a-zA-Z0-9])/g;
|
|
1524
|
+
var CAMEL_BOUNDARY_REGEX = /([a-z0-9])([A-Z])/g;
|
|
1525
|
+
var LEADING_UNDERSCORES_REGEX = /^_+/;
|
|
1519
1526
|
function unwrapJsonSchema(schema) {
|
|
1520
1527
|
if (!schema || typeof schema !== "object") {
|
|
1521
1528
|
return schema;
|
|
@@ -1764,9 +1771,158 @@ function coerceStringToArray(s, unwrapped) {
|
|
|
1764
1771
|
}
|
|
1765
1772
|
return null;
|
|
1766
1773
|
}
|
|
1774
|
+
function getStrictObjectSchemaInfo(unwrapped) {
|
|
1775
|
+
if (getSchemaType(unwrapped) !== "object") {
|
|
1776
|
+
return null;
|
|
1777
|
+
}
|
|
1778
|
+
if (unwrapped.additionalProperties !== false) {
|
|
1779
|
+
return null;
|
|
1780
|
+
}
|
|
1781
|
+
const properties = unwrapped.properties;
|
|
1782
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) {
|
|
1783
|
+
return null;
|
|
1784
|
+
}
|
|
1785
|
+
const propertyMap = properties;
|
|
1786
|
+
const required = Array.isArray(unwrapped.required) ? unwrapped.required.filter(
|
|
1787
|
+
(value) => typeof value === "string" && value.length > 0
|
|
1788
|
+
) : [];
|
|
1789
|
+
const patternProps = unwrapped.patternProperties;
|
|
1790
|
+
const patternProperties = patternProps && typeof patternProps === "object" && !Array.isArray(patternProps) ? patternProps : void 0;
|
|
1791
|
+
return {
|
|
1792
|
+
properties: propertyMap,
|
|
1793
|
+
required,
|
|
1794
|
+
patternProperties
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
function isSingularPluralPair(left, right) {
|
|
1798
|
+
return left.length > 1 && right.length > 1 && (left === `${right}s` || right === `${left}s`);
|
|
1799
|
+
}
|
|
1800
|
+
function snakeToCamel(value) {
|
|
1801
|
+
const trimmed = value.replace(LEADING_UNDERSCORES_REGEX, "");
|
|
1802
|
+
if (trimmed.length === 0) {
|
|
1803
|
+
return value;
|
|
1804
|
+
}
|
|
1805
|
+
const camelized = trimmed.replace(
|
|
1806
|
+
SNAKE_SEGMENT_REGEX,
|
|
1807
|
+
(_, c) => c.toUpperCase()
|
|
1808
|
+
);
|
|
1809
|
+
return camelized.charAt(0).toLowerCase() + camelized.slice(1);
|
|
1810
|
+
}
|
|
1811
|
+
function camelToSnake(value) {
|
|
1812
|
+
return value.replace(CAMEL_BOUNDARY_REGEX, "$1_$2").toLowerCase();
|
|
1813
|
+
}
|
|
1814
|
+
function isCaseStylePair(targetKey, sourceKey) {
|
|
1815
|
+
if (targetKey === sourceKey) {
|
|
1816
|
+
return false;
|
|
1817
|
+
}
|
|
1818
|
+
const sourceLooksSnake = sourceKey.includes("_");
|
|
1819
|
+
const targetLooksSnake = targetKey.includes("_");
|
|
1820
|
+
if (sourceLooksSnake && snakeToCamel(sourceKey) === targetKey) {
|
|
1821
|
+
return true;
|
|
1822
|
+
}
|
|
1823
|
+
if (!sourceLooksSnake && targetLooksSnake && camelToSnake(sourceKey) === targetKey) {
|
|
1824
|
+
return true;
|
|
1825
|
+
}
|
|
1826
|
+
return false;
|
|
1827
|
+
}
|
|
1828
|
+
function isUnexpectedKey(key, schemaInfo) {
|
|
1829
|
+
if (Object.hasOwn(schemaInfo.properties, key)) {
|
|
1830
|
+
return false;
|
|
1831
|
+
}
|
|
1832
|
+
const patternSchemas = getPatternSchemasForKey(
|
|
1833
|
+
schemaInfo.patternProperties,
|
|
1834
|
+
key
|
|
1835
|
+
);
|
|
1836
|
+
if (patternSchemas.length > 0) {
|
|
1837
|
+
return patternSchemas.every((schema) => schema === false);
|
|
1838
|
+
}
|
|
1839
|
+
return true;
|
|
1840
|
+
}
|
|
1841
|
+
function computeMissingAndUnexpectedKeys(input, schemaInfo) {
|
|
1842
|
+
const missingRequired = schemaInfo.required.filter(
|
|
1843
|
+
(key) => !Object.hasOwn(input, key)
|
|
1844
|
+
);
|
|
1845
|
+
const unexpectedKeys = Object.keys(input).filter(
|
|
1846
|
+
(key) => isUnexpectedKey(key, schemaInfo)
|
|
1847
|
+
);
|
|
1848
|
+
return { missingRequired, unexpectedKeys };
|
|
1849
|
+
}
|
|
1850
|
+
function applySingularPluralRequiredKeyRename(input, schemaInfo) {
|
|
1851
|
+
const { missingRequired, unexpectedKeys } = computeMissingAndUnexpectedKeys(
|
|
1852
|
+
input,
|
|
1853
|
+
schemaInfo
|
|
1854
|
+
);
|
|
1855
|
+
if (missingRequired.length !== 1 || unexpectedKeys.length !== 1) {
|
|
1856
|
+
return null;
|
|
1857
|
+
}
|
|
1858
|
+
const targetKey = missingRequired[0];
|
|
1859
|
+
const sourceKey = unexpectedKeys[0];
|
|
1860
|
+
if (!Object.hasOwn(schemaInfo.properties, targetKey)) {
|
|
1861
|
+
return null;
|
|
1862
|
+
}
|
|
1863
|
+
if (!isSingularPluralPair(targetKey, sourceKey)) {
|
|
1864
|
+
return null;
|
|
1865
|
+
}
|
|
1866
|
+
if (getSchemaType(schemaInfo.properties[targetKey]) !== "array") {
|
|
1867
|
+
return null;
|
|
1868
|
+
}
|
|
1869
|
+
if (!Array.isArray(input[sourceKey])) {
|
|
1870
|
+
return null;
|
|
1871
|
+
}
|
|
1872
|
+
if (!Object.hasOwn(input, sourceKey) || Object.hasOwn(input, targetKey)) {
|
|
1873
|
+
return null;
|
|
1874
|
+
}
|
|
1875
|
+
const output = { ...input };
|
|
1876
|
+
output[targetKey] = output[sourceKey];
|
|
1877
|
+
delete output[sourceKey];
|
|
1878
|
+
return output;
|
|
1879
|
+
}
|
|
1880
|
+
function applyCaseStyleRequiredKeyRename(input, schemaInfo) {
|
|
1881
|
+
const { missingRequired, unexpectedKeys } = computeMissingAndUnexpectedKeys(
|
|
1882
|
+
input,
|
|
1883
|
+
schemaInfo
|
|
1884
|
+
);
|
|
1885
|
+
if (missingRequired.length !== 1 || unexpectedKeys.length !== 1) {
|
|
1886
|
+
return null;
|
|
1887
|
+
}
|
|
1888
|
+
const targetKey = missingRequired[0];
|
|
1889
|
+
const sourceKey = unexpectedKeys[0];
|
|
1890
|
+
if (!Object.hasOwn(schemaInfo.properties, targetKey)) {
|
|
1891
|
+
return null;
|
|
1892
|
+
}
|
|
1893
|
+
if (!isCaseStylePair(targetKey, sourceKey)) {
|
|
1894
|
+
return null;
|
|
1895
|
+
}
|
|
1896
|
+
if (!Object.hasOwn(input, sourceKey) || Object.hasOwn(input, targetKey)) {
|
|
1897
|
+
return null;
|
|
1898
|
+
}
|
|
1899
|
+
const output = { ...input };
|
|
1900
|
+
output[targetKey] = output[sourceKey];
|
|
1901
|
+
delete output[sourceKey];
|
|
1902
|
+
return output;
|
|
1903
|
+
}
|
|
1904
|
+
function applyStrictRequiredKeyRename(input, unwrapped) {
|
|
1905
|
+
const schemaInfo = getStrictObjectSchemaInfo(unwrapped);
|
|
1906
|
+
if (!schemaInfo) {
|
|
1907
|
+
return input;
|
|
1908
|
+
}
|
|
1909
|
+
const singularPlural = applySingularPluralRequiredKeyRename(
|
|
1910
|
+
input,
|
|
1911
|
+
schemaInfo
|
|
1912
|
+
);
|
|
1913
|
+
if (singularPlural) {
|
|
1914
|
+
return singularPlural;
|
|
1915
|
+
}
|
|
1916
|
+
const caseStyle = applyCaseStyleRequiredKeyRename(input, schemaInfo);
|
|
1917
|
+
if (caseStyle) {
|
|
1918
|
+
return caseStyle;
|
|
1919
|
+
}
|
|
1920
|
+
return input;
|
|
1921
|
+
}
|
|
1767
1922
|
function coerceObjectToObject(value, unwrapped) {
|
|
1923
|
+
const normalizedInput = applyStrictRequiredKeyRename(value, unwrapped);
|
|
1768
1924
|
const out = {};
|
|
1769
|
-
for (const [k, v] of Object.entries(
|
|
1925
|
+
for (const [k, v] of Object.entries(normalizedInput)) {
|
|
1770
1926
|
out[k] = coerceValueForKey(v, k, unwrapped);
|
|
1771
1927
|
}
|
|
1772
1928
|
return out;
|
|
@@ -1777,6 +1933,109 @@ function coerceArrayToArray(value, prefixItems, itemsSchema) {
|
|
|
1777
1933
|
}
|
|
1778
1934
|
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
1779
1935
|
}
|
|
1936
|
+
function isPrimitiveSchemaType(schemaType) {
|
|
1937
|
+
return schemaType === "string" || schemaType === "number" || schemaType === "integer" || schemaType === "boolean";
|
|
1938
|
+
}
|
|
1939
|
+
function isPrimitiveMatchForSchemaType(value, schemaType) {
|
|
1940
|
+
if (schemaType === "string") {
|
|
1941
|
+
return typeof value === "string";
|
|
1942
|
+
}
|
|
1943
|
+
if (schemaType === "number") {
|
|
1944
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
1945
|
+
}
|
|
1946
|
+
if (schemaType === "integer") {
|
|
1947
|
+
return typeof value === "number" && Number.isFinite(value) && Number.isInteger(value);
|
|
1948
|
+
}
|
|
1949
|
+
return typeof value === "boolean";
|
|
1950
|
+
}
|
|
1951
|
+
function coercePrimitiveWrappedObject(value, itemsSchema) {
|
|
1952
|
+
const schemaType = getSchemaType(itemsSchema);
|
|
1953
|
+
if (!isPrimitiveSchemaType(schemaType)) {
|
|
1954
|
+
return null;
|
|
1955
|
+
}
|
|
1956
|
+
const keys = Object.keys(value);
|
|
1957
|
+
if (keys.length !== 1) {
|
|
1958
|
+
return null;
|
|
1959
|
+
}
|
|
1960
|
+
const singleValue = value[keys[0]];
|
|
1961
|
+
if (singleValue && typeof singleValue === "object") {
|
|
1962
|
+
return null;
|
|
1963
|
+
}
|
|
1964
|
+
const coerced = coerceBySchema(singleValue, itemsSchema);
|
|
1965
|
+
return isPrimitiveMatchForSchemaType(coerced, schemaType) ? coerced : null;
|
|
1966
|
+
}
|
|
1967
|
+
function coerceParallelArraysObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
1968
|
+
if (prefixItems && prefixItems.length > 0) {
|
|
1969
|
+
return null;
|
|
1970
|
+
}
|
|
1971
|
+
const unwrappedItems = unwrapJsonSchema(itemsSchema);
|
|
1972
|
+
if (!unwrappedItems || typeof unwrappedItems !== "object" || Array.isArray(unwrappedItems)) {
|
|
1973
|
+
return null;
|
|
1974
|
+
}
|
|
1975
|
+
const itemSchema = unwrappedItems;
|
|
1976
|
+
if (getSchemaType(itemSchema) !== "object") {
|
|
1977
|
+
return null;
|
|
1978
|
+
}
|
|
1979
|
+
if (itemSchema.additionalProperties !== false) {
|
|
1980
|
+
return null;
|
|
1981
|
+
}
|
|
1982
|
+
const properties = itemSchema.properties;
|
|
1983
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) {
|
|
1984
|
+
return null;
|
|
1985
|
+
}
|
|
1986
|
+
const propertyMap = properties;
|
|
1987
|
+
const entries = Object.entries(maybe);
|
|
1988
|
+
if (entries.length < 2) {
|
|
1989
|
+
return null;
|
|
1990
|
+
}
|
|
1991
|
+
if (!entries.every(([, value]) => Array.isArray(value))) {
|
|
1992
|
+
return null;
|
|
1993
|
+
}
|
|
1994
|
+
if (!entries.every(([key]) => Object.hasOwn(propertyMap, key))) {
|
|
1995
|
+
return null;
|
|
1996
|
+
}
|
|
1997
|
+
if (!entries.every(([key]) => {
|
|
1998
|
+
const schemaType = getSchemaType(propertyMap[key]);
|
|
1999
|
+
return schemaType !== "array" && schemaType !== "object";
|
|
2000
|
+
})) {
|
|
2001
|
+
return null;
|
|
2002
|
+
}
|
|
2003
|
+
const lengths = [
|
|
2004
|
+
...new Set(entries.map(([, value]) => value.length))
|
|
2005
|
+
];
|
|
2006
|
+
if (lengths.length !== 1) {
|
|
2007
|
+
return null;
|
|
2008
|
+
}
|
|
2009
|
+
const length = lengths[0];
|
|
2010
|
+
if (length < 2) {
|
|
2011
|
+
return null;
|
|
2012
|
+
}
|
|
2013
|
+
const zipped = [];
|
|
2014
|
+
for (let index = 0; index < length; index += 1) {
|
|
2015
|
+
const item = {};
|
|
2016
|
+
for (const [key, value] of entries) {
|
|
2017
|
+
item[key] = value[index];
|
|
2018
|
+
}
|
|
2019
|
+
zipped.push(item);
|
|
2020
|
+
}
|
|
2021
|
+
return coerceArrayToArray(zipped, prefixItems, itemsSchema);
|
|
2022
|
+
}
|
|
2023
|
+
function coerceSingleKeyObjectToArray(singleValue, itemsSchema) {
|
|
2024
|
+
if (Array.isArray(singleValue)) {
|
|
2025
|
+
return singleValue.map((v) => coerceBySchema(v, itemsSchema));
|
|
2026
|
+
}
|
|
2027
|
+
if (singleValue && typeof singleValue === "object") {
|
|
2028
|
+
const primitiveWrapped = coercePrimitiveWrappedObject(
|
|
2029
|
+
singleValue,
|
|
2030
|
+
itemsSchema
|
|
2031
|
+
);
|
|
2032
|
+
if (primitiveWrapped !== null) {
|
|
2033
|
+
return [primitiveWrapped];
|
|
2034
|
+
}
|
|
2035
|
+
return [coerceBySchema(singleValue, itemsSchema)];
|
|
2036
|
+
}
|
|
2037
|
+
return null;
|
|
2038
|
+
}
|
|
1780
2039
|
function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
1781
2040
|
if (Object.hasOwn(maybe, "item")) {
|
|
1782
2041
|
const items = maybe.item;
|
|
@@ -1788,15 +2047,23 @@ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
|
1788
2047
|
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
1789
2048
|
return coerceArrayToArray(arr, prefixItems, itemsSchema);
|
|
1790
2049
|
}
|
|
2050
|
+
const parallelArrays = coerceParallelArraysObjectToArray(
|
|
2051
|
+
maybe,
|
|
2052
|
+
prefixItems,
|
|
2053
|
+
itemsSchema
|
|
2054
|
+
);
|
|
2055
|
+
if (parallelArrays !== null) {
|
|
2056
|
+
return parallelArrays;
|
|
2057
|
+
}
|
|
1791
2058
|
if (keys.length === 1) {
|
|
1792
2059
|
const singleKey = keys[0];
|
|
1793
2060
|
if (!(schemaIsUnconstrained(itemsSchema) || schemaHasProperty(itemsSchema, singleKey))) {
|
|
1794
|
-
const
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
if (
|
|
1799
|
-
return
|
|
2061
|
+
const result = coerceSingleKeyObjectToArray(
|
|
2062
|
+
maybe[singleKey],
|
|
2063
|
+
itemsSchema
|
|
2064
|
+
);
|
|
2065
|
+
if (result !== null) {
|
|
2066
|
+
return result;
|
|
1800
2067
|
}
|
|
1801
2068
|
}
|
|
1802
2069
|
}
|
|
@@ -1826,6 +2093,86 @@ function coerceStringToPrimitive(s, schemaType) {
|
|
|
1826
2093
|
}
|
|
1827
2094
|
return null;
|
|
1828
2095
|
}
|
|
2096
|
+
function coercePrimitiveToString(value, schemaType) {
|
|
2097
|
+
if (schemaType !== "string") {
|
|
2098
|
+
return null;
|
|
2099
|
+
}
|
|
2100
|
+
if (typeof value === "boolean") {
|
|
2101
|
+
return value ? "true" : "false";
|
|
2102
|
+
}
|
|
2103
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2104
|
+
return String(value);
|
|
2105
|
+
}
|
|
2106
|
+
return null;
|
|
2107
|
+
}
|
|
2108
|
+
function coerceStringByEnumWhitespace(rawValue, unwrapped) {
|
|
2109
|
+
const enumValues = unwrapped.enum;
|
|
2110
|
+
if (!Array.isArray(enumValues) || enumValues.length === 0) {
|
|
2111
|
+
return null;
|
|
2112
|
+
}
|
|
2113
|
+
if (!enumValues.every((item) => typeof item === "string")) {
|
|
2114
|
+
return null;
|
|
2115
|
+
}
|
|
2116
|
+
const normalizedEnumValues = enumValues;
|
|
2117
|
+
if (normalizedEnumValues.includes(rawValue)) {
|
|
2118
|
+
return null;
|
|
2119
|
+
}
|
|
2120
|
+
const unquoted = unwrapMatchingQuotes(rawValue);
|
|
2121
|
+
if (unquoted !== null) {
|
|
2122
|
+
const exactMatches = normalizedEnumValues.filter(
|
|
2123
|
+
(item) => item === unquoted
|
|
2124
|
+
);
|
|
2125
|
+
if (exactMatches.length === 1) {
|
|
2126
|
+
return exactMatches[0];
|
|
2127
|
+
}
|
|
2128
|
+
}
|
|
2129
|
+
const candidates = [rawValue, unquoted].filter(
|
|
2130
|
+
(item) => item !== null
|
|
2131
|
+
);
|
|
2132
|
+
for (const candidate of candidates) {
|
|
2133
|
+
if (!HAS_WHITESPACE_REGEX.test(candidate)) {
|
|
2134
|
+
continue;
|
|
2135
|
+
}
|
|
2136
|
+
const normalizedInput = candidate.replace(WHITESPACE_REGEX2, "");
|
|
2137
|
+
const matches = normalizedEnumValues.filter(
|
|
2138
|
+
(item) => item.replace(WHITESPACE_REGEX2, "") === normalizedInput
|
|
2139
|
+
);
|
|
2140
|
+
if (matches.length === 1) {
|
|
2141
|
+
return matches[0];
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
return null;
|
|
2145
|
+
}
|
|
2146
|
+
function unwrapMatchingQuotes(value) {
|
|
2147
|
+
if (value.length < 2) {
|
|
2148
|
+
return null;
|
|
2149
|
+
}
|
|
2150
|
+
const first = value[0];
|
|
2151
|
+
const last = value.at(-1);
|
|
2152
|
+
const isQuote = (first === SINGLE_QUOTE || first === DOUBLE_QUOTE) && first === last;
|
|
2153
|
+
if (!isQuote) {
|
|
2154
|
+
return null;
|
|
2155
|
+
}
|
|
2156
|
+
return value.slice(1, -1);
|
|
2157
|
+
}
|
|
2158
|
+
function coerceObjectToPrimitive(value, schemaType, fullSchema) {
|
|
2159
|
+
if (!isPrimitiveSchemaType(schemaType)) {
|
|
2160
|
+
return null;
|
|
2161
|
+
}
|
|
2162
|
+
const keys = Object.keys(value);
|
|
2163
|
+
if (keys.length !== 1) {
|
|
2164
|
+
return null;
|
|
2165
|
+
}
|
|
2166
|
+
const singleValue = value[keys[0]];
|
|
2167
|
+
if (singleValue && typeof singleValue === "object") {
|
|
2168
|
+
return null;
|
|
2169
|
+
}
|
|
2170
|
+
const coerced = coerceBySchema(
|
|
2171
|
+
singleValue,
|
|
2172
|
+
fullSchema != null ? fullSchema : { type: schemaType }
|
|
2173
|
+
);
|
|
2174
|
+
return isPrimitiveMatchForSchemaType(coerced, schemaType) ? coerced : null;
|
|
2175
|
+
}
|
|
1829
2176
|
function coerceStringValue(value, schemaType, u) {
|
|
1830
2177
|
const s = value.trim();
|
|
1831
2178
|
if (schemaType === "object") {
|
|
@@ -1844,6 +2191,10 @@ function coerceStringValue(value, schemaType, u) {
|
|
|
1844
2191
|
if (primitiveResult !== null) {
|
|
1845
2192
|
return primitiveResult;
|
|
1846
2193
|
}
|
|
2194
|
+
const enumWhitespaceCanonical = coerceStringByEnumWhitespace(s, u);
|
|
2195
|
+
if (enumWhitespaceCanonical !== null) {
|
|
2196
|
+
return enumWhitespaceCanonical;
|
|
2197
|
+
}
|
|
1847
2198
|
return value;
|
|
1848
2199
|
}
|
|
1849
2200
|
function coerceArrayValue(value, prefixItems, itemsSchema) {
|
|
@@ -1882,9 +2233,23 @@ function coerceBySchema(value, schema) {
|
|
|
1882
2233
|
if (typeof value === "string") {
|
|
1883
2234
|
return coerceStringValue(value, schemaType, u);
|
|
1884
2235
|
}
|
|
2236
|
+
const primitiveString = coercePrimitiveToString(value, schemaType);
|
|
2237
|
+
if (primitiveString !== null) {
|
|
2238
|
+
return primitiveString;
|
|
2239
|
+
}
|
|
1885
2240
|
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
1886
2241
|
return coerceObjectToObject(value, u);
|
|
1887
2242
|
}
|
|
2243
|
+
if (value && typeof value === "object" && !Array.isArray(value) && isPrimitiveSchemaType(schemaType)) {
|
|
2244
|
+
const primitiveResult = coerceObjectToPrimitive(
|
|
2245
|
+
value,
|
|
2246
|
+
schemaType,
|
|
2247
|
+
u
|
|
2248
|
+
);
|
|
2249
|
+
if (primitiveResult !== null) {
|
|
2250
|
+
return primitiveResult;
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
1888
2253
|
if (schemaType === "array") {
|
|
1889
2254
|
const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
|
|
1890
2255
|
const itemsSchema = u.items;
|
|
@@ -2899,7 +3264,7 @@ var XMLTokenizer = class {
|
|
|
2899
3264
|
};
|
|
2900
3265
|
|
|
2901
3266
|
// src/rxml/core/parser.ts
|
|
2902
|
-
var
|
|
3267
|
+
var WHITESPACE_REGEX3 = /\s/;
|
|
2903
3268
|
var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2904
3269
|
var DIGIT_KEY_REGEX2 = /^\d+$/;
|
|
2905
3270
|
function getTopLevelStringProps(s) {
|
|
@@ -3069,7 +3434,7 @@ function parse2(xmlInner, schema, options = {}) {
|
|
|
3069
3434
|
const closeHead = s.indexOf(`</${rootName}`, range.end);
|
|
3070
3435
|
if (closeHead === range.end) {
|
|
3071
3436
|
let p = closeHead + 2 + rootName.length;
|
|
3072
|
-
while (p < s.length &&
|
|
3437
|
+
while (p < s.length && WHITESPACE_REGEX3.test(s[p])) {
|
|
3073
3438
|
p += 1;
|
|
3074
3439
|
}
|
|
3075
3440
|
if (s[p] === ">") {
|
|
@@ -3407,7 +3772,7 @@ function createIntermediateCall(toolName, rawSegment, schema) {
|
|
|
3407
3772
|
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
3408
3773
|
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
3409
3774
|
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
3410
|
-
var
|
|
3775
|
+
var WHITESPACE_REGEX4 = /\s/;
|
|
3411
3776
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
3412
3777
|
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
3413
3778
|
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
@@ -3548,7 +3913,7 @@ function balanceTags(xml) {
|
|
|
3548
3913
|
}
|
|
3549
3914
|
function skipWs(s, p, len) {
|
|
3550
3915
|
let idx = p;
|
|
3551
|
-
while (idx < len &&
|
|
3916
|
+
while (idx < len && WHITESPACE_REGEX4.test(s[idx])) {
|
|
3552
3917
|
idx += 1;
|
|
3553
3918
|
}
|
|
3554
3919
|
return idx;
|
|
@@ -3601,7 +3966,7 @@ function handleOpeningTagSegment(src, lt, out, stack) {
|
|
|
3601
3966
|
return len;
|
|
3602
3967
|
}
|
|
3603
3968
|
let r = q - 1;
|
|
3604
|
-
while (r >= nameStart &&
|
|
3969
|
+
while (r >= nameStart && WHITESPACE_REGEX4.test(src[r])) {
|
|
3605
3970
|
r -= 1;
|
|
3606
3971
|
}
|
|
3607
3972
|
const selfClosing = src[r] === "/";
|
|
@@ -3765,7 +4130,31 @@ function parse3(xml, schema, options = {}) {
|
|
|
3765
4130
|
|
|
3766
4131
|
// src/core/utils/regex-constants.ts
|
|
3767
4132
|
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
3768
|
-
var
|
|
4133
|
+
var WHITESPACE_REGEX5 = /\s/;
|
|
4134
|
+
|
|
4135
|
+
// src/core/utils/xml-root-repair.ts
|
|
4136
|
+
var XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX = /^<([A-Za-z_][A-Za-z0-9_-]*)\s*\r?\n([\s\S]+?)\r?\n\s*\/>\s*$/;
|
|
4137
|
+
function tryRepairXmlSelfClosingRootWithBody(rawText, toolNames) {
|
|
4138
|
+
const trimmed = rawText.trim();
|
|
4139
|
+
if (trimmed.length === 0) {
|
|
4140
|
+
return null;
|
|
4141
|
+
}
|
|
4142
|
+
const match = trimmed.match(XML_SELF_CLOSING_ROOT_WITH_BODY_REGEX);
|
|
4143
|
+
if (!match) {
|
|
4144
|
+
return null;
|
|
4145
|
+
}
|
|
4146
|
+
const rootTag = match[1];
|
|
4147
|
+
if (!toolNames.includes(rootTag)) {
|
|
4148
|
+
return null;
|
|
4149
|
+
}
|
|
4150
|
+
const body = match[2].trimEnd();
|
|
4151
|
+
if (body.trim().length === 0 || body.includes(`</${rootTag}>`)) {
|
|
4152
|
+
return null;
|
|
4153
|
+
}
|
|
4154
|
+
return `<${rootTag}>
|
|
4155
|
+
${body}
|
|
4156
|
+
</${rootTag}>`;
|
|
4157
|
+
}
|
|
3769
4158
|
|
|
3770
4159
|
// src/core/protocols/xml-protocol.ts
|
|
3771
4160
|
function getToolSchema(tools, toolName) {
|
|
@@ -3869,7 +4258,7 @@ function consumeClosingTag(text, lt) {
|
|
|
3869
4258
|
}
|
|
3870
4259
|
function consumeOpenTag(text, lt) {
|
|
3871
4260
|
let p = lt + 1;
|
|
3872
|
-
while (p < text.length &&
|
|
4261
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3873
4262
|
p += 1;
|
|
3874
4263
|
}
|
|
3875
4264
|
const nameStart = p;
|
|
@@ -3882,7 +4271,7 @@ function consumeOpenTag(text, lt) {
|
|
|
3882
4271
|
return null;
|
|
3883
4272
|
}
|
|
3884
4273
|
let r = q - 1;
|
|
3885
|
-
while (r >= nameStart &&
|
|
4274
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
3886
4275
|
r -= 1;
|
|
3887
4276
|
}
|
|
3888
4277
|
const selfClosing = text[r] === "/";
|
|
@@ -3911,7 +4300,7 @@ function nextTagToken(text, fromPos) {
|
|
|
3911
4300
|
if (next === "/") {
|
|
3912
4301
|
const closing = consumeClosingTag(text, lt);
|
|
3913
4302
|
let p = lt + 2;
|
|
3914
|
-
while (p < text.length &&
|
|
4303
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3915
4304
|
p += 1;
|
|
3916
4305
|
}
|
|
3917
4306
|
const nameStart = p;
|
|
@@ -4048,6 +4437,102 @@ function findToolCalls(text, toolNames) {
|
|
|
4048
4437
|
}
|
|
4049
4438
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4050
4439
|
}
|
|
4440
|
+
function handleSpecialToken(depth) {
|
|
4441
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: false };
|
|
4442
|
+
}
|
|
4443
|
+
function handleOpenToken(token, depth, lastCompleteEnd) {
|
|
4444
|
+
if (token.selfClosing) {
|
|
4445
|
+
return {
|
|
4446
|
+
depth,
|
|
4447
|
+
lastCompleteEnd: depth === 0 ? token.nextPos : lastCompleteEnd,
|
|
4448
|
+
shouldBreak: false
|
|
4449
|
+
};
|
|
4450
|
+
}
|
|
4451
|
+
return { depth: depth + 1, lastCompleteEnd, shouldBreak: false };
|
|
4452
|
+
}
|
|
4453
|
+
function handleCloseToken(token, depth) {
|
|
4454
|
+
if (depth <= 0) {
|
|
4455
|
+
return { depth, lastCompleteEnd: -1, shouldBreak: true };
|
|
4456
|
+
}
|
|
4457
|
+
const newDepth = depth - 1;
|
|
4458
|
+
return {
|
|
4459
|
+
depth: newDepth,
|
|
4460
|
+
lastCompleteEnd: newDepth === 0 ? token.nextPos : -1,
|
|
4461
|
+
shouldBreak: false
|
|
4462
|
+
};
|
|
4463
|
+
}
|
|
4464
|
+
function findLinePrefixedXmlBodyEnd(text, bodyStartIndex) {
|
|
4465
|
+
let cursor = bodyStartIndex;
|
|
4466
|
+
let depth = 0;
|
|
4467
|
+
let lastCompleteEnd = -1;
|
|
4468
|
+
while (cursor < text.length) {
|
|
4469
|
+
if (depth === 0) {
|
|
4470
|
+
cursor = consumeWhitespace(text, cursor);
|
|
4471
|
+
if (cursor >= text.length || text.charAt(cursor) !== "<") {
|
|
4472
|
+
break;
|
|
4473
|
+
}
|
|
4474
|
+
}
|
|
4475
|
+
const token = nextTagToken(text, cursor);
|
|
4476
|
+
if (token.kind === "eof") {
|
|
4477
|
+
break;
|
|
4478
|
+
}
|
|
4479
|
+
let result;
|
|
4480
|
+
if (token.kind === "special") {
|
|
4481
|
+
result = handleSpecialToken(depth);
|
|
4482
|
+
} else if (token.kind === "open") {
|
|
4483
|
+
result = handleOpenToken(token, depth, lastCompleteEnd);
|
|
4484
|
+
} else {
|
|
4485
|
+
result = handleCloseToken(token, depth);
|
|
4486
|
+
}
|
|
4487
|
+
depth = result.depth;
|
|
4488
|
+
if (result.lastCompleteEnd !== -1) {
|
|
4489
|
+
lastCompleteEnd = result.lastCompleteEnd;
|
|
4490
|
+
}
|
|
4491
|
+
if (result.shouldBreak) {
|
|
4492
|
+
break;
|
|
4493
|
+
}
|
|
4494
|
+
cursor = token.nextPos;
|
|
4495
|
+
}
|
|
4496
|
+
return lastCompleteEnd;
|
|
4497
|
+
}
|
|
4498
|
+
function findLinePrefixedToolCall(text, toolNames) {
|
|
4499
|
+
var _a;
|
|
4500
|
+
let best = null;
|
|
4501
|
+
for (const toolName of toolNames) {
|
|
4502
|
+
const linePattern = new RegExp(
|
|
4503
|
+
`(^|\\n)[\\t ]*${escapeRegExp(toolName)}[\\t ]*:?[\\t ]*(?:\\r?\\n|$)`,
|
|
4504
|
+
"g"
|
|
4505
|
+
);
|
|
4506
|
+
let match = linePattern.exec(text);
|
|
4507
|
+
while (match !== null) {
|
|
4508
|
+
const prefix = (_a = match[1]) != null ? _a : "";
|
|
4509
|
+
const startIndex = match.index + prefix.length;
|
|
4510
|
+
const contentStart = consumeWhitespace(text, linePattern.lastIndex);
|
|
4511
|
+
if (contentStart >= text.length || text.charAt(contentStart) !== "<") {
|
|
4512
|
+
match = linePattern.exec(text);
|
|
4513
|
+
continue;
|
|
4514
|
+
}
|
|
4515
|
+
const contentEnd = findLinePrefixedXmlBodyEnd(text, contentStart);
|
|
4516
|
+
if (contentEnd === -1 || contentEnd <= contentStart) {
|
|
4517
|
+
match = linePattern.exec(text);
|
|
4518
|
+
continue;
|
|
4519
|
+
}
|
|
4520
|
+
const content = text.slice(contentStart, contentEnd);
|
|
4521
|
+
const candidate = {
|
|
4522
|
+
toolName,
|
|
4523
|
+
startIndex,
|
|
4524
|
+
endIndex: contentEnd,
|
|
4525
|
+
content,
|
|
4526
|
+
segment: text.slice(startIndex, contentEnd)
|
|
4527
|
+
};
|
|
4528
|
+
if (best === null || candidate.startIndex < best.startIndex) {
|
|
4529
|
+
best = candidate;
|
|
4530
|
+
}
|
|
4531
|
+
break;
|
|
4532
|
+
}
|
|
4533
|
+
}
|
|
4534
|
+
return best;
|
|
4535
|
+
}
|
|
4051
4536
|
function findEarliestToolTag(buffer, toolNames) {
|
|
4052
4537
|
var _a, _b;
|
|
4053
4538
|
let bestIndex = -1;
|
|
@@ -4086,7 +4571,7 @@ function isOpenTagPrefix(suffix, toolName) {
|
|
|
4086
4571
|
}
|
|
4087
4572
|
function consumeWhitespace(text, index) {
|
|
4088
4573
|
let i = index;
|
|
4089
|
-
while (i < text.length &&
|
|
4574
|
+
while (i < text.length && WHITESPACE_REGEX5.test(text.charAt(i))) {
|
|
4090
4575
|
i += 1;
|
|
4091
4576
|
}
|
|
4092
4577
|
return i;
|
|
@@ -4337,6 +4822,27 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
4337
4822
|
}
|
|
4338
4823
|
};
|
|
4339
4824
|
}
|
|
4825
|
+
function findToolCallsWithFallbacks(text, toolNames) {
|
|
4826
|
+
let parseText = text;
|
|
4827
|
+
let toolCalls = findToolCalls(parseText, toolNames);
|
|
4828
|
+
if (toolCalls.length === 0) {
|
|
4829
|
+
const fallbackToolCall = findLinePrefixedToolCall(parseText, toolNames);
|
|
4830
|
+
if (fallbackToolCall !== null) {
|
|
4831
|
+
toolCalls.push(fallbackToolCall);
|
|
4832
|
+
}
|
|
4833
|
+
}
|
|
4834
|
+
if (toolCalls.length === 0) {
|
|
4835
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(parseText, toolNames);
|
|
4836
|
+
if (repaired) {
|
|
4837
|
+
const repairedCalls = findToolCalls(repaired, toolNames);
|
|
4838
|
+
if (repairedCalls.length > 0) {
|
|
4839
|
+
parseText = repaired;
|
|
4840
|
+
toolCalls = repairedCalls;
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
}
|
|
4844
|
+
return { parseText, toolCalls };
|
|
4845
|
+
}
|
|
4340
4846
|
var xmlProtocol = (protocolOptions) => {
|
|
4341
4847
|
var _a;
|
|
4342
4848
|
const parseOptions = {
|
|
@@ -4370,28 +4876,31 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4370
4876
|
}
|
|
4371
4877
|
const processedElements = [];
|
|
4372
4878
|
let currentIndex = 0;
|
|
4373
|
-
const toolCalls =
|
|
4879
|
+
const { parseText, toolCalls } = findToolCallsWithFallbacks(
|
|
4880
|
+
text,
|
|
4881
|
+
toolNames
|
|
4882
|
+
);
|
|
4374
4883
|
for (const tc of toolCalls) {
|
|
4375
4884
|
if (tc.startIndex > currentIndex) {
|
|
4376
4885
|
processedElements.push({
|
|
4377
4886
|
type: "text",
|
|
4378
|
-
text:
|
|
4887
|
+
text: parseText.substring(currentIndex, tc.startIndex)
|
|
4379
4888
|
});
|
|
4380
4889
|
}
|
|
4381
4890
|
processToolCall({
|
|
4382
4891
|
toolCall: tc,
|
|
4383
4892
|
tools,
|
|
4384
4893
|
options,
|
|
4385
|
-
text,
|
|
4894
|
+
text: parseText,
|
|
4386
4895
|
processedElements,
|
|
4387
4896
|
parseOptions
|
|
4388
4897
|
});
|
|
4389
4898
|
currentIndex = tc.endIndex;
|
|
4390
4899
|
}
|
|
4391
|
-
if (currentIndex <
|
|
4900
|
+
if (currentIndex < parseText.length) {
|
|
4392
4901
|
processedElements.push({
|
|
4393
4902
|
type: "text",
|
|
4394
|
-
text:
|
|
4903
|
+
text: parseText.substring(currentIndex)
|
|
4395
4904
|
});
|
|
4396
4905
|
}
|
|
4397
4906
|
return processedElements;
|
|
@@ -4430,6 +4939,20 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4430
4939
|
return new TransformStream({
|
|
4431
4940
|
transform(chunk, controller) {
|
|
4432
4941
|
var _a2;
|
|
4942
|
+
if (chunk.type === "finish") {
|
|
4943
|
+
if (currentToolCall) {
|
|
4944
|
+
const unfinishedContent = `<${currentToolCall.name}>${currentToolCall.content}${buffer}`;
|
|
4945
|
+
flushText(controller, unfinishedContent);
|
|
4946
|
+
buffer = "";
|
|
4947
|
+
currentToolCall = null;
|
|
4948
|
+
} else if (buffer) {
|
|
4949
|
+
flushText(controller, buffer);
|
|
4950
|
+
buffer = "";
|
|
4951
|
+
}
|
|
4952
|
+
flushText(controller);
|
|
4953
|
+
controller.enqueue(chunk);
|
|
4954
|
+
return;
|
|
4955
|
+
}
|
|
4433
4956
|
if (chunk.type !== "text-delta") {
|
|
4434
4957
|
if (buffer) {
|
|
4435
4958
|
flushText(controller, buffer);
|
|
@@ -4491,7 +5014,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4491
5014
|
break;
|
|
4492
5015
|
}
|
|
4493
5016
|
let p = ltIdx + 2;
|
|
4494
|
-
while (p < gtIdx &&
|
|
5017
|
+
while (p < gtIdx && WHITESPACE_REGEX5.test(text[p])) {
|
|
4495
5018
|
p++;
|
|
4496
5019
|
}
|
|
4497
5020
|
const nameStart = p;
|
|
@@ -4511,7 +5034,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4511
5034
|
pos = gtIdx === -1 ? text.length : gtIdx + 1;
|
|
4512
5035
|
} else {
|
|
4513
5036
|
let p = ltIdx + 1;
|
|
4514
|
-
while (p < text.length &&
|
|
5037
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
4515
5038
|
p++;
|
|
4516
5039
|
}
|
|
4517
5040
|
const nameStart = p;
|
|
@@ -4524,7 +5047,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4524
5047
|
break;
|
|
4525
5048
|
}
|
|
4526
5049
|
let r = gtIdx - 1;
|
|
4527
|
-
while (r >= nameStart &&
|
|
5050
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
4528
5051
|
r--;
|
|
4529
5052
|
}
|
|
4530
5053
|
const selfClosing = text[r] === "/";
|
|
@@ -4756,18 +5279,32 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4756
5279
|
}
|
|
4757
5280
|
const processedElements = [];
|
|
4758
5281
|
let currentIndex = 0;
|
|
4759
|
-
|
|
5282
|
+
let parseText = text;
|
|
5283
|
+
let toolCalls = findToolCalls2(parseText, toolNames);
|
|
5284
|
+
if (toolCalls.length === 0) {
|
|
5285
|
+
const repaired = tryRepairXmlSelfClosingRootWithBody(
|
|
5286
|
+
parseText,
|
|
5287
|
+
toolNames
|
|
5288
|
+
);
|
|
5289
|
+
if (repaired) {
|
|
5290
|
+
const repairedCalls = findToolCalls2(repaired, toolNames);
|
|
5291
|
+
if (repairedCalls.length > 0) {
|
|
5292
|
+
parseText = repaired;
|
|
5293
|
+
toolCalls = repairedCalls;
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
5296
|
+
}
|
|
4760
5297
|
for (const tc of toolCalls) {
|
|
4761
5298
|
currentIndex = processToolCallMatch(
|
|
4762
|
-
|
|
5299
|
+
parseText,
|
|
4763
5300
|
tc,
|
|
4764
5301
|
currentIndex,
|
|
4765
5302
|
processedElements,
|
|
4766
5303
|
options
|
|
4767
5304
|
);
|
|
4768
5305
|
}
|
|
4769
|
-
if (currentIndex <
|
|
4770
|
-
addTextSegment(
|
|
5306
|
+
if (currentIndex < parseText.length) {
|
|
5307
|
+
addTextSegment(parseText.substring(currentIndex), processedElements);
|
|
4771
5308
|
}
|
|
4772
5309
|
return processedElements;
|
|
4773
5310
|
},
|
|
@@ -4863,6 +5400,20 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4863
5400
|
return new TransformStream({
|
|
4864
5401
|
transform(chunk, controller) {
|
|
4865
5402
|
var _a;
|
|
5403
|
+
if (chunk.type === "finish") {
|
|
5404
|
+
if (currentToolCall) {
|
|
5405
|
+
const unfinishedContent = `<${currentToolCall.name}>${buffer}`;
|
|
5406
|
+
flushText(controller, unfinishedContent);
|
|
5407
|
+
buffer = "";
|
|
5408
|
+
currentToolCall = null;
|
|
5409
|
+
} else if (buffer) {
|
|
5410
|
+
flushText(controller, buffer);
|
|
5411
|
+
buffer = "";
|
|
5412
|
+
}
|
|
5413
|
+
flushText(controller);
|
|
5414
|
+
controller.enqueue(chunk);
|
|
5415
|
+
return;
|
|
5416
|
+
}
|
|
4866
5417
|
if (chunk.type !== "text-delta") {
|
|
4867
5418
|
if (buffer) {
|
|
4868
5419
|
flushText(controller, buffer);
|
|
@@ -4986,17 +5537,56 @@ function encodeOriginalTools(tools) {
|
|
|
4986
5537
|
inputSchema: JSON.stringify(t.inputSchema)
|
|
4987
5538
|
}))) || [];
|
|
4988
5539
|
}
|
|
4989
|
-
function decodeOriginalTools(originalTools) {
|
|
5540
|
+
function decodeOriginalTools(originalTools, options) {
|
|
5541
|
+
var _a, _b, _c;
|
|
4990
5542
|
if (!originalTools) {
|
|
4991
5543
|
return [];
|
|
4992
5544
|
}
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5545
|
+
const decodedTools = [];
|
|
5546
|
+
for (const [index, tool] of originalTools.entries()) {
|
|
5547
|
+
if (!tool || typeof tool.name !== "string") {
|
|
5548
|
+
(_a = options == null ? void 0 : options.onError) == null ? void 0 : _a.call(options, "Invalid originalTools entry: missing tool name", {
|
|
5549
|
+
index,
|
|
5550
|
+
tool
|
|
5551
|
+
});
|
|
5552
|
+
continue;
|
|
5553
|
+
}
|
|
5554
|
+
if (typeof tool.inputSchema !== "string") {
|
|
5555
|
+
(_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
|
|
5556
|
+
options,
|
|
5557
|
+
"Invalid originalTools entry: inputSchema must be a string",
|
|
5558
|
+
{
|
|
5559
|
+
index,
|
|
5560
|
+
toolName: tool.name
|
|
5561
|
+
}
|
|
5562
|
+
);
|
|
5563
|
+
continue;
|
|
5564
|
+
}
|
|
5565
|
+
try {
|
|
5566
|
+
decodedTools.push({
|
|
5567
|
+
type: "function",
|
|
5568
|
+
name: tool.name,
|
|
5569
|
+
inputSchema: JSON.parse(tool.inputSchema)
|
|
5570
|
+
});
|
|
5571
|
+
} catch (error) {
|
|
5572
|
+
(_c = options == null ? void 0 : options.onError) == null ? void 0 : _c.call(
|
|
5573
|
+
options,
|
|
5574
|
+
"Failed to decode originalTools input schema, using permissive fallback schema",
|
|
5575
|
+
{
|
|
5576
|
+
index,
|
|
5577
|
+
toolName: tool.name,
|
|
5578
|
+
inputSchema: tool.inputSchema,
|
|
5579
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5580
|
+
}
|
|
5581
|
+
);
|
|
5582
|
+
decodedTools.push({
|
|
5583
|
+
type: "function",
|
|
5584
|
+
name: tool.name,
|
|
5585
|
+
inputSchema: { type: "object" }
|
|
5586
|
+
});
|
|
5587
|
+
}
|
|
5588
|
+
}
|
|
5589
|
+
return decodedTools;
|
|
5000
5590
|
}
|
|
5001
5591
|
function isToolChoiceActive(params) {
|
|
5002
5592
|
var _a, _b, _c;
|
|
@@ -5006,23 +5596,337 @@ function isToolChoiceActive(params) {
|
|
|
5006
5596
|
|
|
5007
5597
|
// src/generate-handler.ts
|
|
5008
5598
|
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
5009
|
-
|
|
5599
|
+
|
|
5600
|
+
// src/core/utils/generated-text-json-recovery.ts
|
|
5601
|
+
function isRecord(value) {
|
|
5602
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5603
|
+
}
|
|
5604
|
+
function safeStringify2(value) {
|
|
5605
|
+
try {
|
|
5606
|
+
return JSON.stringify(value != null ? value : {});
|
|
5607
|
+
} catch (e) {
|
|
5608
|
+
return "{}";
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
function parseJsonCandidate(candidateText) {
|
|
5612
|
+
try {
|
|
5613
|
+
return parse(candidateText);
|
|
5614
|
+
} catch (e) {
|
|
5615
|
+
return void 0;
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
function extractCodeBlockCandidates(text) {
|
|
5619
|
+
var _a, _b;
|
|
5620
|
+
const codeBlockRegex = /```(?:json|yaml|xml)?\s*([\s\S]*?)```/gi;
|
|
5621
|
+
const candidates = [];
|
|
5622
|
+
let match;
|
|
5623
|
+
while (true) {
|
|
5624
|
+
match = codeBlockRegex.exec(text);
|
|
5625
|
+
if (!match) {
|
|
5626
|
+
break;
|
|
5627
|
+
}
|
|
5628
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
5629
|
+
if (body) {
|
|
5630
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
5631
|
+
const endIndex = startIndex + match[0].length;
|
|
5632
|
+
candidates.push({
|
|
5633
|
+
text: body,
|
|
5634
|
+
startIndex,
|
|
5635
|
+
endIndex
|
|
5636
|
+
});
|
|
5637
|
+
}
|
|
5638
|
+
}
|
|
5639
|
+
return candidates;
|
|
5640
|
+
}
|
|
5641
|
+
function scanJsonChar(state, char) {
|
|
5642
|
+
if (state.inString) {
|
|
5643
|
+
if (state.escaping) {
|
|
5644
|
+
return { ...state, escaping: false };
|
|
5645
|
+
}
|
|
5646
|
+
if (char === "\\") {
|
|
5647
|
+
return { ...state, escaping: true };
|
|
5648
|
+
}
|
|
5649
|
+
if (char === '"') {
|
|
5650
|
+
return { ...state, inString: false };
|
|
5651
|
+
}
|
|
5652
|
+
return state;
|
|
5653
|
+
}
|
|
5654
|
+
if (char === '"') {
|
|
5655
|
+
return { ...state, inString: true };
|
|
5656
|
+
}
|
|
5657
|
+
if (char === "{") {
|
|
5658
|
+
return { ...state, depth: state.depth + 1 };
|
|
5659
|
+
}
|
|
5660
|
+
if (char === "}") {
|
|
5661
|
+
return { ...state, depth: Math.max(0, state.depth - 1) };
|
|
5662
|
+
}
|
|
5663
|
+
return state;
|
|
5664
|
+
}
|
|
5665
|
+
function extractBalancedJsonObjects(text) {
|
|
5666
|
+
const maxCandidateLength = 1e4;
|
|
5667
|
+
const candidates = [];
|
|
5668
|
+
let state = { depth: 0, inString: false, escaping: false };
|
|
5669
|
+
let currentStart = null;
|
|
5670
|
+
let ignoreCurrent = false;
|
|
5671
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
5672
|
+
const char = text[index];
|
|
5673
|
+
if (!state.inString && char === "{" && state.depth === 0) {
|
|
5674
|
+
currentStart = index;
|
|
5675
|
+
ignoreCurrent = false;
|
|
5676
|
+
}
|
|
5677
|
+
state = scanJsonChar(state, char);
|
|
5678
|
+
if (currentStart !== null && !ignoreCurrent && index - currentStart + 1 > maxCandidateLength) {
|
|
5679
|
+
ignoreCurrent = true;
|
|
5680
|
+
}
|
|
5681
|
+
if (!state.inString && char === "}" && state.depth === 0) {
|
|
5682
|
+
if (currentStart !== null && !ignoreCurrent) {
|
|
5683
|
+
const endIndex = index + 1;
|
|
5684
|
+
const candidate = text.slice(currentStart, endIndex);
|
|
5685
|
+
if (candidate.length > 1) {
|
|
5686
|
+
candidates.push({
|
|
5687
|
+
text: candidate,
|
|
5688
|
+
startIndex: currentStart,
|
|
5689
|
+
endIndex
|
|
5690
|
+
});
|
|
5691
|
+
}
|
|
5692
|
+
}
|
|
5693
|
+
currentStart = null;
|
|
5694
|
+
ignoreCurrent = false;
|
|
5695
|
+
}
|
|
5696
|
+
}
|
|
5697
|
+
return candidates;
|
|
5698
|
+
}
|
|
5699
|
+
function extractTaggedToolCallCandidates(rawText) {
|
|
5700
|
+
var _a, _b;
|
|
5701
|
+
const toolCallRegex = /<tool_call>([\s\S]*?)<\/tool_call>/gi;
|
|
5702
|
+
const candidates = [];
|
|
5703
|
+
let match;
|
|
5704
|
+
while (true) {
|
|
5705
|
+
match = toolCallRegex.exec(rawText);
|
|
5706
|
+
if (!match) {
|
|
5707
|
+
break;
|
|
5708
|
+
}
|
|
5709
|
+
const body = (_a = match[1]) == null ? void 0 : _a.trim();
|
|
5710
|
+
if (!body) {
|
|
5711
|
+
continue;
|
|
5712
|
+
}
|
|
5713
|
+
const startIndex = (_b = match.index) != null ? _b : 0;
|
|
5714
|
+
const endIndex = startIndex + match[0].length;
|
|
5715
|
+
candidates.push({
|
|
5716
|
+
text: body,
|
|
5717
|
+
startIndex,
|
|
5718
|
+
endIndex
|
|
5719
|
+
});
|
|
5720
|
+
}
|
|
5721
|
+
return candidates;
|
|
5722
|
+
}
|
|
5723
|
+
function extractJsonLikeCandidates(rawText) {
|
|
5724
|
+
return mergeJsonCandidatesByStart(
|
|
5725
|
+
extractTaggedToolCallCandidates(rawText),
|
|
5726
|
+
extractCodeBlockCandidates(rawText),
|
|
5727
|
+
extractBalancedJsonObjects(rawText)
|
|
5728
|
+
);
|
|
5729
|
+
}
|
|
5730
|
+
function mergeJsonCandidatesByStart(tagged, codeBlocks, balanced) {
|
|
5731
|
+
return [...tagged, ...codeBlocks, ...balanced].sort(
|
|
5732
|
+
(a, b) => a.startIndex !== b.startIndex ? a.startIndex - b.startIndex : b.endIndex - a.endIndex
|
|
5733
|
+
);
|
|
5734
|
+
}
|
|
5735
|
+
function toToolCallPart(candidate) {
|
|
5736
|
+
return {
|
|
5737
|
+
type: "tool-call",
|
|
5738
|
+
toolCallId: generateId(),
|
|
5739
|
+
toolName: candidate.toolName,
|
|
5740
|
+
input: candidate.input
|
|
5741
|
+
};
|
|
5742
|
+
}
|
|
5743
|
+
function toRecoveredParts(text, candidate, toolCallPart) {
|
|
5744
|
+
const out = [];
|
|
5745
|
+
const prefix = text.slice(0, candidate.startIndex);
|
|
5746
|
+
if (prefix.length > 0) {
|
|
5747
|
+
out.push({ type: "text", text: prefix });
|
|
5748
|
+
}
|
|
5749
|
+
out.push(toolCallPart);
|
|
5750
|
+
const suffix = text.slice(candidate.endIndex);
|
|
5751
|
+
if (suffix.length > 0) {
|
|
5752
|
+
out.push({ type: "text", text: suffix });
|
|
5753
|
+
}
|
|
5754
|
+
return out;
|
|
5755
|
+
}
|
|
5756
|
+
function parseAsToolPayload(payload, tools) {
|
|
5757
|
+
if (!isRecord(payload)) {
|
|
5758
|
+
return null;
|
|
5759
|
+
}
|
|
5760
|
+
const toolName = typeof payload.name === "string" && payload.name.trim().length > 0 ? payload.name.trim() : null;
|
|
5761
|
+
if (!toolName) {
|
|
5762
|
+
return null;
|
|
5763
|
+
}
|
|
5764
|
+
if (!tools.some((tool) => tool.name === toolName)) {
|
|
5765
|
+
return null;
|
|
5766
|
+
}
|
|
5767
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
5768
|
+
if (!isRecord(rawArgs)) {
|
|
5769
|
+
return null;
|
|
5770
|
+
}
|
|
5771
|
+
return {
|
|
5772
|
+
toolName,
|
|
5773
|
+
input: safeStringify2(rawArgs)
|
|
5774
|
+
};
|
|
5775
|
+
}
|
|
5776
|
+
function isLikelyArgumentsShapeForTool(args, tool) {
|
|
5777
|
+
const unwrapped = unwrapJsonSchema(tool.inputSchema);
|
|
5778
|
+
if (!isRecord(unwrapped)) {
|
|
5779
|
+
return false;
|
|
5780
|
+
}
|
|
5781
|
+
if (getSchemaType(unwrapped) !== "object") {
|
|
5782
|
+
return false;
|
|
5783
|
+
}
|
|
5784
|
+
const properties = unwrapped.properties;
|
|
5785
|
+
if (!isRecord(properties)) {
|
|
5786
|
+
return false;
|
|
5787
|
+
}
|
|
5788
|
+
const keys = Object.keys(args);
|
|
5789
|
+
if (keys.length === 0) {
|
|
5790
|
+
return false;
|
|
5791
|
+
}
|
|
5792
|
+
const knownKeys = keys.filter((key) => Object.hasOwn(properties, key));
|
|
5793
|
+
if (knownKeys.length === 0) {
|
|
5794
|
+
return false;
|
|
5795
|
+
}
|
|
5796
|
+
if (unwrapped.additionalProperties === false && knownKeys.length !== keys.length) {
|
|
5797
|
+
return false;
|
|
5798
|
+
}
|
|
5799
|
+
return true;
|
|
5800
|
+
}
|
|
5801
|
+
function parseAsArgumentsOnly(payload, tools) {
|
|
5802
|
+
if (tools.length !== 1) {
|
|
5803
|
+
return null;
|
|
5804
|
+
}
|
|
5805
|
+
if (!isRecord(payload)) {
|
|
5806
|
+
return null;
|
|
5807
|
+
}
|
|
5808
|
+
const hasNameEnvelope = Object.hasOwn(payload, "name") && typeof payload.name === "string" && payload.name.length > 0;
|
|
5809
|
+
const hasArgumentsEnvelope = Object.hasOwn(payload, "arguments") && (typeof payload.arguments === "string" || isRecord(payload.arguments));
|
|
5810
|
+
if (hasNameEnvelope || hasArgumentsEnvelope) {
|
|
5811
|
+
return null;
|
|
5812
|
+
}
|
|
5813
|
+
const tool = tools[0];
|
|
5814
|
+
if (!isLikelyArgumentsShapeForTool(payload, tool)) {
|
|
5815
|
+
return null;
|
|
5816
|
+
}
|
|
5817
|
+
return {
|
|
5818
|
+
toolName: tool.name,
|
|
5819
|
+
input: safeStringify2(payload)
|
|
5820
|
+
};
|
|
5821
|
+
}
|
|
5822
|
+
function recoverToolCallFromJsonCandidates(text, tools) {
|
|
5823
|
+
if (tools.length === 0) {
|
|
5824
|
+
return null;
|
|
5825
|
+
}
|
|
5826
|
+
const jsonCandidates = extractJsonLikeCandidates(text);
|
|
5827
|
+
for (const jsonCandidate of jsonCandidates) {
|
|
5828
|
+
const parsed = parseJsonCandidate(jsonCandidate.text);
|
|
5829
|
+
if (parsed === void 0) {
|
|
5830
|
+
continue;
|
|
5831
|
+
}
|
|
5832
|
+
const toolPayload = parseAsToolPayload(parsed, tools);
|
|
5833
|
+
if (toolPayload) {
|
|
5834
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(toolPayload));
|
|
5835
|
+
}
|
|
5836
|
+
const argsPayload = parseAsArgumentsOnly(parsed, tools);
|
|
5837
|
+
if (argsPayload) {
|
|
5838
|
+
return toRecoveredParts(text, jsonCandidate, toToolCallPart(argsPayload));
|
|
5839
|
+
}
|
|
5840
|
+
}
|
|
5841
|
+
return null;
|
|
5842
|
+
}
|
|
5843
|
+
|
|
5844
|
+
// src/core/utils/tool-call-coercion.ts
|
|
5845
|
+
function coerceToolCallInput(toolName, input, tools) {
|
|
5010
5846
|
var _a;
|
|
5847
|
+
let args = {};
|
|
5848
|
+
if (typeof input === "string") {
|
|
5849
|
+
try {
|
|
5850
|
+
args = JSON.parse(input);
|
|
5851
|
+
} catch (e) {
|
|
5852
|
+
return;
|
|
5853
|
+
}
|
|
5854
|
+
} else if (input && typeof input === "object") {
|
|
5855
|
+
args = input;
|
|
5856
|
+
} else {
|
|
5857
|
+
return;
|
|
5858
|
+
}
|
|
5859
|
+
const schema = (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
5860
|
+
const coerced = coerceBySchema(args, schema);
|
|
5861
|
+
return JSON.stringify(coerced != null ? coerced : {});
|
|
5862
|
+
}
|
|
5863
|
+
function coerceToolCallPart(part, tools) {
|
|
5864
|
+
const coercedInput = coerceToolCallInput(part.toolName, part.input, tools);
|
|
5865
|
+
if (coercedInput === void 0) {
|
|
5866
|
+
return part;
|
|
5867
|
+
}
|
|
5868
|
+
return {
|
|
5869
|
+
...part,
|
|
5870
|
+
input: coercedInput
|
|
5871
|
+
};
|
|
5872
|
+
}
|
|
5873
|
+
|
|
5874
|
+
// src/core/utils/tool-choice.ts
|
|
5875
|
+
function ensureNonEmptyToolName(name) {
|
|
5876
|
+
if (typeof name !== "string") {
|
|
5877
|
+
return "unknown";
|
|
5878
|
+
}
|
|
5879
|
+
const trimmed = name.trim();
|
|
5880
|
+
return trimmed.length > 0 ? trimmed : "unknown";
|
|
5881
|
+
}
|
|
5882
|
+
function safeStringify3(value) {
|
|
5883
|
+
try {
|
|
5884
|
+
return JSON.stringify(value != null ? value : {});
|
|
5885
|
+
} catch (e) {
|
|
5886
|
+
return "{}";
|
|
5887
|
+
}
|
|
5888
|
+
}
|
|
5889
|
+
function parseToolChoicePayload({
|
|
5890
|
+
text,
|
|
5891
|
+
tools,
|
|
5892
|
+
onError,
|
|
5893
|
+
errorMessage
|
|
5894
|
+
}) {
|
|
5895
|
+
let parsed;
|
|
5011
5896
|
try {
|
|
5012
|
-
|
|
5897
|
+
parsed = JSON.parse(text);
|
|
5013
5898
|
} catch (error) {
|
|
5014
|
-
|
|
5015
|
-
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5899
|
+
onError == null ? void 0 : onError(errorMessage, {
|
|
5900
|
+
text,
|
|
5901
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5902
|
+
});
|
|
5903
|
+
return { toolName: "unknown", input: "{}" };
|
|
5904
|
+
}
|
|
5905
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
5906
|
+
onError == null ? void 0 : onError("toolChoice JSON payload must be an object", {
|
|
5907
|
+
parsedType: typeof parsed,
|
|
5908
|
+
parsed
|
|
5909
|
+
});
|
|
5910
|
+
return { toolName: "unknown", input: "{}" };
|
|
5024
5911
|
}
|
|
5912
|
+
const payload = parsed;
|
|
5913
|
+
const toolName = ensureNonEmptyToolName(payload.name);
|
|
5914
|
+
const rawArgs = Object.hasOwn(payload, "arguments") ? payload.arguments : {};
|
|
5915
|
+
if (rawArgs == null || typeof rawArgs !== "object" || Array.isArray(rawArgs)) {
|
|
5916
|
+
onError == null ? void 0 : onError("toolChoice arguments must be a JSON object", {
|
|
5917
|
+
toolName,
|
|
5918
|
+
arguments: rawArgs
|
|
5919
|
+
});
|
|
5920
|
+
return { toolName, input: "{}" };
|
|
5921
|
+
}
|
|
5922
|
+
const coercedInput = coerceToolCallInput(toolName, rawArgs, tools);
|
|
5923
|
+
return {
|
|
5924
|
+
toolName,
|
|
5925
|
+
input: coercedInput != null ? coercedInput : safeStringify3(rawArgs)
|
|
5926
|
+
};
|
|
5025
5927
|
}
|
|
5928
|
+
|
|
5929
|
+
// src/generate-handler.ts
|
|
5026
5930
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
5027
5931
|
if (debugSummary) {
|
|
5028
5932
|
debugSummary.originalText = originText;
|
|
@@ -5036,25 +5940,34 @@ function logDebugSummary(debugSummary, toolCall, originText) {
|
|
|
5036
5940
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
5037
5941
|
}
|
|
5038
5942
|
}
|
|
5039
|
-
async function handleToolChoice(doGenerate, params) {
|
|
5040
|
-
var _a, _b, _c;
|
|
5943
|
+
async function handleToolChoice(doGenerate, params, tools) {
|
|
5944
|
+
var _a, _b, _c, _d;
|
|
5041
5945
|
const result = await doGenerate();
|
|
5042
5946
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
5043
|
-
|
|
5947
|
+
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
5948
|
+
let toolName = "unknown";
|
|
5949
|
+
let input = "{}";
|
|
5044
5950
|
if (first && first.type === "text") {
|
|
5045
5951
|
if (getDebugLevel() === "parse") {
|
|
5046
5952
|
logRawChunk(first.text);
|
|
5047
5953
|
}
|
|
5048
|
-
parsed =
|
|
5954
|
+
const parsed = parseToolChoicePayload({
|
|
5955
|
+
text: first.text,
|
|
5956
|
+
tools,
|
|
5957
|
+
onError,
|
|
5958
|
+
errorMessage: "Failed to parse toolChoice JSON from generated model output"
|
|
5959
|
+
});
|
|
5960
|
+
toolName = parsed.toolName;
|
|
5961
|
+
input = parsed.input;
|
|
5049
5962
|
}
|
|
5050
5963
|
const toolCall = {
|
|
5051
5964
|
type: "tool-call",
|
|
5052
5965
|
toolCallId: (0, import_provider_utils.generateId)(),
|
|
5053
|
-
toolName
|
|
5054
|
-
input
|
|
5966
|
+
toolName,
|
|
5967
|
+
input
|
|
5055
5968
|
};
|
|
5056
5969
|
const originText = first && first.type === "text" ? first.text : "";
|
|
5057
|
-
const debugSummary = (
|
|
5970
|
+
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
5058
5971
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
5059
5972
|
return {
|
|
5060
5973
|
...result,
|
|
@@ -5069,7 +5982,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5069
5982
|
if (getDebugLevel() === "stream") {
|
|
5070
5983
|
logRawChunk(contentItem.text);
|
|
5071
5984
|
}
|
|
5072
|
-
|
|
5985
|
+
const parsedByProtocol = protocol.parseGeneratedText({
|
|
5073
5986
|
text: contentItem.text,
|
|
5074
5987
|
tools,
|
|
5075
5988
|
options: {
|
|
@@ -5077,9 +5990,20 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5077
5990
|
...providerOptions == null ? void 0 : providerOptions.toolCallMiddleware
|
|
5078
5991
|
}
|
|
5079
5992
|
});
|
|
5993
|
+
const hasToolCall = parsedByProtocol.some(
|
|
5994
|
+
(part) => part.type === "tool-call"
|
|
5995
|
+
);
|
|
5996
|
+
if (hasToolCall) {
|
|
5997
|
+
return parsedByProtocol;
|
|
5998
|
+
}
|
|
5999
|
+
const recoveredFromJson = recoverToolCallFromJsonCandidates(
|
|
6000
|
+
contentItem.text,
|
|
6001
|
+
tools
|
|
6002
|
+
);
|
|
6003
|
+
return recoveredFromJson != null ? recoveredFromJson : parsedByProtocol;
|
|
5080
6004
|
});
|
|
5081
6005
|
return parsed.map(
|
|
5082
|
-
(part) =>
|
|
6006
|
+
(part) => part.type === "tool-call" ? coerceToolCallPart(part, tools) : part
|
|
5083
6007
|
);
|
|
5084
6008
|
}
|
|
5085
6009
|
function logParsedContent(content) {
|
|
@@ -5122,12 +6046,14 @@ async function wrapGenerate({
|
|
|
5122
6046
|
params
|
|
5123
6047
|
}) {
|
|
5124
6048
|
var _a, _b;
|
|
5125
|
-
|
|
5126
|
-
return handleToolChoice(doGenerate, params);
|
|
5127
|
-
}
|
|
6049
|
+
const onError = extractOnErrorOption(params.providerOptions);
|
|
5128
6050
|
const tools = originalToolsSchema.decode(
|
|
5129
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
6051
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
6052
|
+
onError
|
|
5130
6053
|
);
|
|
6054
|
+
if (isToolChoiceActive(params)) {
|
|
6055
|
+
return handleToolChoice(doGenerate, params, tools);
|
|
6056
|
+
}
|
|
5131
6057
|
const result = await doGenerate();
|
|
5132
6058
|
if (result.content.length === 0) {
|
|
5133
6059
|
return result;
|
|
@@ -5151,28 +6077,6 @@ async function wrapGenerate({
|
|
|
5151
6077
|
content: newContent
|
|
5152
6078
|
};
|
|
5153
6079
|
}
|
|
5154
|
-
function fixToolCallWithSchema(part, tools) {
|
|
5155
|
-
var _a;
|
|
5156
|
-
if (part.type !== "tool-call") {
|
|
5157
|
-
return part;
|
|
5158
|
-
}
|
|
5159
|
-
let args = {};
|
|
5160
|
-
if (typeof part.input === "string") {
|
|
5161
|
-
try {
|
|
5162
|
-
args = JSON.parse(part.input);
|
|
5163
|
-
} catch (e) {
|
|
5164
|
-
return part;
|
|
5165
|
-
}
|
|
5166
|
-
} else if (part.input && typeof part.input === "object") {
|
|
5167
|
-
args = part.input;
|
|
5168
|
-
}
|
|
5169
|
-
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
5170
|
-
const coerced = coerceBySchema(args, schema);
|
|
5171
|
-
return {
|
|
5172
|
-
...part,
|
|
5173
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
5174
|
-
};
|
|
5175
|
-
}
|
|
5176
6080
|
|
|
5177
6081
|
// src/core/prompts/hermes-system-prompt.ts
|
|
5178
6082
|
function hermesSystemPromptTemplate(tools) {
|
|
@@ -5576,19 +6480,22 @@ async function wrapStream({
|
|
|
5576
6480
|
params
|
|
5577
6481
|
}) {
|
|
5578
6482
|
var _a, _b, _c;
|
|
6483
|
+
const onErrorOptions = extractOnErrorOption(params.providerOptions);
|
|
6484
|
+
const tools = originalToolsSchema.decode(
|
|
6485
|
+
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools,
|
|
6486
|
+
onErrorOptions
|
|
6487
|
+
);
|
|
5579
6488
|
if (isToolChoiceActive(params)) {
|
|
5580
6489
|
return toolChoiceStream({
|
|
5581
6490
|
doGenerate,
|
|
5582
|
-
|
|
6491
|
+
tools,
|
|
6492
|
+
options: onErrorOptions
|
|
5583
6493
|
});
|
|
5584
6494
|
}
|
|
5585
6495
|
const { stream, ...rest } = await doStream();
|
|
5586
6496
|
const debugLevel = getDebugLevel();
|
|
5587
|
-
const tools = originalToolsSchema.decode(
|
|
5588
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
5589
|
-
);
|
|
5590
6497
|
const options = {
|
|
5591
|
-
...
|
|
6498
|
+
...onErrorOptions,
|
|
5592
6499
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
5593
6500
|
};
|
|
5594
6501
|
const coreStream = stream.pipeThrough(
|
|
@@ -5606,10 +6513,11 @@ async function wrapStream({
|
|
|
5606
6513
|
const v3Stream = coreStream.pipeThrough(
|
|
5607
6514
|
new TransformStream({
|
|
5608
6515
|
transform(part, controller) {
|
|
6516
|
+
const normalizedPart = part.type === "tool-call" ? coerceToolCallPart(part, tools) : part;
|
|
5609
6517
|
if (debugLevel === "stream") {
|
|
5610
|
-
logParsedChunk(
|
|
6518
|
+
logParsedChunk(normalizedPart);
|
|
5611
6519
|
}
|
|
5612
|
-
controller.enqueue(
|
|
6520
|
+
controller.enqueue(normalizedPart);
|
|
5613
6521
|
}
|
|
5614
6522
|
})
|
|
5615
6523
|
);
|
|
@@ -5620,41 +6528,36 @@ async function wrapStream({
|
|
|
5620
6528
|
}
|
|
5621
6529
|
async function toolChoiceStream({
|
|
5622
6530
|
doGenerate,
|
|
6531
|
+
tools,
|
|
5623
6532
|
options
|
|
5624
6533
|
}) {
|
|
5625
|
-
var _a
|
|
6534
|
+
var _a;
|
|
6535
|
+
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
5626
6536
|
const result = await doGenerate();
|
|
5627
|
-
let
|
|
6537
|
+
let toolName = "unknown";
|
|
6538
|
+
let input = "{}";
|
|
5628
6539
|
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5638
|
-
}
|
|
5639
|
-
);
|
|
5640
|
-
toolJson = {};
|
|
5641
|
-
}
|
|
6540
|
+
const parsed = parseToolChoicePayload({
|
|
6541
|
+
text: result.content[0].text,
|
|
6542
|
+
tools: normalizedTools,
|
|
6543
|
+
onError: options == null ? void 0 : options.onError,
|
|
6544
|
+
errorMessage: "Failed to parse toolChoice JSON from streamed model output"
|
|
6545
|
+
});
|
|
6546
|
+
toolName = parsed.toolName;
|
|
6547
|
+
input = parsed.input;
|
|
5642
6548
|
}
|
|
5643
6549
|
const stream = new ReadableStream({
|
|
5644
6550
|
start(controller) {
|
|
5645
6551
|
controller.enqueue({
|
|
5646
6552
|
type: "tool-call",
|
|
5647
6553
|
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
5648
|
-
toolName
|
|
5649
|
-
input
|
|
6554
|
+
toolName,
|
|
6555
|
+
input
|
|
5650
6556
|
});
|
|
5651
6557
|
controller.enqueue({
|
|
5652
6558
|
type: "finish",
|
|
5653
|
-
usage: (result == null ? void 0 : result.usage)
|
|
5654
|
-
|
|
5655
|
-
outputTokens: 0
|
|
5656
|
-
},
|
|
5657
|
-
finishReason: "tool-calls"
|
|
6559
|
+
usage: normalizeUsage(result == null ? void 0 : result.usage),
|
|
6560
|
+
finishReason: normalizeToolCallsFinishReason(result == null ? void 0 : result.finishReason)
|
|
5658
6561
|
});
|
|
5659
6562
|
controller.close();
|
|
5660
6563
|
}
|
|
@@ -5665,6 +6568,60 @@ async function toolChoiceStream({
|
|
|
5665
6568
|
stream
|
|
5666
6569
|
};
|
|
5667
6570
|
}
|
|
6571
|
+
var ZERO_USAGE = {
|
|
6572
|
+
inputTokens: {
|
|
6573
|
+
total: 0,
|
|
6574
|
+
noCache: void 0,
|
|
6575
|
+
cacheRead: void 0,
|
|
6576
|
+
cacheWrite: void 0
|
|
6577
|
+
},
|
|
6578
|
+
outputTokens: {
|
|
6579
|
+
total: 0,
|
|
6580
|
+
text: void 0,
|
|
6581
|
+
reasoning: void 0
|
|
6582
|
+
}
|
|
6583
|
+
};
|
|
6584
|
+
function normalizeToolCallsFinishReason(finishReason) {
|
|
6585
|
+
let raw = "tool-calls";
|
|
6586
|
+
if (typeof finishReason === "string") {
|
|
6587
|
+
raw = finishReason;
|
|
6588
|
+
} else if (finishReason && typeof finishReason === "object" && "raw" in finishReason && typeof finishReason.raw === "string") {
|
|
6589
|
+
raw = finishReason.raw;
|
|
6590
|
+
} else if (finishReason && typeof finishReason === "object" && "unified" in finishReason && typeof finishReason.unified === "string") {
|
|
6591
|
+
raw = finishReason.unified;
|
|
6592
|
+
}
|
|
6593
|
+
return {
|
|
6594
|
+
unified: "tool-calls",
|
|
6595
|
+
raw
|
|
6596
|
+
};
|
|
6597
|
+
}
|
|
6598
|
+
function normalizeUsage(usage) {
|
|
6599
|
+
if (!usage || typeof usage !== "object") {
|
|
6600
|
+
return ZERO_USAGE;
|
|
6601
|
+
}
|
|
6602
|
+
const usageRecord = usage;
|
|
6603
|
+
const input = usageRecord.inputTokens;
|
|
6604
|
+
const output = usageRecord.outputTokens;
|
|
6605
|
+
if (input && typeof input === "object" && output && typeof output === "object") {
|
|
6606
|
+
return usage;
|
|
6607
|
+
}
|
|
6608
|
+
if (typeof input === "number" && typeof output === "number") {
|
|
6609
|
+
return {
|
|
6610
|
+
inputTokens: {
|
|
6611
|
+
total: input,
|
|
6612
|
+
noCache: void 0,
|
|
6613
|
+
cacheRead: void 0,
|
|
6614
|
+
cacheWrite: void 0
|
|
6615
|
+
},
|
|
6616
|
+
outputTokens: {
|
|
6617
|
+
total: output,
|
|
6618
|
+
text: void 0,
|
|
6619
|
+
reasoning: void 0
|
|
6620
|
+
}
|
|
6621
|
+
};
|
|
6622
|
+
}
|
|
6623
|
+
return ZERO_USAGE;
|
|
6624
|
+
}
|
|
5668
6625
|
|
|
5669
6626
|
// src/transform-handler.ts
|
|
5670
6627
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
@@ -5790,6 +6747,11 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
5790
6747
|
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
5791
6748
|
);
|
|
5792
6749
|
}
|
|
6750
|
+
if (functionTools.length === 0) {
|
|
6751
|
+
throw new Error(
|
|
6752
|
+
"Tool choice type 'required' is set, but no function tools are provided. Provider-defined tools are not supported by this middleware."
|
|
6753
|
+
);
|
|
6754
|
+
}
|
|
5793
6755
|
return {
|
|
5794
6756
|
...baseReturnParams,
|
|
5795
6757
|
responseFormat: {
|