@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/community.cjs
CHANGED
|
@@ -850,6 +850,13 @@ function generateId() {
|
|
|
850
850
|
return Math.random().toString(36).substring(2, 15);
|
|
851
851
|
}
|
|
852
852
|
|
|
853
|
+
// src/core/utils/protocol-utils.ts
|
|
854
|
+
function addTextSegment(text, processedElements) {
|
|
855
|
+
if (text.trim()) {
|
|
856
|
+
processedElements.push({ type: "text", text });
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
853
860
|
// src/core/utils/regex.ts
|
|
854
861
|
function escapeRegExp(literal) {
|
|
855
862
|
return literal.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -881,11 +888,6 @@ function processToolCallJson(toolCallJson, fullMatch, processedElements, options
|
|
|
881
888
|
processedElements.push({ type: "text", text: fullMatch });
|
|
882
889
|
}
|
|
883
890
|
}
|
|
884
|
-
function addTextSegment(text, processedElements) {
|
|
885
|
-
if (text.trim()) {
|
|
886
|
-
processedElements.push({ type: "text", text });
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
891
|
function processMatchedToolCall(context) {
|
|
890
892
|
const { match, text, currentIndex, processedElements, options } = context;
|
|
891
893
|
const startIndex = match.index;
|
|
@@ -1514,6 +1516,13 @@ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
|
|
|
1514
1516
|
var NEWLINE_SPLIT_REGEX = /\n+/;
|
|
1515
1517
|
var COMMA_SPLIT_REGEX = /,\s*/;
|
|
1516
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 = /^_+/;
|
|
1517
1526
|
function unwrapJsonSchema(schema) {
|
|
1518
1527
|
if (!schema || typeof schema !== "object") {
|
|
1519
1528
|
return schema;
|
|
@@ -1762,9 +1771,158 @@ function coerceStringToArray(s, unwrapped) {
|
|
|
1762
1771
|
}
|
|
1763
1772
|
return null;
|
|
1764
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
|
+
}
|
|
1765
1922
|
function coerceObjectToObject(value, unwrapped) {
|
|
1923
|
+
const normalizedInput = applyStrictRequiredKeyRename(value, unwrapped);
|
|
1766
1924
|
const out = {};
|
|
1767
|
-
for (const [k, v] of Object.entries(
|
|
1925
|
+
for (const [k, v] of Object.entries(normalizedInput)) {
|
|
1768
1926
|
out[k] = coerceValueForKey(v, k, unwrapped);
|
|
1769
1927
|
}
|
|
1770
1928
|
return out;
|
|
@@ -1775,6 +1933,109 @@ function coerceArrayToArray(value, prefixItems, itemsSchema) {
|
|
|
1775
1933
|
}
|
|
1776
1934
|
return value.map((v) => coerceBySchema(v, itemsSchema));
|
|
1777
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
|
+
}
|
|
1778
2039
|
function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
1779
2040
|
if (Object.hasOwn(maybe, "item")) {
|
|
1780
2041
|
const items = maybe.item;
|
|
@@ -1786,15 +2047,23 @@ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
|
|
|
1786
2047
|
const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
|
|
1787
2048
|
return coerceArrayToArray(arr, prefixItems, itemsSchema);
|
|
1788
2049
|
}
|
|
2050
|
+
const parallelArrays = coerceParallelArraysObjectToArray(
|
|
2051
|
+
maybe,
|
|
2052
|
+
prefixItems,
|
|
2053
|
+
itemsSchema
|
|
2054
|
+
);
|
|
2055
|
+
if (parallelArrays !== null) {
|
|
2056
|
+
return parallelArrays;
|
|
2057
|
+
}
|
|
1789
2058
|
if (keys.length === 1) {
|
|
1790
2059
|
const singleKey = keys[0];
|
|
1791
2060
|
if (!(schemaIsUnconstrained(itemsSchema) || schemaHasProperty(itemsSchema, singleKey))) {
|
|
1792
|
-
const
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
if (
|
|
1797
|
-
return
|
|
2061
|
+
const result = coerceSingleKeyObjectToArray(
|
|
2062
|
+
maybe[singleKey],
|
|
2063
|
+
itemsSchema
|
|
2064
|
+
);
|
|
2065
|
+
if (result !== null) {
|
|
2066
|
+
return result;
|
|
1798
2067
|
}
|
|
1799
2068
|
}
|
|
1800
2069
|
}
|
|
@@ -1824,6 +2093,86 @@ function coerceStringToPrimitive(s, schemaType) {
|
|
|
1824
2093
|
}
|
|
1825
2094
|
return null;
|
|
1826
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
|
+
}
|
|
1827
2176
|
function coerceStringValue(value, schemaType, u) {
|
|
1828
2177
|
const s = value.trim();
|
|
1829
2178
|
if (schemaType === "object") {
|
|
@@ -1842,6 +2191,10 @@ function coerceStringValue(value, schemaType, u) {
|
|
|
1842
2191
|
if (primitiveResult !== null) {
|
|
1843
2192
|
return primitiveResult;
|
|
1844
2193
|
}
|
|
2194
|
+
const enumWhitespaceCanonical = coerceStringByEnumWhitespace(s, u);
|
|
2195
|
+
if (enumWhitespaceCanonical !== null) {
|
|
2196
|
+
return enumWhitespaceCanonical;
|
|
2197
|
+
}
|
|
1845
2198
|
return value;
|
|
1846
2199
|
}
|
|
1847
2200
|
function coerceArrayValue(value, prefixItems, itemsSchema) {
|
|
@@ -1880,9 +2233,23 @@ function coerceBySchema(value, schema) {
|
|
|
1880
2233
|
if (typeof value === "string") {
|
|
1881
2234
|
return coerceStringValue(value, schemaType, u);
|
|
1882
2235
|
}
|
|
2236
|
+
const primitiveString = coercePrimitiveToString(value, schemaType);
|
|
2237
|
+
if (primitiveString !== null) {
|
|
2238
|
+
return primitiveString;
|
|
2239
|
+
}
|
|
1883
2240
|
if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
|
|
1884
2241
|
return coerceObjectToObject(value, u);
|
|
1885
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
|
+
}
|
|
1886
2253
|
if (schemaType === "array") {
|
|
1887
2254
|
const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
|
|
1888
2255
|
const itemsSchema = u.items;
|
|
@@ -2897,7 +3264,7 @@ var XMLTokenizer = class {
|
|
|
2897
3264
|
};
|
|
2898
3265
|
|
|
2899
3266
|
// src/rxml/core/parser.ts
|
|
2900
|
-
var
|
|
3267
|
+
var WHITESPACE_REGEX3 = /\s/;
|
|
2901
3268
|
var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
|
|
2902
3269
|
var DIGIT_KEY_REGEX2 = /^\d+$/;
|
|
2903
3270
|
function getTopLevelStringProps(s) {
|
|
@@ -3067,7 +3434,7 @@ function parse2(xmlInner, schema, options = {}) {
|
|
|
3067
3434
|
const closeHead = s.indexOf(`</${rootName}`, range.end);
|
|
3068
3435
|
if (closeHead === range.end) {
|
|
3069
3436
|
let p = closeHead + 2 + rootName.length;
|
|
3070
|
-
while (p < s.length &&
|
|
3437
|
+
while (p < s.length && WHITESPACE_REGEX3.test(s[p])) {
|
|
3071
3438
|
p += 1;
|
|
3072
3439
|
}
|
|
3073
3440
|
if (s[p] === ">") {
|
|
@@ -3405,7 +3772,7 @@ function createIntermediateCall(toolName, rawSegment, schema) {
|
|
|
3405
3772
|
var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
|
|
3406
3773
|
var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
|
|
3407
3774
|
var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
|
|
3408
|
-
var
|
|
3775
|
+
var WHITESPACE_REGEX4 = /\s/;
|
|
3409
3776
|
var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
|
|
3410
3777
|
var NAME_START_CHAR_RE = /[A-Za-z_:]/;
|
|
3411
3778
|
var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
|
|
@@ -3546,7 +3913,7 @@ function balanceTags(xml) {
|
|
|
3546
3913
|
}
|
|
3547
3914
|
function skipWs(s, p, len) {
|
|
3548
3915
|
let idx = p;
|
|
3549
|
-
while (idx < len &&
|
|
3916
|
+
while (idx < len && WHITESPACE_REGEX4.test(s[idx])) {
|
|
3550
3917
|
idx += 1;
|
|
3551
3918
|
}
|
|
3552
3919
|
return idx;
|
|
@@ -3599,7 +3966,7 @@ function handleOpeningTagSegment(src, lt, out, stack) {
|
|
|
3599
3966
|
return len;
|
|
3600
3967
|
}
|
|
3601
3968
|
let r = q - 1;
|
|
3602
|
-
while (r >= nameStart &&
|
|
3969
|
+
while (r >= nameStart && WHITESPACE_REGEX4.test(src[r])) {
|
|
3603
3970
|
r -= 1;
|
|
3604
3971
|
}
|
|
3605
3972
|
const selfClosing = src[r] === "/";
|
|
@@ -3642,12 +4009,9 @@ function getStringPropertyNames(schema) {
|
|
|
3642
4009
|
}
|
|
3643
4010
|
return names;
|
|
3644
4011
|
}
|
|
3645
|
-
function escapeRegExp2(s) {
|
|
3646
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3647
|
-
}
|
|
3648
4012
|
function dedupeSingleTag(xml, key) {
|
|
3649
4013
|
var _a, _b;
|
|
3650
|
-
const escaped =
|
|
4014
|
+
const escaped = escapeRegExp(key);
|
|
3651
4015
|
const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
|
|
3652
4016
|
const matches = Array.from(xml.matchAll(re));
|
|
3653
4017
|
if (matches.length <= 1) {
|
|
@@ -3764,9 +4128,35 @@ function parse3(xml, schema, options = {}) {
|
|
|
3764
4128
|
throw new RXMLParseError("Failed to parse XML with repair heuristics", error);
|
|
3765
4129
|
}
|
|
3766
4130
|
|
|
3767
|
-
// src/core/
|
|
4131
|
+
// src/core/utils/regex-constants.ts
|
|
3768
4132
|
var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
|
|
3769
|
-
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
|
+
}
|
|
4158
|
+
|
|
4159
|
+
// src/core/protocols/xml-protocol.ts
|
|
3770
4160
|
function getToolSchema(tools, toolName) {
|
|
3771
4161
|
var _a;
|
|
3772
4162
|
return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
|
|
@@ -3868,7 +4258,7 @@ function consumeClosingTag(text, lt) {
|
|
|
3868
4258
|
}
|
|
3869
4259
|
function consumeOpenTag(text, lt) {
|
|
3870
4260
|
let p = lt + 1;
|
|
3871
|
-
while (p < text.length &&
|
|
4261
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3872
4262
|
p += 1;
|
|
3873
4263
|
}
|
|
3874
4264
|
const nameStart = p;
|
|
@@ -3881,7 +4271,7 @@ function consumeOpenTag(text, lt) {
|
|
|
3881
4271
|
return null;
|
|
3882
4272
|
}
|
|
3883
4273
|
let r = q - 1;
|
|
3884
|
-
while (r >= nameStart &&
|
|
4274
|
+
while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
|
|
3885
4275
|
r -= 1;
|
|
3886
4276
|
}
|
|
3887
4277
|
const selfClosing = text[r] === "/";
|
|
@@ -3910,7 +4300,7 @@ function nextTagToken(text, fromPos) {
|
|
|
3910
4300
|
if (next === "/") {
|
|
3911
4301
|
const closing = consumeClosingTag(text, lt);
|
|
3912
4302
|
let p = lt + 2;
|
|
3913
|
-
while (p < text.length &&
|
|
4303
|
+
while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
|
|
3914
4304
|
p += 1;
|
|
3915
4305
|
}
|
|
3916
4306
|
const nameStart = p;
|
|
@@ -4047,6 +4437,102 @@ function findToolCalls(text, toolNames) {
|
|
|
4047
4437
|
}
|
|
4048
4438
|
return toolCalls.sort((a, b) => a.startIndex - b.startIndex);
|
|
4049
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
|
+
}
|
|
4050
4536
|
function findEarliestToolTag(buffer, toolNames) {
|
|
4051
4537
|
var _a, _b;
|
|
4052
4538
|
let bestIndex = -1;
|
|
@@ -4085,7 +4571,7 @@ function isOpenTagPrefix(suffix, toolName) {
|
|
|
4085
4571
|
}
|
|
4086
4572
|
function consumeWhitespace(text, index) {
|
|
4087
4573
|
let i = index;
|
|
4088
|
-
while (i < text.length &&
|
|
4574
|
+
while (i < text.length && WHITESPACE_REGEX5.test(text.charAt(i))) {
|
|
4089
4575
|
i += 1;
|
|
4090
4576
|
}
|
|
4091
4577
|
return i;
|
|
@@ -4336,6 +4822,27 @@ function createProcessBufferHandler(getBuffer, setBuffer, getCurrentToolCall, se
|
|
|
4336
4822
|
}
|
|
4337
4823
|
};
|
|
4338
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
|
+
}
|
|
4339
4846
|
var xmlProtocol = (protocolOptions) => {
|
|
4340
4847
|
var _a;
|
|
4341
4848
|
const parseOptions = {
|
|
@@ -4369,28 +4876,31 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4369
4876
|
}
|
|
4370
4877
|
const processedElements = [];
|
|
4371
4878
|
let currentIndex = 0;
|
|
4372
|
-
const toolCalls =
|
|
4879
|
+
const { parseText, toolCalls } = findToolCallsWithFallbacks(
|
|
4880
|
+
text,
|
|
4881
|
+
toolNames
|
|
4882
|
+
);
|
|
4373
4883
|
for (const tc of toolCalls) {
|
|
4374
4884
|
if (tc.startIndex > currentIndex) {
|
|
4375
4885
|
processedElements.push({
|
|
4376
4886
|
type: "text",
|
|
4377
|
-
text:
|
|
4887
|
+
text: parseText.substring(currentIndex, tc.startIndex)
|
|
4378
4888
|
});
|
|
4379
4889
|
}
|
|
4380
4890
|
processToolCall({
|
|
4381
4891
|
toolCall: tc,
|
|
4382
4892
|
tools,
|
|
4383
4893
|
options,
|
|
4384
|
-
text,
|
|
4894
|
+
text: parseText,
|
|
4385
4895
|
processedElements,
|
|
4386
4896
|
parseOptions
|
|
4387
4897
|
});
|
|
4388
4898
|
currentIndex = tc.endIndex;
|
|
4389
4899
|
}
|
|
4390
|
-
if (currentIndex <
|
|
4900
|
+
if (currentIndex < parseText.length) {
|
|
4391
4901
|
processedElements.push({
|
|
4392
4902
|
type: "text",
|
|
4393
|
-
text:
|
|
4903
|
+
text: parseText.substring(currentIndex)
|
|
4394
4904
|
});
|
|
4395
4905
|
}
|
|
4396
4906
|
return processedElements;
|
|
@@ -4429,6 +4939,20 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4429
4939
|
return new TransformStream({
|
|
4430
4940
|
transform(chunk, controller) {
|
|
4431
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
|
+
}
|
|
4432
4956
|
if (chunk.type !== "text-delta") {
|
|
4433
4957
|
if (buffer) {
|
|
4434
4958
|
flushText(controller, buffer);
|
|
@@ -4474,8 +4998,6 @@ var xmlProtocol = (protocolOptions) => {
|
|
|
4474
4998
|
|
|
4475
4999
|
// src/core/protocols/yaml-protocol.ts
|
|
4476
5000
|
var import_yaml = __toESM(require("yaml"), 1);
|
|
4477
|
-
var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
|
|
4478
|
-
var WHITESPACE_REGEX5 = /\s/;
|
|
4479
5001
|
var LEADING_WHITESPACE_RE = /^(\s*)/;
|
|
4480
5002
|
function findClosingTagEnd(text, contentStart, toolName) {
|
|
4481
5003
|
let pos = contentStart;
|
|
@@ -4496,7 +5018,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4496
5018
|
p++;
|
|
4497
5019
|
}
|
|
4498
5020
|
const nameStart = p;
|
|
4499
|
-
while (p < gtIdx &&
|
|
5021
|
+
while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
4500
5022
|
p++;
|
|
4501
5023
|
}
|
|
4502
5024
|
const name = text.slice(nameStart, p);
|
|
@@ -4516,7 +5038,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
|
|
|
4516
5038
|
p++;
|
|
4517
5039
|
}
|
|
4518
5040
|
const nameStart = p;
|
|
4519
|
-
while (p < text.length &&
|
|
5041
|
+
while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
|
|
4520
5042
|
p++;
|
|
4521
5043
|
}
|
|
4522
5044
|
const name = text.slice(nameStart, p);
|
|
@@ -4643,22 +5165,14 @@ function parseYamlContent(yamlContent, options) {
|
|
|
4643
5165
|
return null;
|
|
4644
5166
|
}
|
|
4645
5167
|
}
|
|
4646
|
-
function appendTextPart(processedElements, textPart) {
|
|
4647
|
-
if (textPart.trim()) {
|
|
4648
|
-
processedElements.push({
|
|
4649
|
-
type: "text",
|
|
4650
|
-
text: textPart
|
|
4651
|
-
});
|
|
4652
|
-
}
|
|
4653
|
-
}
|
|
4654
5168
|
function processToolCallMatch(text, tc, currentIndex, processedElements, options) {
|
|
4655
5169
|
var _a;
|
|
4656
5170
|
if (tc.startIndex < currentIndex) {
|
|
4657
5171
|
return currentIndex;
|
|
4658
5172
|
}
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
5173
|
+
addTextSegment(
|
|
5174
|
+
text.substring(currentIndex, tc.startIndex),
|
|
5175
|
+
processedElements
|
|
4662
5176
|
);
|
|
4663
5177
|
const parsedArgs = parseYamlContent(tc.content, options);
|
|
4664
5178
|
if (parsedArgs !== null) {
|
|
@@ -4765,18 +5279,32 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4765
5279
|
}
|
|
4766
5280
|
const processedElements = [];
|
|
4767
5281
|
let currentIndex = 0;
|
|
4768
|
-
|
|
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
|
+
}
|
|
4769
5297
|
for (const tc of toolCalls) {
|
|
4770
5298
|
currentIndex = processToolCallMatch(
|
|
4771
|
-
|
|
5299
|
+
parseText,
|
|
4772
5300
|
tc,
|
|
4773
5301
|
currentIndex,
|
|
4774
5302
|
processedElements,
|
|
4775
5303
|
options
|
|
4776
5304
|
);
|
|
4777
5305
|
}
|
|
4778
|
-
if (currentIndex <
|
|
4779
|
-
|
|
5306
|
+
if (currentIndex < parseText.length) {
|
|
5307
|
+
addTextSegment(parseText.substring(currentIndex), processedElements);
|
|
4780
5308
|
}
|
|
4781
5309
|
return processedElements;
|
|
4782
5310
|
},
|
|
@@ -4872,6 +5400,20 @@ ${yamlContent}</${toolCall.toolName}>`;
|
|
|
4872
5400
|
return new TransformStream({
|
|
4873
5401
|
transform(chunk, controller) {
|
|
4874
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
|
+
}
|
|
4875
5417
|
if (chunk.type !== "text-delta") {
|
|
4876
5418
|
if (buffer) {
|
|
4877
5419
|
flushText(controller, buffer);
|
|
@@ -4995,17 +5537,56 @@ function encodeOriginalTools(tools) {
|
|
|
4995
5537
|
inputSchema: JSON.stringify(t.inputSchema)
|
|
4996
5538
|
}))) || [];
|
|
4997
5539
|
}
|
|
4998
|
-
function decodeOriginalTools(originalTools) {
|
|
5540
|
+
function decodeOriginalTools(originalTools, options) {
|
|
5541
|
+
var _a, _b, _c;
|
|
4999
5542
|
if (!originalTools) {
|
|
5000
5543
|
return [];
|
|
5001
5544
|
}
|
|
5002
|
-
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5008
|
-
|
|
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;
|
|
5009
5590
|
}
|
|
5010
5591
|
function isToolChoiceActive(params) {
|
|
5011
5592
|
var _a, _b, _c;
|
|
@@ -5015,23 +5596,337 @@ function isToolChoiceActive(params) {
|
|
|
5015
5596
|
|
|
5016
5597
|
// src/generate-handler.ts
|
|
5017
5598
|
var import_provider_utils = require("@ai-sdk/provider-utils");
|
|
5018
|
-
|
|
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) {
|
|
5019
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;
|
|
5020
5896
|
try {
|
|
5021
|
-
|
|
5897
|
+
parsed = JSON.parse(text);
|
|
5022
5898
|
} catch (error) {
|
|
5023
|
-
|
|
5024
|
-
|
|
5025
|
-
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
text,
|
|
5029
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5030
|
-
}
|
|
5031
|
-
);
|
|
5032
|
-
return {};
|
|
5899
|
+
onError == null ? void 0 : onError(errorMessage, {
|
|
5900
|
+
text,
|
|
5901
|
+
error: error instanceof Error ? error.message : String(error)
|
|
5902
|
+
});
|
|
5903
|
+
return { toolName: "unknown", input: "{}" };
|
|
5033
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: "{}" };
|
|
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
|
+
};
|
|
5034
5927
|
}
|
|
5928
|
+
|
|
5929
|
+
// src/generate-handler.ts
|
|
5035
5930
|
function logDebugSummary(debugSummary, toolCall, originText) {
|
|
5036
5931
|
if (debugSummary) {
|
|
5037
5932
|
debugSummary.originalText = originText;
|
|
@@ -5045,25 +5940,34 @@ function logDebugSummary(debugSummary, toolCall, originText) {
|
|
|
5045
5940
|
logParsedSummary({ toolCalls: [toolCall], originalText: originText });
|
|
5046
5941
|
}
|
|
5047
5942
|
}
|
|
5048
|
-
async function handleToolChoice(doGenerate, params) {
|
|
5049
|
-
var _a, _b, _c;
|
|
5943
|
+
async function handleToolChoice(doGenerate, params, tools) {
|
|
5944
|
+
var _a, _b, _c, _d;
|
|
5050
5945
|
const result = await doGenerate();
|
|
5051
5946
|
const first = (_a = result.content) == null ? void 0 : _a[0];
|
|
5052
|
-
|
|
5947
|
+
const onError = (_b = extractOnErrorOption(params.providerOptions)) == null ? void 0 : _b.onError;
|
|
5948
|
+
let toolName = "unknown";
|
|
5949
|
+
let input = "{}";
|
|
5053
5950
|
if (first && first.type === "text") {
|
|
5054
5951
|
if (getDebugLevel() === "parse") {
|
|
5055
5952
|
logRawChunk(first.text);
|
|
5056
5953
|
}
|
|
5057
|
-
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;
|
|
5058
5962
|
}
|
|
5059
5963
|
const toolCall = {
|
|
5060
5964
|
type: "tool-call",
|
|
5061
5965
|
toolCallId: (0, import_provider_utils.generateId)(),
|
|
5062
|
-
toolName
|
|
5063
|
-
input
|
|
5966
|
+
toolName,
|
|
5967
|
+
input
|
|
5064
5968
|
};
|
|
5065
5969
|
const originText = first && first.type === "text" ? first.text : "";
|
|
5066
|
-
const debugSummary = (
|
|
5970
|
+
const debugSummary = (_d = (_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) == null ? void 0 : _d.debugSummary;
|
|
5067
5971
|
logDebugSummary(debugSummary, toolCall, originText);
|
|
5068
5972
|
return {
|
|
5069
5973
|
...result,
|
|
@@ -5078,7 +5982,7 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5078
5982
|
if (getDebugLevel() === "stream") {
|
|
5079
5983
|
logRawChunk(contentItem.text);
|
|
5080
5984
|
}
|
|
5081
|
-
|
|
5985
|
+
const parsedByProtocol = protocol.parseGeneratedText({
|
|
5082
5986
|
text: contentItem.text,
|
|
5083
5987
|
tools,
|
|
5084
5988
|
options: {
|
|
@@ -5086,9 +5990,20 @@ function parseContent(content, protocol, tools, providerOptions) {
|
|
|
5086
5990
|
...providerOptions == null ? void 0 : providerOptions.toolCallMiddleware
|
|
5087
5991
|
}
|
|
5088
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;
|
|
5089
6004
|
});
|
|
5090
6005
|
return parsed.map(
|
|
5091
|
-
(part) =>
|
|
6006
|
+
(part) => part.type === "tool-call" ? coerceToolCallPart(part, tools) : part
|
|
5092
6007
|
);
|
|
5093
6008
|
}
|
|
5094
6009
|
function logParsedContent(content) {
|
|
@@ -5131,12 +6046,14 @@ async function wrapGenerate({
|
|
|
5131
6046
|
params
|
|
5132
6047
|
}) {
|
|
5133
6048
|
var _a, _b;
|
|
5134
|
-
|
|
5135
|
-
return handleToolChoice(doGenerate, params);
|
|
5136
|
-
}
|
|
6049
|
+
const onError = extractOnErrorOption(params.providerOptions);
|
|
5137
6050
|
const tools = originalToolsSchema.decode(
|
|
5138
|
-
(_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
|
|
5139
6053
|
);
|
|
6054
|
+
if (isToolChoiceActive(params)) {
|
|
6055
|
+
return handleToolChoice(doGenerate, params, tools);
|
|
6056
|
+
}
|
|
5140
6057
|
const result = await doGenerate();
|
|
5141
6058
|
if (result.content.length === 0) {
|
|
5142
6059
|
return result;
|
|
@@ -5160,28 +6077,6 @@ async function wrapGenerate({
|
|
|
5160
6077
|
content: newContent
|
|
5161
6078
|
};
|
|
5162
6079
|
}
|
|
5163
|
-
function fixToolCallWithSchema(part, tools) {
|
|
5164
|
-
var _a;
|
|
5165
|
-
if (part.type !== "tool-call") {
|
|
5166
|
-
return part;
|
|
5167
|
-
}
|
|
5168
|
-
let args = {};
|
|
5169
|
-
if (typeof part.input === "string") {
|
|
5170
|
-
try {
|
|
5171
|
-
args = JSON.parse(part.input);
|
|
5172
|
-
} catch (e) {
|
|
5173
|
-
return part;
|
|
5174
|
-
}
|
|
5175
|
-
} else if (part.input && typeof part.input === "object") {
|
|
5176
|
-
args = part.input;
|
|
5177
|
-
}
|
|
5178
|
-
const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
|
|
5179
|
-
const coerced = coerceBySchema(args, schema);
|
|
5180
|
-
return {
|
|
5181
|
-
...part,
|
|
5182
|
-
input: JSON.stringify(coerced != null ? coerced : {})
|
|
5183
|
-
};
|
|
5184
|
-
}
|
|
5185
6080
|
|
|
5186
6081
|
// src/core/prompts/hermes-system-prompt.ts
|
|
5187
6082
|
function hermesSystemPromptTemplate(tools) {
|
|
@@ -5585,19 +6480,22 @@ async function wrapStream({
|
|
|
5585
6480
|
params
|
|
5586
6481
|
}) {
|
|
5587
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
|
+
);
|
|
5588
6488
|
if (isToolChoiceActive(params)) {
|
|
5589
6489
|
return toolChoiceStream({
|
|
5590
6490
|
doGenerate,
|
|
5591
|
-
|
|
6491
|
+
tools,
|
|
6492
|
+
options: onErrorOptions
|
|
5592
6493
|
});
|
|
5593
6494
|
}
|
|
5594
6495
|
const { stream, ...rest } = await doStream();
|
|
5595
6496
|
const debugLevel = getDebugLevel();
|
|
5596
|
-
const tools = originalToolsSchema.decode(
|
|
5597
|
-
(_b = (_a = params.providerOptions) == null ? void 0 : _a.toolCallMiddleware) == null ? void 0 : _b.originalTools
|
|
5598
|
-
);
|
|
5599
6497
|
const options = {
|
|
5600
|
-
...
|
|
6498
|
+
...onErrorOptions,
|
|
5601
6499
|
...((_c = params.providerOptions) == null ? void 0 : _c.toolCallMiddleware) || {}
|
|
5602
6500
|
};
|
|
5603
6501
|
const coreStream = stream.pipeThrough(
|
|
@@ -5615,10 +6513,11 @@ async function wrapStream({
|
|
|
5615
6513
|
const v3Stream = coreStream.pipeThrough(
|
|
5616
6514
|
new TransformStream({
|
|
5617
6515
|
transform(part, controller) {
|
|
6516
|
+
const normalizedPart = part.type === "tool-call" ? coerceToolCallPart(part, tools) : part;
|
|
5618
6517
|
if (debugLevel === "stream") {
|
|
5619
|
-
logParsedChunk(
|
|
6518
|
+
logParsedChunk(normalizedPart);
|
|
5620
6519
|
}
|
|
5621
|
-
controller.enqueue(
|
|
6520
|
+
controller.enqueue(normalizedPart);
|
|
5622
6521
|
}
|
|
5623
6522
|
})
|
|
5624
6523
|
);
|
|
@@ -5629,41 +6528,36 @@ async function wrapStream({
|
|
|
5629
6528
|
}
|
|
5630
6529
|
async function toolChoiceStream({
|
|
5631
6530
|
doGenerate,
|
|
6531
|
+
tools,
|
|
5632
6532
|
options
|
|
5633
6533
|
}) {
|
|
5634
|
-
var _a
|
|
6534
|
+
var _a;
|
|
6535
|
+
const normalizedTools = Array.isArray(tools) ? tools : [];
|
|
5635
6536
|
const result = await doGenerate();
|
|
5636
|
-
let
|
|
6537
|
+
let toolName = "unknown";
|
|
6538
|
+
let input = "{}";
|
|
5637
6539
|
if ((result == null ? void 0 : result.content) && result.content.length > 0 && ((_a = result.content[0]) == null ? void 0 : _a.type) === "text") {
|
|
5638
|
-
|
|
5639
|
-
|
|
5640
|
-
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
|
|
5644
|
-
|
|
5645
|
-
|
|
5646
|
-
error: error instanceof Error ? error.message : String(error)
|
|
5647
|
-
}
|
|
5648
|
-
);
|
|
5649
|
-
toolJson = {};
|
|
5650
|
-
}
|
|
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;
|
|
5651
6548
|
}
|
|
5652
6549
|
const stream = new ReadableStream({
|
|
5653
6550
|
start(controller) {
|
|
5654
6551
|
controller.enqueue({
|
|
5655
6552
|
type: "tool-call",
|
|
5656
6553
|
toolCallId: (0, import_provider_utils2.generateId)(),
|
|
5657
|
-
toolName
|
|
5658
|
-
input
|
|
6554
|
+
toolName,
|
|
6555
|
+
input
|
|
5659
6556
|
});
|
|
5660
6557
|
controller.enqueue({
|
|
5661
6558
|
type: "finish",
|
|
5662
|
-
usage: (result == null ? void 0 : result.usage)
|
|
5663
|
-
|
|
5664
|
-
outputTokens: 0
|
|
5665
|
-
},
|
|
5666
|
-
finishReason: "tool-calls"
|
|
6559
|
+
usage: normalizeUsage(result == null ? void 0 : result.usage),
|
|
6560
|
+
finishReason: normalizeToolCallsFinishReason(result == null ? void 0 : result.finishReason)
|
|
5667
6561
|
});
|
|
5668
6562
|
controller.close();
|
|
5669
6563
|
}
|
|
@@ -5674,6 +6568,60 @@ async function toolChoiceStream({
|
|
|
5674
6568
|
stream
|
|
5675
6569
|
};
|
|
5676
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
|
+
}
|
|
5677
6625
|
|
|
5678
6626
|
// src/transform-handler.ts
|
|
5679
6627
|
function buildFinalPrompt(systemPrompt, processedPrompt, placement) {
|
|
@@ -5799,6 +6747,11 @@ function handleToolChoiceRequired(params, baseReturnParams, functionTools) {
|
|
|
5799
6747
|
"Tool choice type 'required' is set, but no tools are provided in params.tools."
|
|
5800
6748
|
);
|
|
5801
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
|
+
}
|
|
5802
6755
|
return {
|
|
5803
6756
|
...baseReturnParams,
|
|
5804
6757
|
responseFormat: {
|