@agentica/core 0.45.0 → 0.45.1
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 +136 -40
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/cancel.js +102 -12
- package/lib/orchestrate/cancel.js.map +1 -1
- package/lib/orchestrate/select.js +102 -12
- package/lib/orchestrate/select.js.map +1 -1
- package/lib/utils/ChatGptCompletionMessageUtil.d.ts +12 -0
- package/lib/utils/ChatGptCompletionMessageUtil.js +20 -6
- package/lib/utils/ChatGptCompletionMessageUtil.js.map +1 -1
- package/lib/utils/ChatGptCompletionStreamingUtil.js +6 -2
- package/lib/utils/ChatGptCompletionStreamingUtil.js.map +1 -1
- package/package.json +3 -3
- package/src/orchestrate/cancel.ts +152 -38
- package/src/orchestrate/select.ts +136 -20
- package/src/utils/ChatGptCompletionMessageUtil.ts +19 -5
- package/src/utils/ChatGptCompletionStreamingUtil.ts +6 -2
package/lib/index.mjs
CHANGED
|
@@ -1083,12 +1083,12 @@ function accumulate(origin, chunk) {
|
|
|
1083
1083
|
};
|
|
1084
1084
|
}
|
|
1085
1085
|
|
|
1086
|
-
function
|
|
1086
|
+
function mergeChunks(chunks) {
|
|
1087
1087
|
const firstChunk = chunks[0];
|
|
1088
1088
|
if (firstChunk === undefined) {
|
|
1089
1089
|
throw new Error("No chunks received");
|
|
1090
1090
|
}
|
|
1091
|
-
|
|
1091
|
+
return chunks.reduce(accumulate, {
|
|
1092
1092
|
id: firstChunk.id,
|
|
1093
1093
|
choices: [],
|
|
1094
1094
|
created: firstChunk.created,
|
|
@@ -1098,14 +1098,21 @@ function merge(chunks) {
|
|
|
1098
1098
|
service_tier: firstChunk.service_tier,
|
|
1099
1099
|
system_fingerprint: firstChunk.system_fingerprint
|
|
1100
1100
|
});
|
|
1101
|
-
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
function fixEmptyToolArguments(completion) {
|
|
1104
|
+
completion.choices?.forEach(choice => {
|
|
1102
1105
|
choice.message.tool_calls?.filter(tc => tc.type === "function").forEach(toolCall => {
|
|
1103
1106
|
if (toolCall.function.arguments === "") {
|
|
1104
1107
|
toolCall.function.arguments = "{}";
|
|
1105
1108
|
}
|
|
1106
1109
|
});
|
|
1107
1110
|
});
|
|
1108
|
-
return
|
|
1111
|
+
return completion;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
function merge(chunks) {
|
|
1115
|
+
return fixEmptyToolArguments(mergeChunks(chunks));
|
|
1109
1116
|
}
|
|
1110
1117
|
|
|
1111
1118
|
function mergeChoice(acc, cur) {
|
|
@@ -1183,6 +1190,8 @@ const ChatGptCompletionMessageUtil = {
|
|
|
1183
1190
|
transformCompletionChunk,
|
|
1184
1191
|
accumulate,
|
|
1185
1192
|
merge,
|
|
1193
|
+
mergeChunks,
|
|
1194
|
+
fixEmptyToolArguments,
|
|
1186
1195
|
mergeChoice,
|
|
1187
1196
|
mergeToolCalls
|
|
1188
1197
|
};
|
|
@@ -1435,7 +1444,7 @@ async function reduceStreamingWithDispatch(stream, eventProcessor, abortSignal)
|
|
|
1435
1444
|
};
|
|
1436
1445
|
if (acc.object === "chat.completion.chunk") {
|
|
1437
1446
|
registerContext([ acc, chunk ].flatMap(v => v.choices ?? []));
|
|
1438
|
-
return ChatGptCompletionMessageUtil.
|
|
1447
|
+
return ChatGptCompletionMessageUtil.mergeChunks([ acc, chunk ]);
|
|
1439
1448
|
}
|
|
1440
1449
|
registerContext(chunk.choices ?? []);
|
|
1441
1450
|
return ChatGptCompletionMessageUtil.accumulate(acc, chunk);
|
|
@@ -1459,7 +1468,7 @@ async function reduceStreamingWithDispatch(stream, eventProcessor, abortSignal)
|
|
|
1459
1468
|
});
|
|
1460
1469
|
return completion;
|
|
1461
1470
|
}
|
|
1462
|
-
return nullableCompletion;
|
|
1471
|
+
return ChatGptCompletionMessageUtil.fixEmptyToolArguments(nullableCompletion);
|
|
1463
1472
|
}
|
|
1464
1473
|
|
|
1465
1474
|
function createOperationSelection(props) {
|
|
@@ -1998,14 +2007,38 @@ async function step$1(ctx, operations, retry, failures) {
|
|
|
1998
2007
|
if (tc.type !== "function" || tc.function.name !== "cancelFunctions") {
|
|
1999
2008
|
continue;
|
|
2000
2009
|
}
|
|
2001
|
-
const
|
|
2002
|
-
|
|
2010
|
+
const parsed = FUNCTION$2.parse(tc.function.arguments);
|
|
2011
|
+
if (parsed.success === false) {
|
|
2012
|
+
failures.push({
|
|
2013
|
+
kind: "parse",
|
|
2014
|
+
id: tc.id,
|
|
2015
|
+
name: tc.function.name,
|
|
2016
|
+
failure: parsed
|
|
2017
|
+
});
|
|
2018
|
+
continue;
|
|
2019
|
+
}
|
|
2020
|
+
const validation = FUNCTION$2.validate(parsed.data);
|
|
2003
2021
|
if (validation.success === false) {
|
|
2004
2022
|
failures.push({
|
|
2023
|
+
kind: "validation",
|
|
2005
2024
|
id: tc.id,
|
|
2006
2025
|
name: tc.function.name,
|
|
2007
2026
|
validation
|
|
2008
2027
|
});
|
|
2028
|
+
continue;
|
|
2029
|
+
}
|
|
2030
|
+
const referenceErrors = validateFunctionExistence$1(ctx, validation.data);
|
|
2031
|
+
if (referenceErrors.length > 0) {
|
|
2032
|
+
failures.push({
|
|
2033
|
+
kind: "validation",
|
|
2034
|
+
id: tc.id,
|
|
2035
|
+
name: tc.function.name,
|
|
2036
|
+
validation: {
|
|
2037
|
+
success: false,
|
|
2038
|
+
data: validation.data,
|
|
2039
|
+
errors: referenceErrors
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2009
2042
|
}
|
|
2010
2043
|
}
|
|
2011
2044
|
}
|
|
@@ -2022,19 +2055,12 @@ async function step$1(ctx, operations, retry, failures) {
|
|
|
2022
2055
|
} else if (tc.function.name !== "cancelFunctions") {
|
|
2023
2056
|
continue;
|
|
2024
2057
|
}
|
|
2025
|
-
const
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
2029
|
-
return input => {
|
|
2030
|
-
input = JSON.parse(input);
|
|
2031
|
-
return __is(input) ? input : null;
|
|
2032
|
-
};
|
|
2033
|
-
})()(tc.function.arguments);
|
|
2034
|
-
if (input === null) {
|
|
2058
|
+
const parsed = FUNCTION$2.parse(tc.function.arguments);
|
|
2059
|
+
const validation = FUNCTION$2.validate(parsed.data);
|
|
2060
|
+
if (validation.success === false) {
|
|
2035
2061
|
continue;
|
|
2036
2062
|
}
|
|
2037
|
-
for (const reference of
|
|
2063
|
+
for (const reference of validation.data.functions) {
|
|
2038
2064
|
cancelFunctionFromContext(ctx, reference, assistant === undefined ? undefined : {
|
|
2039
2065
|
assistant
|
|
2040
2066
|
});
|
|
@@ -2052,19 +2078,46 @@ function emendMessages$1(failures) {
|
|
|
2052
2078
|
id: f.id,
|
|
2053
2079
|
function: {
|
|
2054
2080
|
name: f.name,
|
|
2055
|
-
arguments: JSON.stringify(f.validation.data)
|
|
2081
|
+
arguments: f.kind === "parse" ? f.failure.input : JSON.stringify(f.validation.data)
|
|
2056
2082
|
}
|
|
2057
2083
|
} ]
|
|
2058
2084
|
}, {
|
|
2059
2085
|
role: "tool",
|
|
2060
|
-
|
|
2061
|
-
|
|
2086
|
+
tool_call_id: f.id,
|
|
2087
|
+
content: f.kind === "parse" ? dedent`
|
|
2088
|
+
Invalid JSON format.
|
|
2089
|
+
|
|
2090
|
+
Here is the detailed parsing failure information,
|
|
2091
|
+
including error messages and their locations within the input:
|
|
2092
|
+
|
|
2093
|
+
\`\`\`json
|
|
2094
|
+
${JSON.stringify(f.failure.errors)}
|
|
2095
|
+
\`\`\`
|
|
2096
|
+
|
|
2097
|
+
And here is the partially parsed data that was successfully
|
|
2098
|
+
extracted before the error occurred:
|
|
2099
|
+
|
|
2100
|
+
\`\`\`json
|
|
2101
|
+
${JSON.stringify(f.failure.data)}
|
|
2102
|
+
\`\`\`
|
|
2103
|
+
` : [ "🚨 VALIDATION FAILURE: Your function arguments do not conform to the required schema.", "", "Each error below is computed absolute truth from rigorous type validation.", "You must fix ALL errors to achieve 100% schema compliance.", "", LlmJson.stringify(f.validation) ].join("\n")
|
|
2062
2104
|
}, {
|
|
2063
2105
|
role: "system",
|
|
2064
|
-
content:
|
|
2106
|
+
content: f.kind === "parse" ? AgenticaSystemPrompt.JSON_PARSE_ERROR.replace("${{FAILURE}}", JSON.stringify(f.failure)) : AgenticaSystemPrompt.VALIDATE
|
|
2065
2107
|
} ]).flat();
|
|
2066
2108
|
}
|
|
2067
2109
|
|
|
2110
|
+
function validateFunctionExistence$1(ctx, data) {
|
|
2111
|
+
const cancellable = ctx.stack.map(s => s.operation.name);
|
|
2112
|
+
const expected = cancellable.length === 0 ? "never" : cancellable.map(name => JSON.stringify(name)).join(" | ");
|
|
2113
|
+
return data.functions.flatMap((reference, i) => cancellable.includes(reference.name) ? [] : [ {
|
|
2114
|
+
path: `$input.functions[${i}].name`,
|
|
2115
|
+
expected,
|
|
2116
|
+
value: reference.name,
|
|
2117
|
+
description: cancellable.length === 0 ? `Function "${reference.name}" cannot be cancelled because no function is currently selected.` : `Function "${reference.name}" is not in the current selection, so it cannot be cancelled.`
|
|
2118
|
+
} ]);
|
|
2119
|
+
}
|
|
2120
|
+
|
|
2068
2121
|
async function describe(ctx, histories) {
|
|
2069
2122
|
if (histories.length === 0) {
|
|
2070
2123
|
return;
|
|
@@ -2435,14 +2488,38 @@ async function step(ctx, operations, retry, failures) {
|
|
|
2435
2488
|
if (tc.type !== "function" || tc.function.name !== "selectFunctions") {
|
|
2436
2489
|
continue;
|
|
2437
2490
|
}
|
|
2438
|
-
const
|
|
2439
|
-
|
|
2491
|
+
const parsed = FUNCTION.parse(tc.function.arguments);
|
|
2492
|
+
if (parsed.success === false) {
|
|
2493
|
+
failures.push({
|
|
2494
|
+
kind: "parse",
|
|
2495
|
+
id: tc.id,
|
|
2496
|
+
name: tc.function.name,
|
|
2497
|
+
failure: parsed
|
|
2498
|
+
});
|
|
2499
|
+
continue;
|
|
2500
|
+
}
|
|
2501
|
+
const validation = FUNCTION.validate(parsed.data);
|
|
2440
2502
|
if (validation.success === false) {
|
|
2441
2503
|
failures.push({
|
|
2504
|
+
kind: "validation",
|
|
2442
2505
|
id: tc.id,
|
|
2443
2506
|
name: tc.function.name,
|
|
2444
2507
|
validation
|
|
2445
2508
|
});
|
|
2509
|
+
continue;
|
|
2510
|
+
}
|
|
2511
|
+
const referenceErrors = validateFunctionExistence(ctx, operations, validation.data);
|
|
2512
|
+
if (referenceErrors.length > 0) {
|
|
2513
|
+
failures.push({
|
|
2514
|
+
kind: "validation",
|
|
2515
|
+
id: tc.id,
|
|
2516
|
+
name: tc.function.name,
|
|
2517
|
+
validation: {
|
|
2518
|
+
success: false,
|
|
2519
|
+
data: validation.data,
|
|
2520
|
+
errors: referenceErrors
|
|
2521
|
+
}
|
|
2522
|
+
});
|
|
2446
2523
|
}
|
|
2447
2524
|
}
|
|
2448
2525
|
}
|
|
@@ -2459,19 +2536,12 @@ async function step(ctx, operations, retry, failures) {
|
|
|
2459
2536
|
} else if (tc.function.name !== "selectFunctions") {
|
|
2460
2537
|
continue;
|
|
2461
2538
|
}
|
|
2462
|
-
const
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
const __is = input => "object" === typeof input && null !== input && _io0(input);
|
|
2466
|
-
return input => {
|
|
2467
|
-
input = JSON.parse(input);
|
|
2468
|
-
return __is(input) ? input : null;
|
|
2469
|
-
};
|
|
2470
|
-
})()(tc.function.arguments);
|
|
2471
|
-
if (input === null) {
|
|
2539
|
+
const parsed = FUNCTION.parse(tc.function.arguments);
|
|
2540
|
+
const validation = FUNCTION.validate(parsed.data);
|
|
2541
|
+
if (validation.success === false) {
|
|
2472
2542
|
continue;
|
|
2473
2543
|
}
|
|
2474
|
-
for (const reference of
|
|
2544
|
+
for (const reference of validation.data.functions) {
|
|
2475
2545
|
selectFunctionFromContext(ctx, reference, assistant === undefined ? undefined : {
|
|
2476
2546
|
assistant
|
|
2477
2547
|
});
|
|
@@ -2489,19 +2559,45 @@ function emendMessages(failures) {
|
|
|
2489
2559
|
id: f.id,
|
|
2490
2560
|
function: {
|
|
2491
2561
|
name: f.name,
|
|
2492
|
-
arguments: JSON.stringify(f.validation.data)
|
|
2562
|
+
arguments: f.kind === "parse" ? f.failure.input : JSON.stringify(f.validation.data)
|
|
2493
2563
|
}
|
|
2494
2564
|
} ]
|
|
2495
2565
|
}, {
|
|
2496
2566
|
role: "tool",
|
|
2497
|
-
|
|
2498
|
-
|
|
2567
|
+
tool_call_id: f.id,
|
|
2568
|
+
content: f.kind === "parse" ? dedent`
|
|
2569
|
+
Invalid JSON format.
|
|
2570
|
+
|
|
2571
|
+
Here is the detailed parsing failure information,
|
|
2572
|
+
including error messages and their locations within the input:
|
|
2573
|
+
|
|
2574
|
+
\`\`\`json
|
|
2575
|
+
${JSON.stringify(f.failure.errors)}
|
|
2576
|
+
\`\`\`
|
|
2577
|
+
|
|
2578
|
+
And here is the partially parsed data that was successfully
|
|
2579
|
+
extracted before the error occurred:
|
|
2580
|
+
|
|
2581
|
+
\`\`\`json
|
|
2582
|
+
${JSON.stringify(f.failure.data)}
|
|
2583
|
+
\`\`\`
|
|
2584
|
+
` : [ "🚨 VALIDATION FAILURE: Your function arguments do not conform to the required schema.", "", "Each error below is computed absolute truth from rigorous type validation.", "You must fix ALL errors to achieve 100% schema compliance.", "", LlmJson.stringify(f.validation) ].join("\n")
|
|
2499
2585
|
}, {
|
|
2500
2586
|
role: "system",
|
|
2501
|
-
content:
|
|
2587
|
+
content: f.kind === "parse" ? AgenticaSystemPrompt.JSON_PARSE_ERROR.replace("${{FAILURE}}", JSON.stringify(f.failure)) : AgenticaSystemPrompt.VALIDATE
|
|
2502
2588
|
} ]).flat();
|
|
2503
2589
|
}
|
|
2504
2590
|
|
|
2591
|
+
function validateFunctionExistence(ctx, candidates, data) {
|
|
2592
|
+
const expected = candidates.map(op => JSON.stringify(op.name)).join(" | ");
|
|
2593
|
+
return data.functions.flatMap((reference, i) => ctx.operations.flat.has(reference.name) ? [] : [ {
|
|
2594
|
+
path: `$input.functions[${i}].name`,
|
|
2595
|
+
expected,
|
|
2596
|
+
value: reference.name,
|
|
2597
|
+
description: [ `Function "${reference.name}" does not exist.`, "Select only from the functions provided by getApiFunctions()." ].join(" ")
|
|
2598
|
+
} ]);
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2505
2601
|
function execute(executor) {
|
|
2506
2602
|
return async ctx => {
|
|
2507
2603
|
if (ctx.ready() === false) {
|