@agentica/core 0.36.2 → 0.36.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/lib/index.mjs +156 -157
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/call.js +2 -3
- package/lib/orchestrate/call.js.map +1 -1
- package/lib/utils/JsonUtil.d.ts +3 -0
- package/lib/utils/JsonUtil.js +201 -4
- package/lib/utils/JsonUtil.js.map +1 -1
- package/lib/utils/stringifyValidateFailure.spec.js +41 -41
- package/lib/utils/stringifyValidateFailure.spec.js.map +1 -1
- package/package.json +2 -2
- package/src/orchestrate/call.ts +2 -3
- package/src/utils/JsonUtil.ts +255 -4
- package/src/utils/stringifyValidateFailure.spec.ts +41 -41
- package/lib/utils/JsonUtil.spec.d.ts +0 -1
- package/lib/utils/JsonUtil.spec.js +0 -151
- package/lib/utils/JsonUtil.spec.js.map +0 -1
- package/lib/utils/stringifyValidateFailure.d.ts +0 -2
- package/lib/utils/stringifyValidateFailure.js +0 -201
- package/lib/utils/stringifyValidateFailure.js.map +0 -1
- package/src/utils/JsonUtil.spec.ts +0 -190
- package/src/utils/stringifyValidateFailure.ts +0 -251
package/lib/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { v4 } from "uuid";
|
|
|
6
6
|
|
|
7
7
|
import { HttpLlm, OpenApi, McpLlm } from "@samchon/openapi";
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import { jsonrepair } from "jsonrepair";
|
|
10
10
|
|
|
11
11
|
import { Escaper } from "typia/lib/utils/Escaper";
|
|
12
12
|
|
|
@@ -911,14 +911,162 @@ const ChatGptTokenUsageAggregator = {
|
|
|
911
911
|
};
|
|
912
912
|
|
|
913
913
|
const JsonUtil = {
|
|
914
|
-
parse
|
|
914
|
+
parse,
|
|
915
|
+
stringifyValidateFailure
|
|
915
916
|
};
|
|
916
917
|
|
|
917
|
-
const pipe = (...fns) => str => fns.reduce(((acc, fn) => fn(acc)), str);
|
|
918
|
-
|
|
919
918
|
function parse(str) {
|
|
920
|
-
|
|
921
|
-
return JSON.parse(
|
|
919
|
+
str = jsonrepair(str);
|
|
920
|
+
return JSON.parse(str);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function stringifyValidateFailure(failure) {
|
|
924
|
+
return stringify({
|
|
925
|
+
value: failure.data,
|
|
926
|
+
errors: failure.errors,
|
|
927
|
+
path: "$input",
|
|
928
|
+
tab: 0,
|
|
929
|
+
inArray: false,
|
|
930
|
+
inToJson: false
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
function stringify(props) {
|
|
935
|
+
const {value, errors, path, tab, inArray, inToJson} = props;
|
|
936
|
+
const indent = " ".repeat(tab);
|
|
937
|
+
const errorComment = getErrorComment(path, errors);
|
|
938
|
+
if (inArray && value === undefined) {
|
|
939
|
+
return `${indent}undefined${errorComment}`;
|
|
940
|
+
}
|
|
941
|
+
if (Array.isArray(value)) {
|
|
942
|
+
if (value.length === 0) {
|
|
943
|
+
return `${indent}[]${errorComment}`;
|
|
944
|
+
}
|
|
945
|
+
const lines = [];
|
|
946
|
+
lines.push(`${indent}[${errorComment}`);
|
|
947
|
+
value.forEach(((item, index) => {
|
|
948
|
+
const itemPath = `${path}[${index}]`;
|
|
949
|
+
let itemStr = stringify({
|
|
950
|
+
value: item,
|
|
951
|
+
errors,
|
|
952
|
+
path: itemPath,
|
|
953
|
+
tab: tab + 1,
|
|
954
|
+
inArray: true,
|
|
955
|
+
inToJson: false
|
|
956
|
+
});
|
|
957
|
+
if (index < value.length - 1) {
|
|
958
|
+
const itemLines = itemStr.split("\n");
|
|
959
|
+
const lastLine = itemLines[itemLines.length - 1];
|
|
960
|
+
const commentIndex = lastLine.indexOf(" //");
|
|
961
|
+
if (commentIndex !== -1) {
|
|
962
|
+
itemLines[itemLines.length - 1] = `${lastLine.slice(0, commentIndex)},${lastLine.slice(commentIndex)}`;
|
|
963
|
+
} else {
|
|
964
|
+
itemLines[itemLines.length - 1] += ",";
|
|
965
|
+
}
|
|
966
|
+
itemStr = itemLines.join("\n");
|
|
967
|
+
}
|
|
968
|
+
lines.push(itemStr);
|
|
969
|
+
}));
|
|
970
|
+
lines.push(`${indent}]`);
|
|
971
|
+
return lines.join("\n");
|
|
972
|
+
}
|
|
973
|
+
if (typeof value === "object" && value !== null) {
|
|
974
|
+
if (!inToJson && typeof value.toJSON === "function") {
|
|
975
|
+
const jsonValue = value.toJSON();
|
|
976
|
+
return stringify({
|
|
977
|
+
value: jsonValue,
|
|
978
|
+
errors,
|
|
979
|
+
path,
|
|
980
|
+
tab,
|
|
981
|
+
inArray,
|
|
982
|
+
inToJson: true
|
|
983
|
+
});
|
|
984
|
+
}
|
|
985
|
+
const existingEntries = Object.entries(value).filter((([_, val]) => val !== undefined));
|
|
986
|
+
const missingKeys = getMissingProperties(path, value, errors);
|
|
987
|
+
const allKeys = [ ...existingEntries.map((([key]) => key)), ...missingKeys ];
|
|
988
|
+
if (allKeys.length === 0) {
|
|
989
|
+
return `${indent}{}${errorComment}`;
|
|
990
|
+
}
|
|
991
|
+
const lines = [];
|
|
992
|
+
lines.push(`${indent}{${errorComment}`);
|
|
993
|
+
allKeys.forEach(((key, index, array) => {
|
|
994
|
+
const propPath = Escaper.variable(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
995
|
+
const propIndent = " ".repeat(tab + 1);
|
|
996
|
+
const val = missingKeys.includes(key) ? undefined : value[key];
|
|
997
|
+
if (val === undefined || val === null || typeof val === "boolean" || typeof val === "number" || typeof val === "string") {
|
|
998
|
+
const propErrorComment = getErrorComment(propPath, errors);
|
|
999
|
+
const valueStr = val === undefined ? `${propIndent}"${key}": undefined` : `${propIndent}"${key}": ${JSON.stringify(val)}`;
|
|
1000
|
+
const withComma = index < array.length - 1 ? `${valueStr},` : valueStr;
|
|
1001
|
+
const line = withComma + propErrorComment;
|
|
1002
|
+
lines.push(line);
|
|
1003
|
+
} else {
|
|
1004
|
+
const keyLine = `${propIndent}"${key}": `;
|
|
1005
|
+
let valStr = stringify({
|
|
1006
|
+
value: val,
|
|
1007
|
+
errors,
|
|
1008
|
+
path: propPath,
|
|
1009
|
+
tab: tab + 1,
|
|
1010
|
+
inArray: false,
|
|
1011
|
+
inToJson: false
|
|
1012
|
+
});
|
|
1013
|
+
const valStrWithoutIndent = valStr.trimStart();
|
|
1014
|
+
if (index < array.length - 1) {
|
|
1015
|
+
const valLines = valStrWithoutIndent.split("\n");
|
|
1016
|
+
const lastLine = valLines[valLines.length - 1];
|
|
1017
|
+
const commentIndex = lastLine.indexOf(" //");
|
|
1018
|
+
if (commentIndex !== -1) {
|
|
1019
|
+
valLines[valLines.length - 1] = `${lastLine.slice(0, commentIndex)},${lastLine.slice(commentIndex)}`;
|
|
1020
|
+
} else {
|
|
1021
|
+
valLines[valLines.length - 1] += ",";
|
|
1022
|
+
}
|
|
1023
|
+
valStr = valLines.join("\n");
|
|
1024
|
+
} else {
|
|
1025
|
+
valStr = valStrWithoutIndent;
|
|
1026
|
+
}
|
|
1027
|
+
const combined = keyLine + valStr;
|
|
1028
|
+
lines.push(combined);
|
|
1029
|
+
}
|
|
1030
|
+
}));
|
|
1031
|
+
lines.push(`${indent}}`);
|
|
1032
|
+
return lines.join("\n");
|
|
1033
|
+
}
|
|
1034
|
+
const valStr = value === undefined ? "undefined" : JSON.stringify(value) ?? String(value);
|
|
1035
|
+
return `${indent}${valStr}${errorComment}`;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
function getErrorComment(path, errors) {
|
|
1039
|
+
const pathErrors = errors.filter((e => e.path === path));
|
|
1040
|
+
if (pathErrors.length === 0) {
|
|
1041
|
+
return "";
|
|
1042
|
+
}
|
|
1043
|
+
return ` // ❌ ${JSON.stringify(pathErrors.map((e => ({
|
|
1044
|
+
path: e.path,
|
|
1045
|
+
expected: e.expected,
|
|
1046
|
+
description: e.description
|
|
1047
|
+
}))))}`;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
function getMissingProperties(path, value, errors) {
|
|
1051
|
+
const missingKeys = new Set;
|
|
1052
|
+
for (const e of errors) {
|
|
1053
|
+
const childKey = extractDirectChildKey(path, e.path);
|
|
1054
|
+
if (childKey !== null) {
|
|
1055
|
+
if (!(childKey in value)) {
|
|
1056
|
+
missingKeys.add(childKey);
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return Array.from(missingKeys);
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
function extractDirectChildKey(parentPath, errorPath) {
|
|
1064
|
+
if (!errorPath.startsWith(parentPath)) {
|
|
1065
|
+
return null;
|
|
1066
|
+
}
|
|
1067
|
+
const suffix = errorPath.slice(parentPath.length);
|
|
1068
|
+
const match = suffix.match(/^\.([^.[\]]+)$/);
|
|
1069
|
+
return match !== null ? match[1] : null;
|
|
922
1070
|
}
|
|
923
1071
|
|
|
924
1072
|
function transformCompletionChunk(source) {
|
|
@@ -1344,155 +1492,6 @@ async function reduceStreamingWithDispatch(stream, eventProcessor, abortSignal)
|
|
|
1344
1492
|
return nullableCompletion;
|
|
1345
1493
|
}
|
|
1346
1494
|
|
|
1347
|
-
function stringifyValidateFailure(failure) {
|
|
1348
|
-
return stringify({
|
|
1349
|
-
value: failure.data,
|
|
1350
|
-
errors: failure.errors,
|
|
1351
|
-
path: "$input",
|
|
1352
|
-
tab: 0,
|
|
1353
|
-
inArray: false,
|
|
1354
|
-
inToJson: false
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
|
|
1358
|
-
function stringify(props) {
|
|
1359
|
-
const {value, errors, path, tab, inArray, inToJson} = props;
|
|
1360
|
-
const indent = " ".repeat(tab);
|
|
1361
|
-
const errorComment = getErrorComment(path, errors);
|
|
1362
|
-
if (inArray && value === undefined) {
|
|
1363
|
-
return `${indent}undefined${errorComment}`;
|
|
1364
|
-
}
|
|
1365
|
-
if (Array.isArray(value)) {
|
|
1366
|
-
if (value.length === 0) {
|
|
1367
|
-
return `${indent}[]${errorComment}`;
|
|
1368
|
-
}
|
|
1369
|
-
const lines = [];
|
|
1370
|
-
lines.push(`${indent}[${errorComment}`);
|
|
1371
|
-
value.forEach(((item, index) => {
|
|
1372
|
-
const itemPath = `${path}[${index}]`;
|
|
1373
|
-
let itemStr = stringify({
|
|
1374
|
-
value: item,
|
|
1375
|
-
errors,
|
|
1376
|
-
path: itemPath,
|
|
1377
|
-
tab: tab + 1,
|
|
1378
|
-
inArray: true,
|
|
1379
|
-
inToJson: false
|
|
1380
|
-
});
|
|
1381
|
-
if (index < value.length - 1) {
|
|
1382
|
-
const itemLines = itemStr.split("\n");
|
|
1383
|
-
const lastLine = itemLines[itemLines.length - 1];
|
|
1384
|
-
const commentIndex = lastLine.indexOf(" //");
|
|
1385
|
-
if (commentIndex !== -1) {
|
|
1386
|
-
itemLines[itemLines.length - 1] = `${lastLine.slice(0, commentIndex)},${lastLine.slice(commentIndex)}`;
|
|
1387
|
-
} else {
|
|
1388
|
-
itemLines[itemLines.length - 1] += ",";
|
|
1389
|
-
}
|
|
1390
|
-
itemStr = itemLines.join("\n");
|
|
1391
|
-
}
|
|
1392
|
-
lines.push(itemStr);
|
|
1393
|
-
}));
|
|
1394
|
-
lines.push(`${indent}]`);
|
|
1395
|
-
return lines.join("\n");
|
|
1396
|
-
}
|
|
1397
|
-
if (typeof value === "object" && value !== null) {
|
|
1398
|
-
if (!inToJson && typeof value.toJSON === "function") {
|
|
1399
|
-
const jsonValue = value.toJSON();
|
|
1400
|
-
return stringify({
|
|
1401
|
-
value: jsonValue,
|
|
1402
|
-
errors,
|
|
1403
|
-
path,
|
|
1404
|
-
tab,
|
|
1405
|
-
inArray,
|
|
1406
|
-
inToJson: true
|
|
1407
|
-
});
|
|
1408
|
-
}
|
|
1409
|
-
const existingEntries = Object.entries(value).filter((([_, val]) => val !== undefined));
|
|
1410
|
-
const missingKeys = getMissingProperties(path, value, errors);
|
|
1411
|
-
const allKeys = [ ...existingEntries.map((([key]) => key)), ...missingKeys ];
|
|
1412
|
-
if (allKeys.length === 0) {
|
|
1413
|
-
return `${indent}{}${errorComment}`;
|
|
1414
|
-
}
|
|
1415
|
-
const lines = [];
|
|
1416
|
-
lines.push(`${indent}{${errorComment}`);
|
|
1417
|
-
allKeys.forEach(((key, index, array) => {
|
|
1418
|
-
const propPath = Escaper.variable(key) ? `${path}.${key}` : `${path}[${JSON.stringify(key)}]`;
|
|
1419
|
-
const propIndent = " ".repeat(tab + 1);
|
|
1420
|
-
const val = missingKeys.includes(key) ? undefined : value[key];
|
|
1421
|
-
if (val === undefined || val === null || typeof val === "boolean" || typeof val === "number" || typeof val === "string") {
|
|
1422
|
-
const propErrorComment = getErrorComment(propPath, errors);
|
|
1423
|
-
const valueStr = val === undefined ? `${propIndent}"${key}": undefined` : `${propIndent}"${key}": ${JSON.stringify(val)}`;
|
|
1424
|
-
const withComma = index < array.length - 1 ? `${valueStr},` : valueStr;
|
|
1425
|
-
const line = withComma + propErrorComment;
|
|
1426
|
-
lines.push(line);
|
|
1427
|
-
} else {
|
|
1428
|
-
const keyLine = `${propIndent}"${key}": `;
|
|
1429
|
-
let valStr = stringify({
|
|
1430
|
-
value: val,
|
|
1431
|
-
errors,
|
|
1432
|
-
path: propPath,
|
|
1433
|
-
tab: tab + 1,
|
|
1434
|
-
inArray: false,
|
|
1435
|
-
inToJson: false
|
|
1436
|
-
});
|
|
1437
|
-
const valStrWithoutIndent = valStr.trimStart();
|
|
1438
|
-
if (index < array.length - 1) {
|
|
1439
|
-
const valLines = valStrWithoutIndent.split("\n");
|
|
1440
|
-
const lastLine = valLines[valLines.length - 1];
|
|
1441
|
-
const commentIndex = lastLine.indexOf(" //");
|
|
1442
|
-
if (commentIndex !== -1) {
|
|
1443
|
-
valLines[valLines.length - 1] = `${lastLine.slice(0, commentIndex)},${lastLine.slice(commentIndex)}`;
|
|
1444
|
-
} else {
|
|
1445
|
-
valLines[valLines.length - 1] += ",";
|
|
1446
|
-
}
|
|
1447
|
-
valStr = valLines.join("\n");
|
|
1448
|
-
} else {
|
|
1449
|
-
valStr = valStrWithoutIndent;
|
|
1450
|
-
}
|
|
1451
|
-
const combined = keyLine + valStr;
|
|
1452
|
-
lines.push(combined);
|
|
1453
|
-
}
|
|
1454
|
-
}));
|
|
1455
|
-
lines.push(`${indent}}`);
|
|
1456
|
-
return lines.join("\n");
|
|
1457
|
-
}
|
|
1458
|
-
const valStr = value === undefined ? "undefined" : JSON.stringify(value) ?? String(value);
|
|
1459
|
-
return `${indent}${valStr}${errorComment}`;
|
|
1460
|
-
}
|
|
1461
|
-
|
|
1462
|
-
function getErrorComment(path, errors) {
|
|
1463
|
-
const pathErrors = errors.filter((e => e.path === path));
|
|
1464
|
-
if (pathErrors.length === 0) {
|
|
1465
|
-
return "";
|
|
1466
|
-
}
|
|
1467
|
-
return ` // ❌ ${JSON.stringify(pathErrors.map((e => ({
|
|
1468
|
-
path: e.path,
|
|
1469
|
-
expected: e.expected,
|
|
1470
|
-
description: e.description
|
|
1471
|
-
}))))}`;
|
|
1472
|
-
}
|
|
1473
|
-
|
|
1474
|
-
function getMissingProperties(path, value, errors) {
|
|
1475
|
-
const missingKeys = new Set;
|
|
1476
|
-
for (const e of errors) {
|
|
1477
|
-
const childKey = extractDirectChildKey(path, e.path);
|
|
1478
|
-
if (childKey !== null) {
|
|
1479
|
-
if (!(childKey in value)) {
|
|
1480
|
-
missingKeys.add(childKey);
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
}
|
|
1484
|
-
return Array.from(missingKeys);
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
function extractDirectChildKey(parentPath, errorPath) {
|
|
1488
|
-
if (!errorPath.startsWith(parentPath)) {
|
|
1489
|
-
return null;
|
|
1490
|
-
}
|
|
1491
|
-
const suffix = errorPath.slice(parentPath.length);
|
|
1492
|
-
const match = suffix.match(/^\.([^.[\]]+)$/);
|
|
1493
|
-
return match !== null ? match[1] : null;
|
|
1494
|
-
}
|
|
1495
|
-
|
|
1496
1495
|
function createOperationSelection(props) {
|
|
1497
1496
|
return {
|
|
1498
1497
|
operation: props.operation,
|
|
@@ -1644,9 +1643,9 @@ async function correctTypeError(ctx, callEvent, validateEvent, previousValidatio
|
|
|
1644
1643
|
toolCall: {
|
|
1645
1644
|
id: callEvent.id,
|
|
1646
1645
|
arguments: JSON.stringify(callEvent.arguments),
|
|
1647
|
-
result: [ "🚨 VALIDATION FAILURE: Your function arguments do not conform to the required schema.", "", "The validation errors below represent computed absolute truth from rigorous type validation.", "Each error is marked with ❌ comments showing the exact location, expected type, and actual value.", "", "You must fix ALL errors to achieve 100% schema compliance.", "", "```json", stringifyValidateFailure(validateEvent.result), "```" ].join("\n")
|
|
1646
|
+
result: [ "🚨 VALIDATION FAILURE: Your function arguments do not conform to the required schema.", "", "The validation errors below represent computed absolute truth from rigorous type validation.", "Each error is marked with ❌ comments showing the exact location, expected type, and actual value.", "", "You must fix ALL errors to achieve 100% schema compliance.", "", "```json", JsonUtil.stringifyValidateFailure(validateEvent.result), "```" ].join("\n")
|
|
1648
1647
|
},
|
|
1649
|
-
systemPrompt: ctx.config?.systemPrompt?.validate?.(previousValidationErrors.slice(0, -1)) ?? [ AgenticaSystemPrompt.VALIDATE, ...previousValidationErrors.length > 1 ? [ "", AgenticaSystemPrompt.VALIDATE_REPEATED.replace("${{HISTORICAL_ERRORS}}", previousValidationErrors.slice(0, -1).map(((ve, i) => [ `### ${i + 1}. Previous Validation Error`, "", "```json", stringifyValidateFailure(ve.result), "```" ].join("\n"))).join("\n\n")) ] : [] ].join("\n"),
|
|
1648
|
+
systemPrompt: ctx.config?.systemPrompt?.validate?.(previousValidationErrors.slice(0, -1)) ?? [ AgenticaSystemPrompt.VALIDATE, ...previousValidationErrors.length > 1 ? [ "", AgenticaSystemPrompt.VALIDATE_REPEATED.replace("${{HISTORICAL_ERRORS}}", previousValidationErrors.slice(0, -1).map(((ve, i) => [ `### ${i + 1}. Previous Validation Error`, "", "```json", JsonUtil.stringifyValidateFailure(ve.result), "```" ].join("\n"))).join("\n\n")) ] : [] ].join("\n"),
|
|
1650
1649
|
life,
|
|
1651
1650
|
previousValidationErrors
|
|
1652
1651
|
});
|