@librechat/agents 3.1.37 → 3.1.39
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/agents/AgentContext.cjs +3 -0
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +1 -1
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +2 -2
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/stream.cjs +2 -1
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +1 -0
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/handlers.cjs +25 -8
- package/dist/cjs/tools/handlers.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +3 -0
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +1 -1
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +2 -2
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/stream.mjs +2 -1
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +1 -0
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/handlers.mjs +25 -8
- package/dist/esm/tools/handlers.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +2 -0
- package/dist/types/tools/CodeExecutor.d.ts +2 -2
- package/dist/types/types/tools.d.ts +1 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +3 -0
- package/src/graphs/Graph.ts +1 -1
- package/src/messages/cache.test.ts +41 -0
- package/src/messages/cache.ts +2 -2
- package/src/scripts/bedrock-content-aggregation-test.ts +265 -0
- package/src/scripts/bedrock-parallel-tools-test.ts +203 -0
- package/src/scripts/tools.ts +3 -12
- package/src/stream.ts +2 -1
- package/src/tools/CodeExecutor.ts +1 -0
- package/src/tools/__tests__/ToolNode.session.test.ts +465 -0
- package/src/tools/__tests__/handlers.test.ts +994 -0
- package/src/tools/handlers.ts +32 -13
- package/src/types/tools.ts +1 -0
package/src/tools/handlers.ts
CHANGED
|
@@ -117,6 +117,7 @@ export async function handleToolCallChunks({
|
|
|
117
117
|
metadata
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
|
+
|
|
120
121
|
await graph.dispatchRunStepDelta(stepId, {
|
|
121
122
|
type: StepTypes.TOOL_CALLS,
|
|
122
123
|
tool_calls: toolCallChunks,
|
|
@@ -129,7 +130,7 @@ export const handleToolCalls = async (
|
|
|
129
130
|
graph?: StandardGraph | MultiAgentGraph
|
|
130
131
|
): Promise<void> => {
|
|
131
132
|
if (!graph || !metadata) {
|
|
132
|
-
console.warn(
|
|
133
|
+
console.warn('Graph or metadata not found in `handleToolCalls`');
|
|
133
134
|
return;
|
|
134
135
|
}
|
|
135
136
|
|
|
@@ -143,6 +144,13 @@ export const handleToolCalls = async (
|
|
|
143
144
|
|
|
144
145
|
const stepKey = graph.getStepKey(metadata);
|
|
145
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Track whether we've already reused an empty TOOL_CALLS step created by
|
|
149
|
+
* handleToolCallChunks during streaming. Only reuse it once (for the first
|
|
150
|
+
* tool call); subsequent parallel tool calls must create their own steps.
|
|
151
|
+
*/
|
|
152
|
+
let reusedChunkStepId: string | undefined;
|
|
153
|
+
|
|
146
154
|
for (const tool_call of toolCalls) {
|
|
147
155
|
const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;
|
|
148
156
|
tool_call.id = toolCallId;
|
|
@@ -159,6 +167,27 @@ export const handleToolCalls = async (
|
|
|
159
167
|
// no previous step
|
|
160
168
|
}
|
|
161
169
|
|
|
170
|
+
/**
|
|
171
|
+
* If the previous step is TOOL_CALLS (from handleToolCallChunks or a prior
|
|
172
|
+
* iteration), either reuse it (if empty) or dispatch a new TOOL_CALLS step
|
|
173
|
+
* directly — skip the intermediate MESSAGE_CREATION to avoid orphaned gaps.
|
|
174
|
+
*/
|
|
175
|
+
if (prevRunStep?.type === StepTypes.TOOL_CALLS) {
|
|
176
|
+
const details = prevRunStep.stepDetails as t.ToolCallsDetails;
|
|
177
|
+
const isEmpty = !details.tool_calls || details.tool_calls.length === 0;
|
|
178
|
+
if (isEmpty && prevStepId !== reusedChunkStepId) {
|
|
179
|
+
graph.toolCallStepIds.set(toolCallId, prevStepId);
|
|
180
|
+
reusedChunkStepId = prevStepId;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
await graph.dispatchRunStep(
|
|
184
|
+
stepKey,
|
|
185
|
+
{ type: StepTypes.TOOL_CALLS, tool_calls: [tool_call] },
|
|
186
|
+
metadata
|
|
187
|
+
);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
162
191
|
/**
|
|
163
192
|
* NOTE: We do NOT dispatch empty text blocks with tool_call_ids because:
|
|
164
193
|
* - Empty text blocks cause providers (Anthropic, Bedrock) to reject messages
|
|
@@ -167,19 +196,9 @@ export const handleToolCalls = async (
|
|
|
167
196
|
* "The content field in the Message object is empty" (Bedrock)
|
|
168
197
|
* - The tool_calls themselves are sufficient
|
|
169
198
|
*/
|
|
170
|
-
|
|
171
|
-
/* If the previous step exists and is a message creation */
|
|
172
|
-
if (
|
|
173
|
-
prevStepId &&
|
|
174
|
-
prevRunStep &&
|
|
175
|
-
prevRunStep.type === StepTypes.MESSAGE_CREATION
|
|
176
|
-
) {
|
|
199
|
+
if (prevStepId && prevRunStep) {
|
|
177
200
|
graph.messageStepHasToolCalls.set(prevStepId, true);
|
|
178
|
-
|
|
179
|
-
} else if (
|
|
180
|
-
!prevRunStep ||
|
|
181
|
-
prevRunStep.type !== StepTypes.MESSAGE_CREATION
|
|
182
|
-
) {
|
|
201
|
+
} else if (!prevRunStep) {
|
|
183
202
|
const messageId = getMessageId(stepKey, graph, true) ?? '';
|
|
184
203
|
const stepId = await graph.dispatchRunStep(
|
|
185
204
|
stepKey,
|