@ai-sdk-tool/parser 3.3.1 → 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-EW3A6Y7O.js → chunk-CXWS24JX.js} +8 -5
- package/dist/chunk-CXWS24JX.js.map +1 -0
- package/dist/{chunk-7E6UFDFQ.js → chunk-NAQSTPDQ.js} +713 -125
- package/dist/chunk-NAQSTPDQ.js.map +1 -0
- package/dist/community.cjs +1088 -135
- package/dist/community.cjs.map +1 -1
- package/dist/community.js +3 -3
- package/dist/index.cjs +1088 -135
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -8
- package/dist/index.d.ts +20 -8
- package/dist/index.js +5 -4
- package/dist/rxml.cjs +382 -15
- 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 +13 -12
- package/dist/chunk-7E6UFDFQ.js.map +0 -1
- package/dist/chunk-EW3A6Y7O.js.map +0 -1
- package/dist/chunk-OUGMLYAW.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -908,6 +908,13 @@ function generateId() {
|
|
|
908
908
|
return Math.random().toString(36).substring(2, 15);
|
|
909
909
|
}
|
|
910
910
|
|
|
911
|
+
// src/core/utils/protocol-utils.ts
|
|
912
|
+
function addTextSegment(text, processedElements) {
|
|
913
|
+
if (text.trim()) {
|
|
914
|
+
processedElements.push({ type: "text", text });
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
|
|
911
918
|
// src/core/utils/regex.ts
|
|
912
919
|
function escapeRegExp(literal) {
|
|
913
920
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -939,11 +946,6 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
939
946
|
processedElements.push({ type: "text", text: fullMatch });
|
|
940
947
|
}
|
|
941
948
|
}
|
|
942
|
-
function addTextSegment(text, processedElements) {
|
|
943
|
-
if (text.trim()) {
|
|
944
|
-
processedElements.push({ type: "text", text });
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
949
|
function processMatchedToolCall(context) {
|
|
948
950
|
const { match, text, currentIndex, processedElements, options } = context;
|
|
949
951
|
const startIndex = match.index;
|
|
@@ -1575,6 +1577,13 @@ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
|
|
|
1575
1577
|
var NEWLINE_SPLIT_REGEX = /\n+/;
|
|
1576
1578
|
var COMMA_SPLIT_REGEX = /,\s*/;
|
|
1577
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 = /^_+/;
|
|
1578
1587
|
function unwrapJsonSchema(schema) {
|
|
1579
1588
|
if (!schema || typeof schema !== "object") {
|
|
1580
1589
|
return schema;
|
|
@@ -1823,9 +1832,158 @@ function coerceStringToArray(s, unwrapped) {
|
|
|
1823
1832
|
}
|
|
1824
1833
|
return null;
|
|
1825
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
|
+
}
|
|
1826
1983
|
function coerceObjectToObject(value, unwrapped) {
|
|
1984
|
+
const normalizedInput = applyStrictRequiredKeyRename(value, unwrapped);
|
|
1827
1985
|
const out = {};
|
|
1828
|
-
for (const [k, v] of Object.entries(
|
|
1986
|
+
for (const [k, v] of Object.entries(normalizedInput)) {
|
|
1829
1987
|
out[k] = coerceValueForKey(v, k, unwrapped);
|
|
1830
1988
|
}
|
|
1831
1989
|
return out;
|
|
@@ -1836,6 +1994,109 @@ function coerceArrayToArray(value, prefixItems, itemsSchema) {
|
|
|
1836
1994
|
}
|
|
1837
1995
|
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
1838
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
|
+
}
|
|
1839
2100
|
function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
1840
2101
|
if (Object.hasOwn(maybe, "item")) {
|
|
1841
2102
|
const items = maybe.item;
|
|
@@ -1847,15 +2108,23 @@ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
|
1847
2108
|
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
1848
2109
|
return coerceArrayToArray(arr, prefixItems, itemsSchema);
|
|
1849
2110
|
}
|
|
2111
|
+
const parallelArrays = coerceParallelArraysObjectToArray(
|
|
2112
|
+
maybe,
|
|
2113
|
+
prefixItems,
|
|
2114
|
+
itemsSchema
|
|
2115
|
+
);
|
|
2116
|
+
if (parallelArrays !== null) {
|
|
2117
|
+
return parallelArrays;
|
|
2118
|
+
}
|
|
1850
2119
|
if (keys.length === 1) {
|
|
1851
2120
|
const singleKey = keys[0];
|
|
1852
2121
|
if (!(schemaIsUnconstrained(itemsSchema) || schemaHasProperty(itemsSchema, singleKey))) {
|
|
1853
|
-
const
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
if (
|
|
1858
|
-
return
|
|
2122
|
+
const result = coerceSingleKeyObjectToArray(
|
|
2123
|
+
maybe[singleKey],
|
|
2124
|
+
itemsSchema
|
|
2125
|
+
);
|
|
2126
|
+
if (result !== null) {
|
|
2127
|
+
return result;
|
|
1859
2128
|
}
|
|
1860
2129
|
}
|
|
1861
2130
|
}
|
|
@@ -1885,6 +2154,86 @@ function coerceStringToPrimitive(s, schemaType) {
|
|
|
1885
2154
|
}
|
|
1886
2155
|
return null;
|
|
1887
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
|
+
}
|
|
1888
2237
|
function coerceStringValue(value, schemaType, u) {
|
|
1889
2238
|
const s = value.trim();
|
|
1890
2239
|
if (schemaType === "object") {
|
|
@@ -1903,6 +2252,10 @@ function coerceStringValue(value, schemaType, u) {
|
|
|
1903
2252
|
if (primitiveResult !== null) {
|
|
1904
2253
|
return primitiveResult;
|
|
1905
2254
|
}
|
|
2255
|
+
const enumWhitespaceCanonical = coerceStringByEnumWhitespace(s, u);
|
|
2256
|
+
if (enumWhitespaceCanonical !== null) {
|
|
2257
|
+
return enumWhitespaceCanonical;
|
|
2258
|
+
}
|
|
1906
2259
|
return value;
|
|
1907
2260
|
}
|
|
1908
2261
|
function coerceArrayValue(value, prefixItems, itemsSchema) {
|
|
@@ -1941,9 +2294,23 @@ function coerceBySchema(value, schema) {
|
|
|
1941
2294
|
if (typeof value === "string") {
|
|
1942
2295
|
return coerceStringValue(value, schemaType, u);
|
|
1943
2296
|
}
|
|
2297
|
+
const primitiveString = coercePrimitiveToString(value, schemaType);
|
|
2298
|
+
if (primitiveString !== null) {
|
|
2299
|
+
return primitiveString;
|
|
2300
|
+
}
|
|
1944
2301
|
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
1945
2302
|
return coerceObjectToObject(value, u);
|
|
1946
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
|
+
}
|
|
1947
2314
|
if (schemaType === "array") {
|
|
1948
2315
|
const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
|
|
1949
2316
|
const itemsSchema = u.items;
|
|
@@ -2958,7 +3325,7 @@ var XMLTokenizer = class {
|
|
|
2958
3325
|
};
|
|
2959
3326
|
|
|
2960
3327
|
// src/rxml/core/parser.ts
|
|
2961
|
-
var
|
|
3328
|
+
var WHITESPACE_REGEX3 = /\s/;
|
|
2962
3329
|
var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2963
3330
|
var DIGIT_KEY_REGEX2 = /^\d+$/;
|
|
2964
3331
|
function getTopLevelStringProps(s) {
|
|
@@ -3128,7 +3495,7 @@ function parse2(xmlInner, schema, options = {}) {
|
|
|
3128
3495
|
const closeHead = s.indexOf(`</${rootName}`, range.end);
|
|
3129
3496
|
if (closeHead === range.end) {
|
|
3130
3497
|
let p = closeHead + 2 + rootName.length;
|
|
3131
|
-
while (p < s.length &&
|
|
3498
|
+
while (p < s.length && WHITESPACE_REGEX3.test(s[p])) {
|
|
3132
3499
|
p += 1;
|
|
3133
3500
|
}
|
|
3134
3501
|
if (s[p] === ">") {
|
|
@@ -3466,7 +3833,7 @@ function createIntermediateCall(toolName, rawSegment, schema) {
|
|
|
3466
3833
|
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
3467
3834
|
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
3468
3835
|
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
3469
|
-
var
|
|
3836
|
+
var WHITESPACE_REGEX4 = /\s/;
|
|
3470
3837
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
3471
3838
|
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
3472
3839
|
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
@@ -3607,7 +3974,7 @@ function balanceTags(xml) {
|
|
|
3607
3974
|
}
|
|
3608
3975
|
function skipWs(s, p, len) {
|
|
3609
3976
|
let idx = p;
|
|
3610
|
-
while (idx < len &&
|
|
3977
|
+
while (idx < len && WHITESPACE_REGEX4.test(s[idx])) {
|
|
3611
3978
|
idx += 1;
|
|
3612
3979
|
}
|
|
3613
3980
|
return idx;
|
|
@@ -3660,7 +4027,7 @@ function handleOpeningTagSegment(src, lt, out, stack) {
|
|
|
3660
4027
|
return len;
|
|
3661
4028
|
}
|
|
3662
4029
|
let r = q - 1;
|
|
3663
|
-
while (r >= nameStart &&
|
|
4030
|
+
while (r >= nameStart && WHITESPACE_REGEX4.test(src[r])) {
|
|
3664
4031
|
r -= 1;
|
|
3665
4032
|
}
|
|
3666
4033
|
const selfClosing = src[r] === "/";
|
|
@@ -3703,12 +4070,9 @@ function getStringPropertyNames(schema) {
|
|
|
3703
4070
|
}
|
|
3704
4071
|
return names;
|
|
3705
4072
|
}
|
|
3706
|
-
function escapeRegExp2(s) {
|
|
3707
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3708
|
-
}
|
|
3709
4073
|
function dedupeSingleTag(xml, key) {
|
|
3710
4074
|
var _a, _b;
|
|
3711
|
-
const escaped =
|
|
4075
|
+
const escaped = escapeRegExp(key);
|
|
3712
4076
|
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
3713
4077
|
const matches = Array.from(xml.matchAll(re));
|
|
3714
4078
|
if (matches.length <= 1) {
|
|
@@ -3825,9 +4189,35 @@ function parse3(xml, schema, options = {}) {
|
|
|
3825
4189
|
throw new RXMLParseError("Failed to parse XML with repair heuristics", error);
|
|
3826
4190
|
}
|
|
3827
4191
|
|
|
3828
|
-
// src/core/
|
|
4192
|
+
// src/core/utils/regex-constants.ts
|
|
3829
4193
|
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
3830
|
-
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
|
+
}
|
|
4219
|
+
|
|
4220
|
+
// src/core/protocols/xml-protocol.ts
|
|
3831
4221
|
function getToolSchema(tools, toolName) {
|
|
3832
4222
|
var _a;
|
|
3833
4223
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
@@ -3929,7 +4319,7 @@ function consumeClosingTag(text, lt) {
|
|
|
3929
4319
|
}
|
|
3930
4320
|
function consumeOpenTag(text, lt) {
|
|
3931
4321
|
let p = lt + 1;
|
|
3932
|
-
while (p < text.length &&
|
|
4322
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3933
4323
|
p += 1;
|
|
3934
4324
|
}
|
|
3935
4325
|
const nameStart = p;
|
|
@@ -3942,7 +4332,7 @@ function consumeOpenTag(text, lt) {
|
|
|
3942
4332
|
return null;
|
|
3943
4333
|
}
|
|
3944
4334
|
let r = q - 1;
|
|
3945
|
-
while (r >= nameStart &&
|
|
4335
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
3946
4336
|
r -= 1;
|
|
3947
4337
|
}
|
|
3948
4338
|
const selfClosing = text[r] === "/";
|
|
@@ -3971,7 +4361,7 @@ function nextTagToken(text, fromPos) {
|
|
|
3971
4361
|
if (next === "/") {
|
|
3972
4362
|
const closing = consumeClosingTag(text, lt);
|
|
3973
4363
|
let p = lt + 2;
|
|
3974
|
-
while (p < text.length &&
|
|
4364
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3975
4365
|
p += 1;
|
|
3976
4366
|
}
|
|
3977
4367
|
const nameStart = p;
|
|
@@ -4108,6 +4498,102 @@ function findToolCalls(text, toolNames) {
|
|
|
4108
4498
|
}
|
|
4109
4499
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4110
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
|
+
}
|
|
4111
4597
|
function findEarliestToolTag(buffer, toolNames) {
|
|
4112
4598
|
var _a, _b;
|
|
4113
4599
|
let bestIndex = -1;
|
|
@@ -4146,7 +4632,7 @@ function isOpenTagPrefix(suffix, toolName) {
|
|
|
4146
4632
|
}
|
|
4147
4633
|
function consumeWhitespace(text, index) {
|
|
4148
4634
|
let i = index;
|
|
4149
|
-
while (i < text.length &&
|
|
4635
|
+
while (i < text.length && WHITESPACE_REGEX5.test(text.charAt(i))) {
|
|
4150
4636
|
i += 1;
|
|
4151
4637
|
}
|
|
4152
4638
|
return i;
|
|
@@ -4397,6 +4883,27 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
4397
4883
|
}
|
|
4398
4884
|
};
|
|
4399
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
|
+
}
|
|
4400
4907
|
var xmlProtocol = (protocolOptions) => {
|
|
4401
4908
|
var _a;
|
|
4402
4909
|
const parseOptions = {
|
|
@@ -4430,28 +4937,31 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4430
4937
|
}
|
|
4431
4938
|
const processedElements = [];
|
|
4432
4939
|
let currentIndex = 0;
|
|
4433
|
-
const toolCalls =
|
|
4940
|
+
const { parseText, toolCalls } = findToolCallsWithFallbacks(
|
|
4941
|
+
text,
|
|
4942
|
+
toolNames
|
|
4943
|
+
);
|
|
4434
4944
|
for (const tc of toolCalls) {
|
|
4435
4945
|
if (tc.startIndex > currentIndex) {
|
|
4436
4946
|
processedElements.push({
|
|
4437
4947
|
type: "text",
|
|
4438
|
-
text:
|
|
4948
|
+
text: parseText.substring(currentIndex, tc.startIndex)
|
|
4439
4949
|
});
|
|
4440
4950
|
}
|
|
4441
4951
|
processToolCall({
|
|
4442
4952
|
toolCall: tc,
|
|
4443
4953
|
tools,
|
|
4444
4954
|
options,
|
|
4445
|
-
text,
|
|
4955
|
+
text: parseText,
|
|
4446
4956
|
processedElements,
|
|
4447
4957
|
parseOptions
|
|
4448
4958
|
});
|
|
4449
4959
|
currentIndex = tc.endIndex;
|
|
4450
4960
|
}
|
|
4451
|
-
if (currentIndex <
|
|
4961
|
+
if (currentIndex < parseText.length) {
|
|
4452
4962
|
processedElements.push({
|
|
4453
4963
|
type: "text",
|
|
4454
|
-
text:
|
|
4964
|
+
text: parseText.substring(currentIndex)
|
|
4455
4965
|
});
|
|
4456
4966
|
}
|
|
4457
4967
|
return processedElements;
|
|
@@ -4490,6 +5000,20 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4490
5000
|
return new TransformStream({
|
|
4491
5001
|
transform(chunk, controller) {
|
|
4492
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
|
+
}
|
|
4493
5017
|
if (chunk.type !== "text-delta") {
|
|
4494
5018
|
if (buffer) {
|
|
4495
5019
|
flushText(controller, buffer);
|
|
@@ -4535,8 +5059,6 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4535
5059
|
|
|
4536
5060
|
// src/core/protocols/yaml-protocol.ts
|
|
4537
5061
|
var import_yaml = __toESM(require("yaml"), 1);
|
|
4538
|
-
var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
|
|
4539
|
-
var WHITESPACE_REGEX5 = /\s/;
|
|
4540
5062
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
4541
5063
|
function findClosingTagEnd(text, contentStart, toolName) {
|
|
4542
5064
|
let pos = contentStart;
|
|
@@ -4557,7 +5079,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4557
5079
|
p++;
|
|
4558
5080
|
}
|
|
4559
5081
|
const nameStart = p;
|
|
4560
|
-
while (p < gtIdx &&
|
|
5082
|
+
while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
4561
5083
|
p++;
|
|
4562
5084
|
}
|
|
4563
5085
|
const name = text.slice(nameStart, p);
|
|
@@ -4577,7 +5099,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4577
5099
|
p++;
|
|
4578
5100
|
}
|
|
4579
5101
|
const nameStart = p;
|
|
4580
|
-
while (p < text.length &&
|
|
5102
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
4581
5103
|
p++;
|
|
4582
5104
|
}
|
|
4583
5105
|
const name = text.slice(nameStart, p);
|
|
@@ -4704,22 +5226,14 @@ function parseYamlContent(yamlContent, options) {
|
|
|
4704
5226
|
return null;
|
|
4705
5227
|
}
|
|
4706
5228
|
}
|
|
4707
|
-
function appendTextPart(processedElements, textPart) {
|
|
4708
|
-
if (textPart.trim()) {
|
|
4709
|
-
processedElements.push({
|
|
4710
|
-
type: "text",
|
|
4711
|
-
text: textPart
|
|
4712
|
-
});
|
|
4713
|
-
}
|
|
4714
|
-
}
|
|
4715
5229
|
function processToolCallMatch(text, tc, currentIndex, processedElements, options) {
|
|
4716
5230
|
var _a;
|
|
4717
5231
|
if (tc.startIndex < currentIndex) {
|
|
4718
5232
|
return currentIndex;
|
|
4719
5233
|
}
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
5234
|
+
addTextSegment(
|
|
5235
|
+
text.substring(currentIndex, tc.startIndex),
|
|
5236
|
+
processedElements
|
|
4723
5237
|
);
|
|
4724
5238
|
const parsedArgs = parseYamlContent(tc.content, options);
|
|
4725
5239
|
if (parsedArgs !== null) {
|
|
@@ -4826,18 +5340,32 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4826
5340
|
}
|
|
4827
5341
|
const processedElements = [];
|
|
4828
5342
|
let currentIndex = 0;
|
|
4829
|
-
|
|
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
|
+
}
|
|
4830
5358
|
for (const tc of toolCalls) {
|
|
4831
5359
|
currentIndex = processToolCallMatch(
|
|
4832
|
-
|
|
5360
|
+
parseText,
|
|
4833
5361
|
tc,
|
|
4834
5362
|
currentIndex,
|
|
4835
5363
|
processedElements,
|
|
4836
5364
|
options
|
|
4837
5365
|
);
|
|
4838
5366
|
}
|
|
4839
|
-
if (currentIndex <
|
|
4840
|
-
|
|
5367
|
+
if (currentIndex < parseText.length) {
|
|
5368
|
+
addTextSegment(parseText.substring(currentIndex), processedElements);
|
|
4841
5369
|
}
|
|
4842
5370
|
return processedElements;
|
|
4843
5371
|
},
|
|
@@ -4933,6 +5461,20 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4933
5461
|
return new TransformStream({
|
|
4934
5462
|
transform(chunk, controller) {
|
|
4935
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
|
+
}
|
|
4936
5478
|
if (chunk.type !== "text-delta") {
|
|
4937
5479
|
if (buffer) {
|
|
4938
5480
|
flushText(controller, buffer);
|
|
@@ -5056,17 +5598,56 @@ function encodeOriginalTools(tools) {
|
|
|
5056
5598
|
inputSchema: JSON.stringify(t.inputSchema)
|
|
5057
5599
|
}))) || [];
|
|
5058
5600
|
}
|
|
5059
|
-
function decodeOriginalTools(originalTools) {
|
|
5601
|
+
function decodeOriginalTools(originalTools, options) {
|
|
5602
|
+
var _a, _b, _c;
|
|
5060
5603
|
if (!originalTools) {
|
|
5061
5604
|
return [];
|
|
5062
5605
|
}
|
|
5063
|
-
|
|
5064
|
-
|
|
5065
|
-
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5069
|
-
|
|
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;
|
|
5070
5651
|
}
|
|
5071
5652
|
function extractToolNamesFromOriginalTools(originalTools) {
|
|
5072
5653
|
return (originalTools == null ? void 0 : originalTools.map((t) => t.name)) || [];
|
|
@@ -5091,23 +5672,337 @@ function hasInputProperty(obj) {
|
|
|
5091
5672
|
|
|
5092
5673
|
// src/generate-handler.ts
|
|
5093
5674
|
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
5094
|
-
|
|
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) {
|
|
5095
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;
|
|
5096
5972
|
try {
|
|
5097
|
-
|
|
5973
|
+
parsed = JSON.parse(text);
|
|
5098
5974
|
} catch (error) {
|
|
5099
|
-
|
|
5100
|
-
|
|
5101
|
-
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
text,
|
|
5105
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5106
|
-
}
|
|
5107
|
-
);
|
|
5108
|
-
return {};
|
|
5975
|
+
onError == null ? void 0 : onError(errorMessage, {
|
|
5976
|
+
text,
|
|
5977
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5978
|
+
});
|
|
5979
|
+
return { toolName: "unknown", input: "{}" };
|
|
5109
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: "{}" };
|
|
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
|
+
};
|
|
5110
6003
|
}
|
|
6004
|
+
|
|
6005
|
+
// src/generate-handler.ts
|
|
5111
6006
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
5112
6007
|
if (debugSummary) {
|
|
5113
6008
|
debugSummary.originalText = originText;
|
|
@@ -5121,25 +6016,34 @@ function logDebugSummary(debugSummary, toolCall, originText) {
|
|
|
5121
6016
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
5122
6017
|
}
|
|
5123
6018
|
}
|
|
5124
|
-
async function handleToolChoice(doGenerate, params) {
|
|
5125
|
-
var _a, _b, _c;
|
|
6019
|
+
async function handleToolChoice(doGenerate, params, tools) {
|
|
6020
|
+
var _a, _b, _c, _d;
|
|
5126
6021
|
const result = await doGenerate();
|
|
5127
6022
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
5128
|
-
|
|
6023
|
+
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
6024
|
+
let toolName = "unknown";
|
|
6025
|
+
let input = "{}";
|
|
5129
6026
|
if (first && first.type === "text") {
|
|
5130
6027
|
if (getDebugLevel() === "parse") {
|
|
5131
6028
|
logRawChunk(first.text);
|
|
5132
6029
|
}
|
|
5133
|
-
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;
|
|
5134
6038
|
}
|
|
5135
6039
|
const toolCall = {
|
|
5136
6040
|
type: "tool-call",
|
|
5137
6041
|
toolCallId: (0, import_provider_utils.generateId)(),
|
|
5138
|
-
toolName
|
|
5139
|
-
input
|
|
6042
|
+
toolName,
|
|
6043
|
+
input
|
|
5140
6044
|
};
|
|
5141
6045
|
const originText = first && first.type === "text" ? first.text : "";
|
|
5142
|
-
const debugSummary = (
|
|
6046
|
+
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
5143
6047
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
5144
6048
|
return {
|
|
5145
6049
|
...result,
|
|
@@ -5154,7 +6058,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5154
6058
|
if (getDebugLevel() === "stream") {
|
|
5155
6059
|
logRawChunk(contentItem.text);
|
|
5156
6060
|
}
|
|
5157
|
-
|
|
6061
|
+
const parsedByProtocol = protocol.parseGeneratedText({
|
|
5158
6062
|
text: contentItem.text,
|
|
5159
6063
|
tools,
|
|
5160
6064
|
options: {
|
|
@@ -5162,9 +6066,20 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5162
6066
|
...providerOptions == null ? void 0 : providerOptions.toolCallMiddleware
|
|
5163
6067
|
}
|
|
5164
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;
|
|
5165
6080
|
});
|
|
5166
6081
|
return parsed.map(
|
|
5167
|
-
(part) =>
|
|
6082
|
+
(part) => part.type === "tool-call" ? coerceToolCallPart(part, tools) : part
|
|
5168
6083
|
);
|
|
5169
6084
|
}
|
|
5170
6085
|
function logParsedContent(content) {
|
|
@@ -5207,12 +6122,14 @@ async function wrapGenerate({
|
|
|
5207
6122
|
params
|
|
5208
6123
|
}) {
|
|
5209
6124
|
var _a, _b;
|
|
5210
|
-
|
|
5211
|
-
return handleToolChoice(doGenerate, params);
|
|
5212
|
-
}
|
|
6125
|
+
const onError = extractOnErrorOption(params.providerOptions);
|
|
5213
6126
|
const tools = originalToolsSchema.decode(
|
|
5214
|
-
(_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
|
|
5215
6129
|
);
|
|
6130
|
+
if (isToolChoiceActive(params)) {
|
|
6131
|
+
return handleToolChoice(doGenerate, params, tools);
|
|
6132
|
+
}
|
|
5216
6133
|
const result = await doGenerate();
|
|
5217
6134
|
if (result.content.length === 0) {
|
|
5218
6135
|
return result;
|
|
@@ -5236,28 +6153,6 @@ async function wrapGenerate({
|
|
|
5236
6153
|
content: newContent
|
|
5237
6154
|
};
|
|
5238
6155
|
}
|
|
5239
|
-
function fixToolCallWithSchema(part, tools) {
|
|
5240
|
-
var _a;
|
|
5241
|
-
if (part.type !== "tool-call") {
|
|
5242
|
-
return part;
|
|
5243
|
-
}
|
|
5244
|
-
let args = {};
|
|
5245
|
-
if (typeof part.input === "string") {
|
|
5246
|
-
try {
|
|
5247
|
-
args = JSON.parse(part.input);
|
|
5248
|
-
} catch (e) {
|
|
5249
|
-
return part;
|
|
5250
|
-
}
|
|
5251
|
-
} else if (part.input && typeof part.input === "object") {
|
|
5252
|
-
args = part.input;
|
|
5253
|
-
}
|
|
5254
|
-
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
5255
|
-
const coerced = coerceBySchema(args, schema);
|
|
5256
|
-
return {
|
|
5257
|
-
...part,
|
|
5258
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
5259
|
-
};
|
|
5260
|
-
}
|
|
5261
6156
|
|
|
5262
6157
|
// src/core/prompts/hermes-system-prompt.ts
|
|
5263
6158
|
function hermesSystemPromptTemplate(tools) {
|
|
@@ -5661,19 +6556,22 @@ async function wrapStream({
|
|
|
5661
6556
|
params
|
|
5662
6557
|
}) {
|
|
5663
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
|
+
);
|
|
5664
6564
|
if (isToolChoiceActive(params)) {
|
|
5665
6565
|
return toolChoiceStream({
|
|
5666
6566
|
doGenerate,
|
|
5667
|
-
|
|
6567
|
+
tools,
|
|
6568
|
+
options: onErrorOptions
|
|
5668
6569
|
});
|
|
5669
6570
|
}
|
|
5670
6571
|
const { stream, ...rest } = await doStream();
|
|
5671
6572
|
const debugLevel = getDebugLevel();
|
|
5672
|
-
const tools = originalToolsSchema.decode(
|
|
5673
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
5674
|
-
);
|
|
5675
6573
|
const options = {
|
|
5676
|
-
...
|
|
6574
|
+
...onErrorOptions,
|
|
5677
6575
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
5678
6576
|
};
|
|
5679
6577
|
const coreStream = stream.pipeThrough(
|
|
@@ -5691,10 +6589,11 @@ async function wrapStream({
|
|
|
5691
6589
|
const v3Stream = coreStream.pipeThrough(
|
|
5692
6590
|
new TransformStream({
|
|
5693
6591
|
transform(part, controller) {
|
|
6592
|
+
const normalizedPart = part.type === "tool-call" ? coerceToolCallPart(part, tools) : part;
|
|
5694
6593
|
if (debugLevel === "stream") {
|
|
5695
|
-
logParsedChunk(
|
|
6594
|
+
logParsedChunk(normalizedPart);
|
|
5696
6595
|
}
|
|
5697
|
-
controller.enqueue(
|
|
6596
|
+
controller.enqueue(normalizedPart);
|
|
5698
6597
|
}
|
|
5699
6598
|
})
|
|
5700
6599
|
);
|
|
@@ -5705,41 +6604,36 @@ async function wrapStream({
|
|
|
5705
6604
|
}
|
|
5706
6605
|
async function toolChoiceStream({
|
|
5707
6606
|
doGenerate,
|
|
6607
|
+
tools,
|
|
5708
6608
|
options
|
|
5709
6609
|
}) {
|
|
5710
|
-
var _a
|
|
6610
|
+
var _a;
|
|
6611
|
+
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
5711
6612
|
const result = await doGenerate();
|
|
5712
|
-
let
|
|
6613
|
+
let toolName = "unknown";
|
|
6614
|
+
let input = "{}";
|
|
5713
6615
|
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
5714
|
-
|
|
5715
|
-
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5723
|
-
}
|
|
5724
|
-
);
|
|
5725
|
-
toolJson = {};
|
|
5726
|
-
}
|
|
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;
|
|
5727
6624
|
}
|
|
5728
6625
|
const stream = new ReadableStream({
|
|
5729
6626
|
start(controller) {
|
|
5730
6627
|
controller.enqueue({
|
|
5731
6628
|
type: "tool-call",
|
|
5732
6629
|
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
5733
|
-
toolName
|
|
5734
|
-
input
|
|
6630
|
+
toolName,
|
|
6631
|
+
input
|
|
5735
6632
|
});
|
|
5736
6633
|
controller.enqueue({
|
|
5737
6634
|
type: "finish",
|
|
5738
|
-
usage: (result == null ? void 0 : result.usage)
|
|
5739
|
-
|
|
5740
|
-
outputTokens: 0
|
|
5741
|
-
},
|
|
5742
|
-
finishReason: "tool-calls"
|
|
6635
|
+
usage: normalizeUsage(result == null ? void 0 : result.usage),
|
|
6636
|
+
finishReason: normalizeToolCallsFinishReason(result == null ? void 0 : result.finishReason)
|
|
5743
6637
|
});
|
|
5744
6638
|
controller.close();
|
|
5745
6639
|
}
|
|
@@ -5750,6 +6644,60 @@ async function toolChoiceStream({
|
|
|
5750
6644
|
stream
|
|
5751
6645
|
};
|
|
5752
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
|
+
}
|
|
5753
6701
|
|
|
5754
6702
|
// src/transform-handler.ts
|
|
5755
6703
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
@@ -5875,6 +6823,11 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
5875
6823
|
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
5876
6824
|
);
|
|
5877
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
|
+
}
|
|
5878
6831
|
return {
|
|
5879
6832
|
...baseReturnParams,
|
|
5880
6833
|
responseFormat: {
|