@librechat/agents 2.1.6 → 2.1.8

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/src/stream.ts CHANGED
@@ -47,59 +47,56 @@ export const handleToolCalls = (toolCalls?: ToolCall[], metadata?: Record<string
47
47
  return;
48
48
  }
49
49
 
50
- const tool_calls: ToolCall[] = [];
51
- const tool_call_ids: string[] = [];
50
+
51
+ const stepKey = graph.getStepKey(metadata);
52
+
52
53
  for (const tool_call of toolCalls) {
53
54
  const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;
54
55
  tool_call.id = toolCallId;
55
56
  if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {
56
57
  continue;
57
58
  }
59
+
60
+ let prevStepId = '';
61
+ let prevRunStep: t.RunStep | undefined;
62
+ try {
63
+ prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);
64
+ prevRunStep = graph.getRunStep(prevStepId);
65
+ } catch (e) {
66
+ // no previous step
67
+ }
58
68
 
59
- tool_calls.push(tool_call);
60
- tool_call_ids.push(toolCallId);
61
- }
62
-
63
- const stepKey = graph.getStepKey(metadata);
64
-
65
- let prevStepId = '';
66
- let prevRunStep: t.RunStep | undefined;
67
- try {
68
- prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);
69
- prevRunStep = graph.getRunStep(prevStepId);
70
- } catch (e) {
71
- // no previous step
72
- }
69
+ const dispatchToolCallIds = (lastMessageStepId: string): void => {
70
+ graph.dispatchMessageDelta(lastMessageStepId, {
71
+ content: [{
72
+ type: 'text',
73
+ text: '',
74
+ tool_call_ids: [toolCallId],
75
+ }],
76
+ });
77
+ };
78
+ /* If the previous step exists and is a message creation */
79
+ if (prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION) {
80
+ dispatchToolCallIds(prevStepId);
81
+ graph.messageStepHasToolCalls.set(prevStepId, true);
82
+ /* If the previous step doesn't exist or is not a message creation */
83
+ } else if (!prevRunStep || prevRunStep.type !== StepTypes.MESSAGE_CREATION) {
84
+ const messageId = getMessageId(stepKey, graph, true) ?? '';
85
+ const stepId = graph.dispatchRunStep(stepKey, {
86
+ type: StepTypes.MESSAGE_CREATION,
87
+ message_creation: {
88
+ message_id: messageId,
89
+ },
90
+ });
91
+ dispatchToolCallIds(stepId);
92
+ graph.messageStepHasToolCalls.set(prevStepId, true);
93
+ }
73
94
 
74
- const dispatchToolCallIds = (lastMessageStepId: string): void => {
75
- graph.dispatchMessageDelta(lastMessageStepId, {
76
- content: [{
77
- type: 'text',
78
- text: '',
79
- tool_call_ids,
80
- }],
81
- });
82
- };
83
- /* If the previous step exists and is a message creation */
84
- if (prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION) {
85
- dispatchToolCallIds(prevStepId);
86
- graph.messageStepHasToolCalls.set(prevStepId, true);
87
- /* If the previous step doesn't exist or is not a message creation */
88
- } else if (!prevRunStep || prevRunStep.type !== StepTypes.MESSAGE_CREATION) {
89
- const messageId = getMessageId(stepKey, graph, true) ?? '';
90
- const stepId = graph.dispatchRunStep(stepKey, {
91
- type: StepTypes.MESSAGE_CREATION,
92
- message_creation: {
93
- message_id: messageId,
94
- },
95
- });
96
- dispatchToolCallIds(stepId);
97
- graph.messageStepHasToolCalls.set(prevStepId, true);
95
+ graph.dispatchRunStep(stepKey, {
96
+ type: StepTypes.TOOL_CALLS,
97
+ tool_calls: [tool_call],
98
+ });
98
99
  }
99
- graph.dispatchRunStep(stepKey, {
100
- type: StepTypes.TOOL_CALLS,
101
- tool_calls,
102
- });
103
100
  };
104
101
 
