@librechat/agents 3.1.88 → 3.1.89
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/cjs/graphs/Graph.cjs +18 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/stream.cjs +115 -8
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +24 -7
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/toolOutputReferences.cjs +8 -0
- package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
- package/dist/cjs/utils/events.cjs +3 -1
- package/dist/cjs/utils/events.cjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +18 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/stream.mjs +115 -8
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +24 -7
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/toolOutputReferences.mjs +8 -1
- package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
- package/dist/esm/utils/events.mjs +3 -1
- package/dist/esm/utils/events.mjs.map +1 -1
- package/dist/types/graphs/Graph.d.ts +8 -0
- package/dist/types/types/tools.d.ts +9 -0
- package/dist/types/utils/events.d.ts +1 -1
- package/package.json +1 -1
- package/src/__tests__/stream.eagerEventExecution.test.ts +1073 -221
- package/src/graphs/Graph.ts +20 -5
- package/src/specs/subagent.test.ts +87 -1
- package/src/stream.ts +163 -12
- package/src/tools/ToolNode.ts +134 -111
- package/src/tools/__tests__/ToolNode.eagerEventExecution.test.ts +278 -14
- package/src/types/tools.ts +9 -0
- package/src/utils/events.ts +4 -2
package/src/tools/ToolNode.ts
CHANGED
|
@@ -1062,13 +1062,13 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1062
1062
|
handlerError:
|
|
1063
1063
|
handlerError instanceof Error
|
|
1064
1064
|
? {
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1065
|
+
message: handlerError.message,
|
|
1066
|
+
stack: handlerError.stack ?? undefined,
|
|
1067
|
+
}
|
|
1068
1068
|
: {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1069
|
+
message: String(handlerError),
|
|
1070
|
+
stack: undefined,
|
|
1071
|
+
},
|
|
1072
1072
|
});
|
|
1073
1073
|
}
|
|
1074
1074
|
}
|
|
@@ -1076,11 +1076,11 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1076
1076
|
const refMeta =
|
|
1077
1077
|
unresolvedRefs.length > 0
|
|
1078
1078
|
? this.recordOutputReference(
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1079
|
+
runId,
|
|
1080
|
+
errorContent,
|
|
1081
|
+
undefined,
|
|
1082
|
+
unresolvedRefs
|
|
1083
|
+
)
|
|
1084
1084
|
: undefined;
|
|
1085
1085
|
return new ToolMessage({
|
|
1086
1086
|
status: 'error',
|
|
@@ -2432,59 +2432,77 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
2432
2432
|
dispatchRequests.length === 0
|
|
2433
2433
|
? Promise.resolve([] as t.ToolExecuteResult[])
|
|
2434
2434
|
: new Promise<t.ToolExecuteResult[]>((resolve, reject) => {
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2435
|
+
let dispatchSettled = false;
|
|
2436
|
+
let resultSettled = false;
|
|
2437
|
+
let settledResults: t.ToolExecuteResult[] | undefined;
|
|
2438
2438
|
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2439
|
+
const maybeResolve = (): void => {
|
|
2440
|
+
if (dispatchSettled && resultSettled) {
|
|
2441
|
+
resolve(settledResults ?? []);
|
|
2442
|
+
}
|
|
2443
|
+
};
|
|
2444
2444
|
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2445
|
+
const batchRequest: t.ToolExecuteBatchRequest = {
|
|
2446
|
+
toolCalls: dispatchRequests,
|
|
2447
|
+
userId: config.configurable?.user_id as string | undefined,
|
|
2448
|
+
agentId: this.agentId,
|
|
2449
|
+
configurable: config.configurable as
|
|
2450
2450
|
| Record<string, unknown>
|
|
2451
2451
|
| undefined,
|
|
2452
|
-
|
|
2452
|
+
metadata: config.metadata as
|
|
2453
2453
|
| Record<string, unknown>
|
|
2454
2454
|
| undefined,
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2455
|
+
resolve: (results): void => {
|
|
2456
|
+
resultSettled = true;
|
|
2457
|
+
settledResults = results;
|
|
2458
|
+
maybeResolve();
|
|
2459
|
+
},
|
|
2460
|
+
reject,
|
|
2461
|
+
};
|
|
2462
2462
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2463
|
+
void safeDispatchCustomEvent(
|
|
2464
|
+
GraphEvents.ON_TOOL_EXECUTE,
|
|
2465
|
+
batchRequest,
|
|
2466
|
+
config
|
|
2467
|
+
)
|
|
2468
|
+
.then(() => {
|
|
2469
|
+
dispatchSettled = true;
|
|
2470
|
+
maybeResolve();
|
|
2471
|
+
})
|
|
2472
|
+
.catch(reject);
|
|
2473
|
+
});
|
|
2474
2474
|
|
|
2475
2475
|
const eagerResultsPromise = Promise.all(
|
|
2476
|
-
eagerExecutions.map(({ request, execution }) =>
|
|
2477
|
-
this.resolveEagerEventExecution(
|
|
2478
|
-
|
|
2479
|
-
|
|
2476
|
+
eagerExecutions.map(async ({ request, execution }) => {
|
|
2477
|
+
const results = await this.resolveEagerEventExecution(
|
|
2478
|
+
request,
|
|
2479
|
+
execution
|
|
2480
|
+
);
|
|
2481
|
+
return {
|
|
2482
|
+
results,
|
|
2483
|
+
completionDispatched:
|
|
2484
|
+
execution.completionDispatched === true &&
|
|
2485
|
+
execution.request.turn === request.turn,
|
|
2486
|
+
toolCallId: request.id,
|
|
2487
|
+
};
|
|
2488
|
+
})
|
|
2489
|
+
);
|
|
2480
2490
|
|
|
2481
2491
|
const [eagerResults, dispatchedResults] = await Promise.all([
|
|
2482
2492
|
eagerResultsPromise,
|
|
2483
2493
|
dispatchPromise,
|
|
2484
2494
|
]);
|
|
2495
|
+
const eagerCompletionDispatchedIds = new Set(
|
|
2496
|
+
eagerResults
|
|
2497
|
+
.filter((result) => result.completionDispatched)
|
|
2498
|
+
.map((result) => result.toolCallId)
|
|
2499
|
+
);
|
|
2500
|
+
const flattenedEagerResults = eagerResults.flatMap(
|
|
2501
|
+
(result) => result.results
|
|
2502
|
+
);
|
|
2485
2503
|
const results = [
|
|
2486
2504
|
...plan.rejectedResults,
|
|
2487
|
-
...
|
|
2505
|
+
...flattenedEagerResults,
|
|
2488
2506
|
...dispatchedResults,
|
|
2489
2507
|
];
|
|
2490
2508
|
|
|
@@ -2537,11 +2555,11 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
2537
2555
|
const errorRefMeta =
|
|
2538
2556
|
unresolved.length > 0
|
|
2539
2557
|
? this.recordOutputReference(
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2558
|
+
registryRunId,
|
|
2559
|
+
contentString,
|
|
2560
|
+
undefined,
|
|
2561
|
+
unresolved
|
|
2562
|
+
)
|
|
2545
2563
|
: undefined;
|
|
2546
2564
|
toolMessage = new ToolMessage({
|
|
2547
2565
|
status: 'error',
|
|
@@ -2660,14 +2678,16 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
2660
2678
|
});
|
|
2661
2679
|
}
|
|
2662
2680
|
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2681
|
+
if (!eagerCompletionDispatchedIds.has(result.toolCallId)) {
|
|
2682
|
+
await this.dispatchStepCompleted(
|
|
2683
|
+
result.toolCallId,
|
|
2684
|
+
toolName,
|
|
2685
|
+
request?.args ?? {},
|
|
2686
|
+
contentString,
|
|
2687
|
+
config,
|
|
2688
|
+
request?.turn
|
|
2689
|
+
);
|
|
2690
|
+
}
|
|
2671
2691
|
|
|
2672
2692
|
postToolBatchEntryByCallId.set(result.toolCallId, {
|
|
2673
2693
|
toolName,
|
|
@@ -2706,8 +2726,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
2706
2726
|
this.eventDrivenMode &&
|
|
2707
2727
|
this.eagerEventToolExecution?.enabled === true &&
|
|
2708
2728
|
this.hookRegistry == null &&
|
|
2709
|
-
this.humanInTheLoop?.enabled !== true
|
|
2710
|
-
this.toolOutputRegistry == null
|
|
2729
|
+
this.humanInTheLoop?.enabled !== true
|
|
2711
2730
|
);
|
|
2712
2731
|
}
|
|
2713
2732
|
|
|
@@ -2725,10 +2744,14 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
2725
2744
|
|
|
2726
2745
|
this.eagerEventToolExecutions?.delete(request.id);
|
|
2727
2746
|
|
|
2747
|
+
// Only tool identity + canonical args define side-effect identity here.
|
|
2748
|
+
// `request.turn` is final-planning metadata; if it drifts between the
|
|
2749
|
+
// streamed eager reservation and model-end materialization, consume the
|
|
2750
|
+
// same-name/same-args eager result and let the final request drive refs,
|
|
2751
|
+
// completion metadata, and PostToolBatch state.
|
|
2728
2752
|
if (
|
|
2729
2753
|
execution.toolName !== request.name ||
|
|
2730
|
-
!recordArgsEqual(execution.args, request.args)
|
|
2731
|
-
execution.request.turn !== request.turn
|
|
2754
|
+
!recordArgsEqual(execution.args, request.args)
|
|
2732
2755
|
) {
|
|
2733
2756
|
return {
|
|
2734
2757
|
toolCallId: request.id,
|
|
@@ -3015,15 +3038,15 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
3015
3038
|
outputs =
|
|
3016
3039
|
directAdditionalContexts.length > 0
|
|
3017
3040
|
? [
|
|
3018
|
-
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3041
|
+
sendOutput,
|
|
3042
|
+
new HumanMessage({
|
|
3043
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
3044
|
+
// Match the event-driven path's marker so hosts /
|
|
3045
|
+
// model-side annotators treat this as system intent
|
|
3046
|
+
// rather than ordinary user text. Codex P2 [46].
|
|
3047
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
3048
|
+
}),
|
|
3049
|
+
]
|
|
3027
3050
|
: [sendOutput];
|
|
3028
3051
|
await this.handleRunToolCompletions(
|
|
3029
3052
|
[input.lg_tool_call],
|
|
@@ -3174,17 +3197,17 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
3174
3197
|
const directOutputs: (BaseMessage | Command)[] =
|
|
3175
3198
|
directCalls.length > 0
|
|
3176
3199
|
? await Promise.all(
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
)
|
|
3200
|
+
directCalls.map((call, i) =>
|
|
3201
|
+
this.runDirectToolWithLifecycleHooks(call, config, {
|
|
3202
|
+
batchIndex: directIndices[i],
|
|
3203
|
+
turn,
|
|
3204
|
+
batchScopeId,
|
|
3205
|
+
resolvedArgsByCallId,
|
|
3206
|
+
preBatchSnapshot,
|
|
3207
|
+
additionalContextsSink: directAdditionalContexts,
|
|
3208
|
+
})
|
|
3187
3209
|
)
|
|
3210
|
+
)
|
|
3188
3211
|
: [];
|
|
3189
3212
|
|
|
3190
3213
|
if (directCalls.length > 0 && directOutputs.length > 0) {
|
|
@@ -3199,29 +3222,29 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
3199
3222
|
const eventResult =
|
|
3200
3223
|
eventCalls.length > 0
|
|
3201
3224
|
? await this.dispatchToolEvents(eventCalls, config, {
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3225
|
+
batchIndices: eventIndices,
|
|
3226
|
+
turn,
|
|
3227
|
+
batchScopeId,
|
|
3228
|
+
preResolvedArgs: preResolvedEventArgs,
|
|
3229
|
+
preBatchSnapshot,
|
|
3230
|
+
})
|
|
3208
3231
|
: {
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3232
|
+
toolMessages: [] as ToolMessage[],
|
|
3233
|
+
injected: [] as BaseMessage[],
|
|
3234
|
+
};
|
|
3212
3235
|
|
|
3213
3236
|
const directInjected: BaseMessage[] =
|
|
3214
3237
|
directAdditionalContexts.length > 0
|
|
3215
3238
|
? [
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3239
|
+
new HumanMessage({
|
|
3240
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
3241
|
+
// System-role metadata to match the event-driven
|
|
3242
|
+
// path so policy/recovery guidance is treated
|
|
3243
|
+
// consistently regardless of whether the tool ran
|
|
3244
|
+
// direct or dispatched. Codex P2 [46].
|
|
3245
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
3246
|
+
}),
|
|
3247
|
+
]
|
|
3225
3248
|
: [];
|
|
3226
3249
|
outputs = [
|
|
3227
3250
|
...directOutputs,
|
|
@@ -3260,15 +3283,15 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
3260
3283
|
outputs =
|
|
3261
3284
|
directAdditionalContexts.length > 0
|
|
3262
3285
|
? [
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3286
|
+
...toolOutputs,
|
|
3287
|
+
new HumanMessage({
|
|
3288
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
3289
|
+
// Same system-role marker the event-driven path
|
|
3290
|
+
// uses so direct vs dispatched is invisible to
|
|
3291
|
+
// downstream consumers. Codex P2 [46].
|
|
3292
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
3293
|
+
}),
|
|
3294
|
+
]
|
|
3272
3295
|
: toolOutputs;
|
|
3273
3296
|
}
|
|
3274
3297
|
}
|