@librechat/agents 1.9.94 → 1.9.95

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.
@@ -222,6 +222,16 @@ function createContentAggregator() {
222
222
  }
223
223
  contentParts[index] = update;
224
224
  }
225
+ else if (partType.startsWith(ContentTypes.THINK) &&
226
+ ContentTypes.THINK in contentPart &&
227
+ typeof contentPart.think === 'string') {
228
+ const currentContent = contentParts[index];
229
+ const update = {
230
+ type: ContentTypes.THINK,
231
+ think: (currentContent.think || '') + contentPart.think,
232
+ };
233
+ contentParts[index] = update;
234
+ }
225
235
  else if (partType === ContentTypes.IMAGE_URL && 'image_url' in contentPart) {
226
236
  const currentContent = contentParts[index];
227
237
  contentParts[index] = {
@@ -279,6 +289,20 @@ function createContentAggregator() {
279
289
  updateContent(runStep.index, contentPart);
280
290
  }
281
291
  }
292
+ else if (event === GraphEvents.ON_REASONING_DELTA) {
293
+ const reasoningDelta = data;
294
+ const runStep = stepMap.get(reasoningDelta.id);
295
+ if (!runStep) {
296
+ console.warn('No run step or runId found for message delta event');
297
+ return;
298
+ }
299
+ if (reasoningDelta.delta.content) {
300
+ const contentPart = Array.isArray(reasoningDelta.delta.content)
301
+ ? reasoningDelta.delta.content[0]
302
+ : reasoningDelta.delta.content;
303
+ updateContent(runStep.index, contentPart);
304
+ }
305
+ }
282
306
  else if (event === GraphEvents.ON_RUN_STEP_DELTA) {
283
307
  const runStepDelta = data;
284
308
  const runStep = stepMap.get(runStepDelta.id);
@@ -1 +1 @@
1
- {"version":3,"file":"stream.mjs","sources":["../../src/stream.ts"],"sourcesContent":["// src/stream.ts\nimport { nanoid } from 'nanoid';\nimport type { AIMessageChunk } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\nimport { StepTypes, ContentTypes, GraphEvents, ToolCallTypes } from '@/common';\n\nfunction getNonEmptyValue(possibleValues: string[]): string | undefined {\n for (const value of possibleValues) {\n if (value && value.trim() !== '') {\n return value;\n }\n }\n return undefined;\n}\n\nconst getMessageId = (stepKey: string, graph: Graph<t.BaseGraphState>, returnExistingId = false): string | undefined => {\n const messageId = graph.messageIdsByStepKey.get(stepKey);\n if (messageId != null && messageId) {\n return returnExistingId ? messageId : undefined;\n }\n\n const prelimMessageId = graph.prelimMessageIdsByStepKey.get(stepKey);\n if (prelimMessageId != null && prelimMessageId) {\n graph.prelimMessageIdsByStepKey.delete(stepKey);\n graph.messageIdsByStepKey.set(stepKey, prelimMessageId);\n return prelimMessageId;\n }\n\n const message_id = `msg_${nanoid()}`;\n graph.messageIdsByStepKey.set(stepKey, message_id);\n return message_id;\n};\n\nexport const handleToolCalls = (toolCalls?: ToolCall[], metadata?: Record<string, unknown>, graph?: Graph): void => {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const tool_calls: ToolCall[] = [];\n const tool_call_ids: string[] = [];\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n tool_calls.push(tool_call);\n tool_call_ids.push(toolCallId);\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch (e) {\n // no previous step\n }\n\n const dispatchToolCallIds = (lastMessageStepId: string): void => {\n graph.dispatchMessageDelta(lastMessageStepId, {\n content: [{\n type: 'text',\n text: '',\n tool_call_ids,\n }],\n });\n };\n /* If the previous step exists and is a message creation */\n if (prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION) {\n dispatchToolCallIds(prevStepId);\n /* If the previous step doesn't exist or is not a message creation */\n } else if (!prevRunStep || prevRunStep.type !== StepTypes.MESSAGE_CREATION) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = graph.dispatchRunStep(stepKey, {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n });\n dispatchToolCallIds(stepId);\n }\n graph.dispatchRunStep(stepKey, {\n type: StepTypes.TOOL_CALLS,\n tool_calls,\n });\n};\n\nexport class ChatModelStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph) {\n throw new Error('Graph not found');\n }\n\n const chunk = data.chunk as AIMessageChunk | undefined;\n const content = chunk?.content;\n\n if (!graph.config) {\n throw new Error('Config not found in graph');\n }\n\n if (!chunk) {\n console.warn(`No chunk found in ${event} event`);\n return;\n }\n\n let hasToolCalls = false;\n const hasToolCallChunks = (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) ?? false;\n\n if (chunk.tool_calls && chunk.tool_calls.length > 0 && chunk.tool_calls.every((tc) => tc.id)) {\n hasToolCalls = true;\n handleToolCalls(chunk.tool_calls, metadata, graph);\n }\n\n const isEmptyContent = typeof content === 'undefined' || !content.length || typeof content === 'string' && !content;\n const isEmptyChunk = isEmptyContent && !hasToolCallChunks;\n const chunkId = chunk.id ?? '';\n if (isEmptyChunk && chunkId && chunkId.startsWith('msg')) {\n if (graph.messageIdsByStepKey.has(chunkId)) {\n return;\n } else if (graph.prelimMessageIdsByStepKey.has(chunkId)) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n graph.prelimMessageIdsByStepKey.set(stepKey, chunkId);\n return;\n } else if (isEmptyChunk) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n if (hasToolCallChunks\n && chunk.tool_call_chunks\n && chunk.tool_call_chunks.length\n && typeof chunk.tool_call_chunks[0]?.index === 'number') {\n const prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);\n const prevRunStep = graph.getRunStep(prevStepId);\n const stepId = graph.getStepIdByKey(stepKey, prevRunStep?.index);\n graph.dispatchRunStepDelta(stepId, {\n type: StepTypes.TOOL_CALLS,\n tool_calls: chunk.tool_call_chunks,\n });\n }\n\n if (isEmptyContent) {\n return;\n }\n\n const message_id = getMessageId(stepKey, graph) ?? '';\n if (message_id) {\n graph.dispatchRunStep(stepKey, {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n });\n }\n\n const stepId = graph.getStepIdByKey(stepKey);\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n // eslint-disable-next-line no-console\n console.warn(`\\n\n==============================================================\n\n\nRun step for ${stepId} does not exist, cannot dispatch delta event.\n\nevent: ${event}\nstepId: ${stepId}\nstepKey: ${stepKey}\nmessage_id: ${message_id}\nhasToolCalls: ${hasToolCalls}\nhasToolCallChunks: ${hasToolCallChunks}\n\n==============================================================\n\\n`);\n return;\n }\n\n /* Note: tool call chunks may have non-empty content that matches the current tool chunk generation */\n if (typeof content === 'string' && runStep.type === StepTypes.TOOL_CALLS) {\n return;\n } else if (hasToolCallChunks && (chunk.tool_call_chunks?.some((tc) => tc.args === content) ?? false)) {\n return;\n } else if (typeof content === 'string') {\n graph.dispatchMessageDelta(stepId, {\n content: [{\n type: 'text',\n text: content,\n }],\n });\n } else if (content.every((c) => c.type?.startsWith('text'))) {\n graph.dispatchMessageDelta(stepId, {\n content,\n });\n }\n }\n}\n\nexport type ContentAggregatorResult = {\n stepMap: Map<string, t.RunStep | undefined>;\n contentParts: Array<t.MessageContentComplex | undefined>;\n aggregateContent: ({ event, data }: {\n event: GraphEvents;\n data: t.RunStep | t.MessageDeltaEvent | t.RunStepDeltaEvent | {\n result: t.ToolEndEvent;\n };\n}) => void\n};\n\nexport function createContentAggregator(): ContentAggregatorResult {\n const contentParts: Array<t.MessageContentComplex | undefined> = [];\n const stepMap = new Map<string, t.RunStep>();\n const toolCallIdMap = new Map<string, string>();\n\n const updateContent = (\n index: number,\n contentPart: t.MessageContentComplex,\n finalUpdate = false,\n ): void => {\n const partType = contentPart.type ?? '';\n if (!partType) {\n console.warn('No content type found in content part');\n return;\n }\n\n if (!contentParts[index]) {\n contentParts[index] = { type: partType };\n }\n\n if (!partType.startsWith(contentParts[index]?.type ?? '')) {\n console.warn('Content type mismatch');\n return;\n }\n\n if (\n partType.startsWith(ContentTypes.TEXT) &&\n ContentTypes.TEXT in contentPart &&\n typeof contentPart.text === 'string'\n ) {\n // TODO: update this!!\n const currentContent = contentParts[index] as t.MessageDeltaUpdate;\n const update: t.MessageDeltaUpdate = {\n type: ContentTypes.TEXT,\n text: (currentContent.text || '') + contentPart.text,\n };\n\n if (contentPart.tool_call_ids) {\n update.tool_call_ids = contentPart.tool_call_ids;\n }\n contentParts[index] = update;\n } else if (partType === ContentTypes.IMAGE_URL && 'image_url' in contentPart) {\n const currentContent = contentParts[index] as { type: 'image_url'; image_url: string };\n contentParts[index] = {\n ...currentContent,\n };\n } else if (partType === ContentTypes.TOOL_CALL && 'tool_call' in contentPart) {\n const existingContent = contentParts[index] as Omit<t.ToolCallContent, 'tool_call'> & { tool_call?: ToolCall } | undefined;\n\n const args = finalUpdate\n ? contentPart.tool_call.args\n : (existingContent?.tool_call?.args || '') + (contentPart.tool_call.args ?? '');\n\n const id = getNonEmptyValue([contentPart.tool_call.id, existingContent?.tool_call?.id]) ?? '';\n const name =\n getNonEmptyValue([contentPart.tool_call.name, existingContent?.tool_call?.name]) ?? '';\n\n const newToolCall: ToolCall & t.PartMetadata = {\n id,\n name,\n args,\n type: ToolCallTypes.TOOL_CALL,\n };\n\n if (finalUpdate) {\n newToolCall.progress = 1;\n newToolCall.output = contentPart.tool_call.output;\n }\n\n contentParts[index] = {\n type: ContentTypes.TOOL_CALL,\n tool_call: newToolCall,\n };\n }\n };\n\n const aggregateContent = ({ event, data }: {\n event: GraphEvents;\n data: t.RunStep | t.MessageDeltaEvent | t.RunStepDeltaEvent | { result: t.ToolEndEvent };\n }): void => {\n\n if (event === GraphEvents.ON_RUN_STEP) {\n const runStep = data as t.RunStep;\n stepMap.set(runStep.id, runStep);\n\n // Store tool call IDs if present\n if (runStep.stepDetails.type === StepTypes.TOOL_CALLS && runStep.stepDetails.tool_calls) {\n runStep.stepDetails.tool_calls.forEach((toolCall) => {\n const toolCallId = toolCall.id ?? '';\n if ('id' in toolCall && toolCallId) {\n toolCallIdMap.set(runStep.id, toolCallId);\n }\n });\n }\n } else if (event === GraphEvents.ON_MESSAGE_DELTA) {\n const messageDelta = data as t.MessageDeltaEvent;\n const runStep = stepMap.get(messageDelta.id);\n if (!runStep) {\n console.warn('No run step or runId found for message delta event');\n return;\n }\n\n if (messageDelta.delta.content) {\n const contentPart = Array.isArray(messageDelta.delta.content)\n ? messageDelta.delta.content[0]\n : messageDelta.delta.content;\n\n updateContent(runStep.index, contentPart);\n }\n } else if (event === GraphEvents.ON_RUN_STEP_DELTA) {\n const runStepDelta = data as t.RunStepDeltaEvent;\n const runStep = stepMap.get(runStepDelta.id);\n if (!runStep) {\n console.warn('No run step or runId found for run step delta event');\n return;\n }\n\n if (\n runStepDelta.delta.type === StepTypes.TOOL_CALLS &&\n runStepDelta.delta.tool_calls\n ) {\n\n runStepDelta.delta.tool_calls.forEach((toolCallDelta) => {\n const toolCallId = toolCallIdMap.get(runStepDelta.id) ?? '';\n\n const contentPart: t.MessageContentComplex = {\n type: ContentTypes.TOOL_CALL,\n tool_call: {\n name: toolCallDelta.name ?? '',\n args: toolCallDelta.args ?? '',\n id: toolCallId,\n },\n };\n\n updateContent(runStep.index, contentPart);\n });\n }\n } else if (event === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const { result } = data as unknown as { result: t.ToolEndEvent };\n\n const { id: stepId } = result;\n\n const runStep = stepMap.get(stepId);\n if (!runStep) {\n console.warn('No run step or runId found for completed tool call event');\n return;\n }\n\n const contentPart: t.MessageContentComplex = {\n type: ContentTypes.TOOL_CALL,\n tool_call: result.tool_call,\n };\n\n updateContent(runStep.index, contentPart, true);\n }\n\n };\n\n return { contentParts, aggregateContent, stepMap };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"stream.mjs","sources":["../../src/stream.ts"],"sourcesContent":["// src/stream.ts\nimport { nanoid } from 'nanoid';\nimport type { AIMessageChunk } from '@langchain/core/messages';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { Graph } from '@/graphs';\nimport type * as t from '@/types';\nimport { StepTypes, ContentTypes, GraphEvents, ToolCallTypes } from '@/common';\n\nfunction getNonEmptyValue(possibleValues: string[]): string | undefined {\n for (const value of possibleValues) {\n if (value && value.trim() !== '') {\n return value;\n }\n }\n return undefined;\n}\n\nconst getMessageId = (stepKey: string, graph: Graph<t.BaseGraphState>, returnExistingId = false): string | undefined => {\n const messageId = graph.messageIdsByStepKey.get(stepKey);\n if (messageId != null && messageId) {\n return returnExistingId ? messageId : undefined;\n }\n\n const prelimMessageId = graph.prelimMessageIdsByStepKey.get(stepKey);\n if (prelimMessageId != null && prelimMessageId) {\n graph.prelimMessageIdsByStepKey.delete(stepKey);\n graph.messageIdsByStepKey.set(stepKey, prelimMessageId);\n return prelimMessageId;\n }\n\n const message_id = `msg_${nanoid()}`;\n graph.messageIdsByStepKey.set(stepKey, message_id);\n return message_id;\n};\n\nexport const handleToolCalls = (toolCalls?: ToolCall[], metadata?: Record<string, unknown>, graph?: Graph): void => {\n if (!graph || !metadata) {\n console.warn(`Graph or metadata not found in ${event} event`);\n return;\n }\n\n if (!toolCalls) {\n return;\n }\n\n if (toolCalls.length === 0) {\n return;\n }\n\n const tool_calls: ToolCall[] = [];\n const tool_call_ids: string[] = [];\n for (const tool_call of toolCalls) {\n const toolCallId = tool_call.id ?? `toolu_${nanoid()}`;\n tool_call.id = toolCallId;\n if (!toolCallId || graph.toolCallStepIds.has(toolCallId)) {\n continue;\n }\n\n tool_calls.push(tool_call);\n tool_call_ids.push(toolCallId);\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n let prevStepId = '';\n let prevRunStep: t.RunStep | undefined;\n try {\n prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);\n prevRunStep = graph.getRunStep(prevStepId);\n } catch (e) {\n // no previous step\n }\n\n const dispatchToolCallIds = (lastMessageStepId: string): void => {\n graph.dispatchMessageDelta(lastMessageStepId, {\n content: [{\n type: 'text',\n text: '',\n tool_call_ids,\n }],\n });\n };\n /* If the previous step exists and is a message creation */\n if (prevStepId && prevRunStep && prevRunStep.type === StepTypes.MESSAGE_CREATION) {\n dispatchToolCallIds(prevStepId);\n /* If the previous step doesn't exist or is not a message creation */\n } else if (!prevRunStep || prevRunStep.type !== StepTypes.MESSAGE_CREATION) {\n const messageId = getMessageId(stepKey, graph, true) ?? '';\n const stepId = graph.dispatchRunStep(stepKey, {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id: messageId,\n },\n });\n dispatchToolCallIds(stepId);\n }\n graph.dispatchRunStep(stepKey, {\n type: StepTypes.TOOL_CALLS,\n tool_calls,\n });\n};\n\nexport class ChatModelStreamHandler implements t.EventHandler {\n handle(event: string, data: t.StreamEventData, metadata?: Record<string, unknown>, graph?: Graph): void {\n if (!graph) {\n throw new Error('Graph not found');\n }\n\n const chunk = data.chunk as AIMessageChunk | undefined;\n const content = chunk?.content;\n\n if (!graph.config) {\n throw new Error('Config not found in graph');\n }\n\n if (!chunk) {\n console.warn(`No chunk found in ${event} event`);\n return;\n }\n\n let hasToolCalls = false;\n const hasToolCallChunks = (chunk.tool_call_chunks && chunk.tool_call_chunks.length > 0) ?? false;\n\n if (chunk.tool_calls && chunk.tool_calls.length > 0 && chunk.tool_calls.every((tc) => tc.id)) {\n hasToolCalls = true;\n handleToolCalls(chunk.tool_calls, metadata, graph);\n }\n\n const isEmptyContent = typeof content === 'undefined' || !content.length || typeof content === 'string' && !content;\n const isEmptyChunk = isEmptyContent && !hasToolCallChunks;\n const chunkId = chunk.id ?? '';\n if (isEmptyChunk && chunkId && chunkId.startsWith('msg')) {\n if (graph.messageIdsByStepKey.has(chunkId)) {\n return;\n } else if (graph.prelimMessageIdsByStepKey.has(chunkId)) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n graph.prelimMessageIdsByStepKey.set(stepKey, chunkId);\n return;\n } else if (isEmptyChunk) {\n return;\n }\n\n const stepKey = graph.getStepKey(metadata);\n\n if (hasToolCallChunks\n && chunk.tool_call_chunks\n && chunk.tool_call_chunks.length\n && typeof chunk.tool_call_chunks[0]?.index === 'number') {\n const prevStepId = graph.getStepIdByKey(stepKey, graph.contentData.length - 1);\n const prevRunStep = graph.getRunStep(prevStepId);\n const stepId = graph.getStepIdByKey(stepKey, prevRunStep?.index);\n graph.dispatchRunStepDelta(stepId, {\n type: StepTypes.TOOL_CALLS,\n tool_calls: chunk.tool_call_chunks,\n });\n }\n\n if (isEmptyContent) {\n return;\n }\n\n const message_id = getMessageId(stepKey, graph) ?? '';\n if (message_id) {\n graph.dispatchRunStep(stepKey, {\n type: StepTypes.MESSAGE_CREATION,\n message_creation: {\n message_id,\n },\n });\n }\n\n const stepId = graph.getStepIdByKey(stepKey);\n const runStep = graph.getRunStep(stepId);\n if (!runStep) {\n // eslint-disable-next-line no-console\n console.warn(`\\n\n==============================================================\n\n\nRun step for ${stepId} does not exist, cannot dispatch delta event.\n\nevent: ${event}\nstepId: ${stepId}\nstepKey: ${stepKey}\nmessage_id: ${message_id}\nhasToolCalls: ${hasToolCalls}\nhasToolCallChunks: ${hasToolCallChunks}\n\n==============================================================\n\\n`);\n return;\n }\n\n /* Note: tool call chunks may have non-empty content that matches the current tool chunk generation */\n if (typeof content === 'string' && runStep.type === StepTypes.TOOL_CALLS) {\n return;\n } else if (hasToolCallChunks && (chunk.tool_call_chunks?.some((tc) => tc.args === content) ?? false)) {\n return;\n } else if (typeof content === 'string') {\n graph.dispatchMessageDelta(stepId, {\n content: [{\n type: 'text',\n text: content,\n }],\n });\n } else if (content.every((c) => c.type?.startsWith('text'))) {\n graph.dispatchMessageDelta(stepId, {\n content,\n });\n }\n }\n}\n\nexport type ContentAggregatorResult = {\n stepMap: Map<string, t.RunStep | undefined>;\n contentParts: Array<t.MessageContentComplex | undefined>;\n aggregateContent: ({ event, data }: {\n event: GraphEvents;\n data: t.RunStep | t.MessageDeltaEvent | t.RunStepDeltaEvent | {\n result: t.ToolEndEvent;\n };\n}) => void\n};\n\nexport function createContentAggregator(): ContentAggregatorResult {\n const contentParts: Array<t.MessageContentComplex | undefined> = [];\n const stepMap = new Map<string, t.RunStep>();\n const toolCallIdMap = new Map<string, string>();\n\n const updateContent = (\n index: number,\n contentPart: t.MessageContentComplex,\n finalUpdate = false,\n ): void => {\n const partType = contentPart.type ?? '';\n if (!partType) {\n console.warn('No content type found in content part');\n return;\n }\n\n if (!contentParts[index]) {\n contentParts[index] = { type: partType };\n }\n\n if (!partType.startsWith(contentParts[index]?.type ?? '')) {\n console.warn('Content type mismatch');\n return;\n }\n\n if (\n partType.startsWith(ContentTypes.TEXT) &&\n ContentTypes.TEXT in contentPart &&\n typeof contentPart.text === 'string'\n ) {\n // TODO: update this!!\n const currentContent = contentParts[index] as t.MessageDeltaUpdate;\n const update: t.MessageDeltaUpdate = {\n type: ContentTypes.TEXT,\n text: (currentContent.text || '') + contentPart.text,\n };\n\n if (contentPart.tool_call_ids) {\n update.tool_call_ids = contentPart.tool_call_ids;\n }\n contentParts[index] = update;\n } else if (\n partType.startsWith(ContentTypes.THINK) &&\n ContentTypes.THINK in contentPart &&\n typeof contentPart.think === 'string'\n ) {\n const currentContent = contentParts[index] as t.ReasoningDeltaUpdate;\n const update: t.ReasoningDeltaUpdate = {\n type: ContentTypes.THINK,\n think: (currentContent.think || '') + contentPart.think,\n };\n contentParts[index] = update;\n } else if (partType === ContentTypes.IMAGE_URL && 'image_url' in contentPart) {\n const currentContent = contentParts[index] as { type: 'image_url'; image_url: string };\n contentParts[index] = {\n ...currentContent,\n };\n } else if (partType === ContentTypes.TOOL_CALL && 'tool_call' in contentPart) {\n const existingContent = contentParts[index] as Omit<t.ToolCallContent, 'tool_call'> & { tool_call?: ToolCall } | undefined;\n\n const args = finalUpdate\n ? contentPart.tool_call.args\n : (existingContent?.tool_call?.args || '') + (contentPart.tool_call.args ?? '');\n\n const id = getNonEmptyValue([contentPart.tool_call.id, existingContent?.tool_call?.id]) ?? '';\n const name =\n getNonEmptyValue([contentPart.tool_call.name, existingContent?.tool_call?.name]) ?? '';\n\n const newToolCall: ToolCall & t.PartMetadata = {\n id,\n name,\n args,\n type: ToolCallTypes.TOOL_CALL,\n };\n\n if (finalUpdate) {\n newToolCall.progress = 1;\n newToolCall.output = contentPart.tool_call.output;\n }\n\n contentParts[index] = {\n type: ContentTypes.TOOL_CALL,\n tool_call: newToolCall,\n };\n }\n };\n\n const aggregateContent = ({ event, data }: {\n event: GraphEvents;\n data: t.RunStep | t.MessageDeltaEvent | t.RunStepDeltaEvent | { result: t.ToolEndEvent };\n }): void => {\n\n if (event === GraphEvents.ON_RUN_STEP) {\n const runStep = data as t.RunStep;\n stepMap.set(runStep.id, runStep);\n\n // Store tool call IDs if present\n if (runStep.stepDetails.type === StepTypes.TOOL_CALLS && runStep.stepDetails.tool_calls) {\n runStep.stepDetails.tool_calls.forEach((toolCall) => {\n const toolCallId = toolCall.id ?? '';\n if ('id' in toolCall && toolCallId) {\n toolCallIdMap.set(runStep.id, toolCallId);\n }\n });\n }\n } else if (event === GraphEvents.ON_MESSAGE_DELTA) {\n const messageDelta = data as t.MessageDeltaEvent;\n const runStep = stepMap.get(messageDelta.id);\n if (!runStep) {\n console.warn('No run step or runId found for message delta event');\n return;\n }\n\n if (messageDelta.delta.content) {\n const contentPart = Array.isArray(messageDelta.delta.content)\n ? messageDelta.delta.content[0]\n : messageDelta.delta.content;\n\n updateContent(runStep.index, contentPart);\n }\n } else if (event === GraphEvents.ON_REASONING_DELTA) {\n const reasoningDelta = data as t.ReasoningDeltaEvent;\n const runStep = stepMap.get(reasoningDelta.id);\n if (!runStep) {\n console.warn('No run step or runId found for message delta event');\n return;\n }\n\n if (reasoningDelta.delta.content) {\n const contentPart = Array.isArray(reasoningDelta.delta.content)\n ? reasoningDelta.delta.content[0]\n : reasoningDelta.delta.content;\n\n updateContent(runStep.index, contentPart);\n }\n } else if (event === GraphEvents.ON_RUN_STEP_DELTA) {\n const runStepDelta = data as t.RunStepDeltaEvent;\n const runStep = stepMap.get(runStepDelta.id);\n if (!runStep) {\n console.warn('No run step or runId found for run step delta event');\n return;\n }\n\n if (\n runStepDelta.delta.type === StepTypes.TOOL_CALLS &&\n runStepDelta.delta.tool_calls\n ) {\n\n runStepDelta.delta.tool_calls.forEach((toolCallDelta) => {\n const toolCallId = toolCallIdMap.get(runStepDelta.id) ?? '';\n\n const contentPart: t.MessageContentComplex = {\n type: ContentTypes.TOOL_CALL,\n tool_call: {\n name: toolCallDelta.name ?? '',\n args: toolCallDelta.args ?? '',\n id: toolCallId,\n },\n };\n\n updateContent(runStep.index, contentPart);\n });\n }\n } else if (event === GraphEvents.ON_RUN_STEP_COMPLETED) {\n const { result } = data as unknown as { result: t.ToolEndEvent };\n\n const { id: stepId } = result;\n\n const runStep = stepMap.get(stepId);\n if (!runStep) {\n console.warn('No run step or runId found for completed tool call event');\n return;\n }\n\n const contentPart: t.MessageContentComplex = {\n type: ContentTypes.TOOL_CALL,\n tool_call: result.tool_call,\n };\n\n updateContent(runStep.index, contentPart, true);\n }\n\n };\n\n return { contentParts, aggregateContent, stepMap };\n}\n"],"names":[],"mappings":"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"}
@@ -13,6 +13,8 @@ export declare enum GraphEvents {
13
13
  ON_RUN_STEP_COMPLETED = "on_run_step_completed",
14
14
  /** [Custom] Delta events for messages */
15
15
  ON_MESSAGE_DELTA = "on_message_delta",
16
+ /** [Custom] Reasoning Delta events for messages */
17
+ ON_REASONING_DELTA = "on_reasoning_delta",
16
18
  /** Custom event, emitted by system */
17
19
  ON_CUSTOM_EVENT = "on_custom_event",
18
20
  /** Emitted when a chat model starts processing. */
@@ -76,6 +78,7 @@ export declare enum StepTypes {
76
78
  }
77
79
  export declare enum ContentTypes {
78
80
  TEXT = "text",
81
+ THINK = "think",
79
82
  TOOL_CALL = "tool_call",
80
83
  IMAGE_FILE = "image_file",
81
84
  IMAGE_URL = "image_url",
@@ -49,7 +49,7 @@ export declare abstract class Graph<T extends t.BaseGraphState = t.BaseGraphStat
49
49
  }
50
50
  export declare class StandardGraph extends Graph<t.BaseGraphState, GraphNode> {
51
51
  private graphState;
52
- private clientOptions;
52
+ clientOptions: t.ClientOptions;
53
53
  boundModel: Runnable;
54
54
  /** The last recorded timestamp that a stream API call was invoked */
55
55
  lastStreamCall: number | undefined;
@@ -0,0 +1,32 @@
1
+ import type * as t from '@/types';
2
+ export declare const createMockStream: (options?: {
3
+ text?: string;
4
+ reasoningText?: string;
5
+ streamRate?: number;
6
+ reasoningKey?: "reasoning" | "reasoning_content";
7
+ }) => () => AsyncGenerator<t.CustomChunk>;
8
+ /**
9
+ (async function testStream(): Promise<void> {
10
+ const runId = nanoid();
11
+
12
+ const streamHandler = new SplitStreamHandler({
13
+ runId,
14
+ handlers: {
15
+ [GraphEvents.ON_RUN_STEP]: (data): void => {
16
+ console.dir(data, { depth: null });
17
+ },
18
+ [GraphEvents.ON_MESSAGE_DELTA]: (): void => {
19
+ // console.dir(data, { depth: null });
20
+ },
21
+ },
22
+ });
23
+ const stream = createMockStream({
24
+ reasoningText: 'This is a test reasoning text.',
25
+ streamRate: 5,
26
+ })();
27
+
28
+ for await (const chunk of stream) {
29
+ streamHandler.handle(chunk);
30
+ }
31
+ })();
32
+ */
@@ -0,0 +1,35 @@
1
+ import type * as t from '@/types';
2
+ import { ContentTypes } from '@/common';
3
+ export declare const SEPARATORS: string[];
4
+ export declare class SplitStreamHandler {
5
+ private inCodeBlock;
6
+ private inThinkBlock;
7
+ private accumulate;
8
+ tokens: string[];
9
+ lastToken: string;
10
+ reasoningTokens: string[];
11
+ currentStepId?: string;
12
+ currentMessageId?: string;
13
+ currentType?: ContentTypes.TEXT | ContentTypes.THINK;
14
+ currentLength: number;
15
+ reasoningKey: 'reasoning_content' | 'reasoning';
16
+ currentIndex: number;
17
+ blockThreshold: number;
18
+ /** The run ID AKA the Message ID associated with the complete generation */
19
+ runId: string;
20
+ handlers?: t.SplitStreamHandlers;
21
+ constructor({ runId, handlers, accumulate, reasoningKey, blockThreshold, }: {
22
+ runId: string;
23
+ accumulate?: boolean;
24
+ handlers: t.SplitStreamHandlers;
25
+ blockThreshold?: number;
26
+ reasoningKey?: 'reasoning_content' | 'reasoning';
27
+ });
28
+ getMessageId: () => string | undefined;
29
+ createMessageStep: (type?: ContentTypes.TEXT | ContentTypes.THINK) => [string, string];
30
+ dispatchRunStep: (stepId: string, stepDetails: t.StepDetails) => void;
31
+ dispatchMessageDelta: (stepId: string, delta: t.MessageDelta) => void;
32
+ dispatchReasoningDelta: (stepId: string, delta: t.ReasoningDelta) => void;
33
+ handleContent: (content: string, stepId: string, _type: ContentTypes.TEXT | ContentTypes.THINK) => void;
34
+ handle(chunk?: t.CustomChunk): void;
35
+ }
@@ -1,7 +1,8 @@
1
+ import type OpenAITypes from 'openai';
1
2
  import type { MessageContentImageUrl, MessageContentText, ToolMessage, BaseMessage } from '@langchain/core/messages';
2
3
  import type { ToolCall, ToolCallChunk } from '@langchain/core/messages/tool';
3
4
  import type { LLMResult, Generation } from '@langchain/core/outputs';
4
- import { StepTypes, ContentTypes } from '@/common/enum';
5
+ import { StepTypes, ContentTypes, GraphEvents } from '@/common/enum';
5
6
  export type HandleLLMEnd = (output: LLMResult, runId: string, parentRunId?: string, tags?: string[]) => void;
6
7
  export type MetadataAggregatorResult = {
7
8
  handleLLMEnd: HandleLLMEnd;
@@ -36,7 +37,7 @@ export type RunStep = {
36
37
  index: number;
37
38
  stepIndex?: number;
38
39
  stepDetails: StepDetails;
39
- usage: null | {};
40
+ usage?: null | {};
40
41
  };
41
42
  /**
42
43
  * Represents a run step delta i.e. any changed fields on a run step during
@@ -139,16 +140,65 @@ export interface MessageDelta {
139
140
  */
140
141
  tool_call_ids?: string[];
141
142
  }
143
+ /**
144
+ * Represents a reasoning delta i.e. any changed fields on a message during
145
+ * streaming.
146
+ */
147
+ export interface ReasoningDeltaEvent {
148
+ /**
149
+ * The identifier of the message, which can be referenced in API endpoints.
150
+ */
151
+ id: string;
152
+ /**
153
+ * The delta containing the fields that have changed.
154
+ */
155
+ delta: ReasoningDelta;
156
+ }
157
+ /**
158
+ * The reasoning delta containing the fields that have changed on the Message.
159
+ */
160
+ export interface ReasoningDelta {
161
+ /**
162
+ * The content of the message in array of text and/or images.
163
+ */
164
+ content?: MessageContentComplex[];
165
+ }
142
166
  export type MessageDeltaUpdate = {
143
167
  type: ContentTypes.TEXT;
144
168
  text: string;
145
169
  tool_call_ids?: string[];
146
170
  };
147
- export type ContentType = 'text' | 'image_url' | 'tool_call' | string;
171
+ export type ReasoningDeltaUpdate = {
172
+ type: ContentTypes.THINK;
173
+ think: string;
174
+ };
175
+ export type ContentType = 'text' | 'image_url' | 'tool_call' | 'think' | string;
148
176
  export type MessageContentComplex = (MessageContentText | MessageContentImageUrl | (Record<string, any> & {
149
- type?: 'text' | 'image_url' | string;
177
+ type?: 'text' | 'image_url' | 'think' | string;
150
178
  }) | (Record<string, any> & {
151
179
  type?: never;
152
180
  })) & {
153
181
  tool_call_ids?: string[];
154
182
  };
183
+ export type CustomChunk = Partial<OpenAITypes.ChatCompletionChunk> & {
184
+ choices?: Partial<Array<Partial<OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice> & {
185
+ delta?: Partial<OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice.Delta> & {
186
+ reasoning?: string | null;
187
+ reasoning_content?: string | null;
188
+ };
189
+ }>>;
190
+ };
191
+ export type SplitStreamHandlers = Partial<{
192
+ [GraphEvents.ON_RUN_STEP]: ({ event, data }: {
193
+ event: GraphEvents;
194
+ data: RunStep;
195
+ }) => void;
196
+ [GraphEvents.ON_MESSAGE_DELTA]: ({ event, data }: {
197
+ event: GraphEvents;
198
+ data: MessageDeltaEvent;
199
+ }) => void;
200
+ [GraphEvents.ON_REASONING_DELTA]: ({ event, data }: {
201
+ event: GraphEvents;
202
+ data: ReasoningDeltaEvent;
203
+ }) => void;
204
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "1.9.94",
3
+ "version": "1.9.95",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -70,16 +70,16 @@
70
70
  "@aws-crypto/sha256-js": "^5.2.0",
71
71
  "@aws-sdk/credential-provider-node": "^3.613.0",
72
72
  "@aws-sdk/types": "^3.609.0",
73
- "@langchain/anthropic": "^0.3.11",
73
+ "@langchain/anthropic": "^0.3.12",
74
74
  "@langchain/aws": "^0.1.3",
75
- "@langchain/community": "^0.3.14",
76
- "@langchain/core": "^0.3.26",
77
- "@langchain/google-genai": "^0.1.6",
78
- "@langchain/google-vertexai": "^0.1.6",
79
- "@langchain/langgraph": "^0.2.34",
75
+ "@langchain/community": "^0.3.27",
76
+ "@langchain/core": "^0.3.36",
77
+ "@langchain/google-genai": "^0.1.7",
78
+ "@langchain/google-vertexai": "^0.1.8",
79
+ "@langchain/langgraph": "^0.2.41",
80
80
  "@langchain/mistralai": "^0.0.26",
81
- "@langchain/ollama": "^0.1.1",
82
- "@langchain/openai": "^0.3.14",
81
+ "@langchain/ollama": "^0.1.5",
82
+ "@langchain/openai": "^0.4.2",
83
83
  "@smithy/eventstream-codec": "^2.2.0",
84
84
  "@smithy/protocol-http": "^3.0.6",
85
85
  "@smithy/signature-v4": "^2.0.10",
@@ -108,7 +108,7 @@
108
108
  "@types/babel__generator": "^7.6.8",
109
109
  "@types/babel__template": "^7.4.4",
110
110
  "@types/istanbul-lib-report": "^3.0.3",
111
- "@types/jest": "^29.5.12",
111
+ "@types/jest": "^29.5.14",
112
112
  "@types/node": "^20.14.11",
113
113
  "@types/rollup": "^0.54.0",
114
114
  "@types/yargs-parser": "^21.0.3",
@@ -132,7 +132,7 @@
132
132
  "rollup-plugin-cleaner": "^1.0.0",
133
133
  "rollup-plugin-obfuscator": "^1.1.0",
134
134
  "rollup-plugin-visualizer": "^5.12.0",
135
- "ts-jest": "^29.2.0",
135
+ "ts-jest": "^29.2.5",
136
136
  "ts-node": "^10.9.2",
137
137
  "ts-node-dev": "^2.0.0",
138
138
  "tsc-alias": "^1.8.10",
@@ -15,6 +15,8 @@ export enum GraphEvents {
15
15
  ON_RUN_STEP_COMPLETED = 'on_run_step_completed',
16
16
  /** [Custom] Delta events for messages */
17
17
  ON_MESSAGE_DELTA = 'on_message_delta',
18
+ /** [Custom] Reasoning Delta events for messages */
19
+ ON_REASONING_DELTA = 'on_reasoning_delta',
18
20
 
19
21
  /* Official Events */
20
22
 
@@ -101,6 +103,7 @@ export enum StepTypes {
101
103
 
102
104
  export enum ContentTypes {
103
105
  TEXT = 'text',
106
+ THINK = 'think',
104
107
  TOOL_CALL = 'tool_call',
105
108
  IMAGE_FILE = 'image_file',
106
109
  IMAGE_URL = 'image_url',
@@ -76,7 +76,7 @@ export class StandardGraph extends Graph<
76
76
  GraphNode
77
77
  > {
78
78
  private graphState: t.GraphStateChannels<t.BaseGraphState>;
79
- private clientOptions: t.ClientOptions;
79
+ clientOptions: t.ClientOptions;
80
80
  boundModel: Runnable;
81
81
  /** The last recorded timestamp that a stream API call was invoked */
82
82
  lastStreamCall: number | undefined;
@@ -0,0 +1,99 @@
1
+ /* eslint-disable no-console */
2
+ // import { nanoid } from 'nanoid';
3
+ import type OpenAITypes from 'openai';
4
+ import type * as t from '@/types';
5
+ // import { SplitStreamHandler } from '@/splitStream';
6
+ // import { GraphEvents } from '@/common';
7
+ import { sleep } from '@/utils';
8
+
9
+ const choiceProps: OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice = { finish_reason: null, index: 0, delta: {} };
10
+ const reasoningSplitRegex = /(?<=\s+)|(?=\s+)/;
11
+ const contentSplitRegex = /(?<=<\/?think>)|(?=<\/?think>)|(?<=\s+)|(?=\s+)/;
12
+ export const createMockStream = (options: {
13
+ text?: string;
14
+ reasoningText?: string;
15
+ streamRate?: number;
16
+ reasoningKey?: 'reasoning' | 'reasoning_content';
17
+ } = {}) => {
18
+ const {
19
+ text,
20
+ reasoningText,
21
+ streamRate = 25,
22
+ reasoningKey = 'reasoning_content'
23
+ } = options;
24
+
25
+ return async function* mockOpenAIStream(): AsyncGenerator<t.CustomChunk> {
26
+ const content = text ?? `Here's a sample message that includes code:
27
+ \`\`\`python
28
+ def hello_world():
29
+ print("Hello, World!")
30
+ # This is a long code block
31
+ # That shouldn't be split
32
+ return True
33
+ \`\`\`
34
+ Now we're back to regular text. This is a very long sentence that should probably be split at some point because it exceeds our threshold and contains multiple natural breaking points. Let's see how it handles this case properly.
35
+
36
+ Here's another code block:
37
+ \`\`\`javascript
38
+ console.log("Another test");
39
+ // More code here
40
+ \`\`\`
41
+ And finally some more regular text to test our splitting logic.`;
42
+
43
+ if (reasoningText != null && reasoningText) {
44
+ // Split reasoning text into "token-like" chunks
45
+ const reasoningTokens = reasoningText.split(reasoningSplitRegex);
46
+ for (const token of reasoningTokens) {
47
+ yield {
48
+ choices: [{
49
+ ...choiceProps,
50
+ delta: {
51
+ [reasoningKey]: token,
52
+ },
53
+ }]
54
+ };
55
+ await sleep(streamRate);
56
+ }
57
+ }
58
+
59
+ // Split main content into "token-like" chunks
60
+ const tokens = content.split(contentSplitRegex);
61
+ for (const token of tokens) {
62
+ yield {
63
+ choices: [{
64
+ ...choiceProps,
65
+ delta: {
66
+ content: token
67
+ }
68
+ }]
69
+ };
70
+ await sleep(streamRate);
71
+ }
72
+ };
73
+ };
74
+
75
+ /**
76
+ (async function testStream(): Promise<void> {
77
+ const runId = nanoid();
78
+
79
+ const streamHandler = new SplitStreamHandler({
80
+ runId,
81
+ handlers: {
82
+ [GraphEvents.ON_RUN_STEP]: (data): void => {
83
+ console.dir(data, { depth: null });
84
+ },
85
+ [GraphEvents.ON_MESSAGE_DELTA]: (): void => {
86
+ // console.dir(data, { depth: null });
87
+ },
88
+ },
89
+ });
90
+ const stream = createMockStream({
91
+ reasoningText: 'This is a test reasoning text.',
92
+ streamRate: 5,
93
+ })();
94
+
95
+ for await (const chunk of stream) {
96
+ streamHandler.handle(chunk);
97
+ }
98
+ })();
99
+ */