105
102
  export class ChatModelStreamHandler implements t.EventHandler {
@@ -213,11 +210,11 @@ hasToolCallChunks: ${hasToolCallChunks}
213
210
  graph.dispatchMessageDelta(stepId, {
214
211
  content,
215
212
  });
216
- } else if (content.every((c) => c.type?.startsWith(ContentTypes.THINKING))) {
213
+ } else if (content.every((c) => c.type?.startsWith(ContentTypes.THINKING) || c.type?.startsWith(ContentTypes.REASONING_CONTENT))) {
217
214
  graph.dispatchReasoningDelta(stepId, {
218
215
  content: content.map((c) => ({
219
216
  type: ContentTypes.THINK,
220
- think: (c as t.ThinkingContentText).thinking,
217
+ think: (c as t.ThinkingContentText).thinking ?? (c as t.BedrockReasoningContentText).reasoningText?.text ?? '',
221
218
  }))});
222
219
  }
223
220
  }
@@ -230,14 +227,31 @@ hasToolCallChunks: ${hasToolCallChunks}
230
227
  stepKey: string;
231
228
  toolCallChunks: ToolCallChunk[],
232
229
  }): void => {
233
- const prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);
234
- const prevRunStep = graph.getRunStep(prevStepId);
230
+ let prevStepId: string;
231
+ let prevRunStep: t.RunStep | undefined;
232
+ try {
233
+ prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);
234
+ prevRunStep = graph.getRunStep(prevStepId);
235
+ } catch (e) {
236
+ /** Edge Case: If no previous step exists, create a new message creation step */
237
+ const message_id = getMessageId(stepKey, graph, true) ?? '';
238
+ prevStepId = graph.dispatchRunStep(stepKey, {
239
+ type: StepTypes.MESSAGE_CREATION,
240
+ message_creation: {
241
+ message_id,
242
+ },
243
+ });
244
+ prevRunStep = graph.getRunStep(prevStepId);
245
+ }
246
+
235
247
  const _stepId = graph.getStepIdByKey(stepKey, prevRunStep?.index);
248
+
236
249
  /** Edge Case: Tool Call Run Step or `tool_call_ids` never dispatched */
237
250
  const tool_calls: ToolCall[] | undefined =
238
- prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION
239
- ? []
240
- : undefined;
251
+ prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION
252
+ ? []
253
+ : undefined;
254
+
241
255
  /** Edge Case: `id` and `name` fields cannot be empty strings */
242
256
  for (const toolCallChunk of toolCallChunks) {
243
257
  if (toolCallChunk.name === '') {
@@ -278,7 +292,7 @@ hasToolCallChunks: ${hasToolCallChunks}
278
292
  };
279
293
  handleReasoning(chunk: Partial<AIMessageChunk>, graph: Graph): void {
280
294
  let reasoning_content = chunk.additional_kwargs?.[graph.reasoningKey] as string | undefined;
281
- if (Array.isArray(chunk.content) && chunk.content[0]?.type === 'thinking') {
295
+ if (Array.isArray(chunk.content) && (chunk.content[0]?.type === 'thinking' || chunk.content[0]?.type === 'reasoning_content')) {
282
296
  reasoning_content = 'valid';
283
297
  }
284
298
  if (reasoning_content != null && reasoning_content && (chunk.content == null || chunk.content === '' || reasoning_content === 'valid')) {
@@ -221,7 +221,14 @@ export type ThinkingContentText = {
221
221
  type: ContentTypes.THINKING;
222
222
  index?: number;
223
223
  signature?: string;
224
- thinking: string;
224
+ thinking?: string;
225
+ };
226
+
227
+ /** Bedrock's Reasoning Content Block Format */
228
+ export type BedrockReasoningContentText = {
229
+ type: ContentTypes.REASONING_CONTENT;
230
+ index?: number;
231
+ reasoningText: { text?: string; signature?: string; }
225
232
  };
226
233
 
227
234
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -75,7 +75,7 @@ export const llmConfigs: Record<string, t.LLMConfig | undefined> = {
75
75
  },
76
76
  [Providers.VERTEXAI]: {
77
77
  provider: Providers.VERTEXAI,
78
- modelName: 'gemini-2.0-flash-exp',
78
+ modelName: 'gemini-2.0-flash-001',
79
79
  streaming: true,
80
80
  streamUsage: true,
81
81
  keyFile: process.env.VERTEXAI_KEY_FILE,