@librechat/agents 1.9.2 → 1.9.4

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.
@@ -50,9 +50,22 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
50
50
  super(fields);
51
51
  this._lc_stream_delay = fields._lc_stream_delay ?? 25;
52
52
  }
53
- async *_streamResponseChunks(messages$1, options, runManager) {
53
+ createGenerationChunk(text, chunk) {
54
+ return new outputs.ChatGenerationChunk({
55
+ message: new messages.AIMessageChunk({
56
+ content: chunk.content,
57
+ additional_kwargs: chunk.additional_kwargs,
58
+ tool_call_chunks: chunk.tool_call_chunks,
59
+ usage_metadata: chunk.usage_metadata,
60
+ response_metadata: chunk.response_metadata,
61
+ id: chunk.id,
62
+ }),
63
+ text,
64
+ });
65
+ }
66
+ async *_streamResponseChunks(messages, options, runManager) {
54
67
  const params = this.invocationParams(options);
55
- const formattedMessages = message_inputs._convertMessagesToAnthropicPayload(messages$1);
68
+ const formattedMessages = message_inputs._convertMessagesToAnthropicPayload(messages);
56
69
  const coerceContentToString = !_toolsInParams({
57
70
  ...params,
58
71
  ...formattedMessages,
@@ -78,50 +91,30 @@ class CustomAnthropic extends anthropic.ChatAnthropicMessages {
78
91
  if (!result)
79
92
  continue;
80
93
  const { chunk } = result;
81
- // Extract the text content token for text field and runManager.
82
94
  const [token = '', tokenType] = extractToken(chunk);
83
- const createGenerationChunk = (text, incomingChunk) => {
84
- return new outputs.ChatGenerationChunk({
85
- message: new messages.AIMessageChunk({
86
- // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
87
- content: incomingChunk.content,
88
- additional_kwargs: incomingChunk.additional_kwargs,
89
- tool_call_chunks: incomingChunk.tool_call_chunks,
90
- usage_metadata: shouldStreamUsage ? incomingChunk.usage_metadata : undefined,
91
- response_metadata: incomingChunk.response_metadata,
92
- id: incomingChunk.id,
93
- }),
94
- text,
95
- });
96
- };
97
95
  if (!tokenType || tokenType === 'input') {
98
- const generationChunk = createGenerationChunk(token, chunk);
96
+ const generationChunk = this.createGenerationChunk(token, chunk);
99
97
  yield generationChunk;
100
98
  await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
99
+ continue;
101
100
  }
102
- else {
103
- const textStream = new text.TextStream(token, { delay: this._lc_stream_delay });
104
- const generator = textStream.generateText();
105
- let result = await generator.next();
106
- while (result.done !== true) {
107
- const currentToken = result.value;
101
+ const textStream = new text.TextStream(token, {
102
+ delay: this._lc_stream_delay,
103
+ firstWordChunk: true,
104
+ minChunkSize: 4,
105
+ maxChunkSize: 8,
106
+ });
107
+ const generator = textStream.generateText();
108
+ try {
109
+ for await (const currentToken of generator) {
108
110
  const newChunk = cloneChunk(currentToken, tokenType, chunk);
109
- const generationChunk = createGenerationChunk(currentToken, newChunk);
111
+ const generationChunk = this.createGenerationChunk(currentToken, newChunk);
110
112
  yield generationChunk;
111
113
  await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
112
- result = await generator.next();
113
114
  }
114
115
  }
115
- }
116
- /** Hack to force langgraph to continue */
117
- if (options.signal?.aborted !== true) {
118
- try {
119
- stream.controller.abort();
120
- }
121
- catch (e) {
122
- console.warn('Error aborting stream after data stream', e);
123
- console.error(e);
124
- // Ignore
116
+ finally {
117
+ await generator.return();
125
118
  }
126
119
  }
127
120
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llm.cjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n\n // Extract the text content token for text field and runManager.\n const [token = '', tokenType] = extractToken(chunk);\n const createGenerationChunk = (text: string, incomingChunk: AIMessageChunk): ChatGenerationChunk => {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: incomingChunk.content,\n additional_kwargs: incomingChunk.additional_kwargs,\n tool_call_chunks: incomingChunk.tool_call_chunks,\n usage_metadata: shouldStreamUsage ? incomingChunk.usage_metadata : undefined,\n response_metadata: incomingChunk.response_metadata,\n id: incomingChunk.id,\n }),\n text,\n });\n };\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = createGenerationChunk(token, chunk);\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n } else {\n const textStream = new TextStream(token, { delay: this._lc_stream_delay });\n const generator = textStream.generateText();\n let result = await generator.next();\n\n while (result.done !== true) {\n const currentToken = result.value;\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = createGenerationChunk(currentToken, newChunk);\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n\n result = await generator.next();\n }\n }\n }\n\n /** Hack to force langgraph to continue */\n if (options.signal?.aborted !== true) {\n try {\n stream.controller.abort();\n } catch (e) {\n console.warn('Error aborting stream after data stream', e);\n console.error(e);\n // Ignore\n }\n }\n }\n}\n"],"names":["AIMessageChunk","ChatAnthropicMessages","messages","_convertMessagesToAnthropicPayload","_makeMessageChunkFromAnthropicEvent","ChatGenerationChunk","TextStream"],"mappings":"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"}
1
+ {"version":3,"file":"llm.cjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n private createGenerationChunk(text: string, chunk: AIMessageChunk): ChatGenerationChunk {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n usage_metadata: chunk.usage_metadata,\n response_metadata: chunk.response_metadata,\n id: chunk.id,\n }),\n text,\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = this.createGenerationChunk(token, chunk);\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = this.createGenerationChunk(currentToken, newChunk);\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n }\n}"],"names":["AIMessageChunk","ChatAnthropicMessages","ChatGenerationChunk","_convertMessagesToAnthropicPayload","_makeMessageChunkFromAnthropicEvent","TextStream"],"mappings":"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"}
@@ -48,6 +48,19 @@ class CustomAnthropic extends ChatAnthropicMessages {
48
48
  super(fields);
49
49
  this._lc_stream_delay = fields._lc_stream_delay ?? 25;
50
50
  }
51
+ createGenerationChunk(text, chunk) {
52
+ return new ChatGenerationChunk({
53
+ message: new AIMessageChunk({
54
+ content: chunk.content,
55
+ additional_kwargs: chunk.additional_kwargs,
56
+ tool_call_chunks: chunk.tool_call_chunks,
57
+ usage_metadata: chunk.usage_metadata,
58
+ response_metadata: chunk.response_metadata,
59
+ id: chunk.id,
60
+ }),
61
+ text,
62
+ });
63
+ }
51
64
  async *_streamResponseChunks(messages, options, runManager) {
52
65
  const params = this.invocationParams(options);
53
66
  const formattedMessages = _convertMessagesToAnthropicPayload(messages);
@@ -76,50 +89,30 @@ class CustomAnthropic extends ChatAnthropicMessages {
76
89
  if (!result)
77
90
  continue;
78
91
  const { chunk } = result;
79
- // Extract the text content token for text field and runManager.
80
92
  const [token = '', tokenType] = extractToken(chunk);
81
- const createGenerationChunk = (text, incomingChunk) => {
82
- return new ChatGenerationChunk({
83
- message: new AIMessageChunk({
84
- // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
85
- content: incomingChunk.content,
86
- additional_kwargs: incomingChunk.additional_kwargs,
87
- tool_call_chunks: incomingChunk.tool_call_chunks,
88
- usage_metadata: shouldStreamUsage ? incomingChunk.usage_metadata : undefined,
89
- response_metadata: incomingChunk.response_metadata,
90
- id: incomingChunk.id,
91
- }),
92
- text,
93
- });
94
- };
95
93
  if (!tokenType || tokenType === 'input') {
96
- const generationChunk = createGenerationChunk(token, chunk);
94
+ const generationChunk = this.createGenerationChunk(token, chunk);
97
95
  yield generationChunk;
98
96
  await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
97
+ continue;
99
98
  }
100
- else {
101
- const textStream = new TextStream(token, { delay: this._lc_stream_delay });
102
- const generator = textStream.generateText();
103
- let result = await generator.next();
104
- while (result.done !== true) {
105
- const currentToken = result.value;
99
+ const textStream = new TextStream(token, {
100
+ delay: this._lc_stream_delay,
101
+ firstWordChunk: true,
102
+ minChunkSize: 4,
103
+ maxChunkSize: 8,
104
+ });
105
+ const generator = textStream.generateText();
106
+ try {
107
+ for await (const currentToken of generator) {
106
108
  const newChunk = cloneChunk(currentToken, tokenType, chunk);
107
- const generationChunk = createGenerationChunk(currentToken, newChunk);
109
+ const generationChunk = this.createGenerationChunk(currentToken, newChunk);
108
110
  yield generationChunk;
109
111
  await runManager?.handleLLMNewToken(token, undefined, undefined, undefined, undefined, { chunk: generationChunk });
110
- result = await generator.next();
111
112
  }
112
113
  }
113
- }
114
- /** Hack to force langgraph to continue */
115
- if (options.signal?.aborted !== true) {
116
- try {
117
- stream.controller.abort();
118
- }
119
- catch (e) {
120
- console.warn('Error aborting stream after data stream', e);
121
- console.error(e);
122
- // Ignore
114
+ finally {
115
+ await generator.return();
123
116
  }
124
117
  }
125
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"llm.mjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n\n // Extract the text content token for text field and runManager.\n const [token = '', tokenType] = extractToken(chunk);\n const createGenerationChunk = (text: string, incomingChunk: AIMessageChunk): ChatGenerationChunk => {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().\n content: incomingChunk.content,\n additional_kwargs: incomingChunk.additional_kwargs,\n tool_call_chunks: incomingChunk.tool_call_chunks,\n usage_metadata: shouldStreamUsage ? incomingChunk.usage_metadata : undefined,\n response_metadata: incomingChunk.response_metadata,\n id: incomingChunk.id,\n }),\n text,\n });\n };\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = createGenerationChunk(token, chunk);\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n } else {\n const textStream = new TextStream(token, { delay: this._lc_stream_delay });\n const generator = textStream.generateText();\n let result = await generator.next();\n\n while (result.done !== true) {\n const currentToken = result.value;\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = createGenerationChunk(currentToken, newChunk);\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n\n result = await generator.next();\n }\n }\n }\n\n /** Hack to force langgraph to continue */\n if (options.signal?.aborted !== true) {\n try {\n stream.controller.abort();\n } catch (e) {\n console.warn('Error aborting stream after data stream', e);\n console.error(e);\n // Ignore\n }\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"llm.mjs","sources":["../../../../src/llm/anthropic/llm.ts"],"sourcesContent":["import { AIMessageChunk } from '@langchain/core/messages';\nimport { ChatAnthropicMessages } from '@langchain/anthropic';\nimport { ChatGenerationChunk } from '@langchain/core/outputs';\nimport type { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';\nimport type { AnthropicInput } from '@langchain/anthropic';\nimport type { AnthropicMessageCreateParams } from '@/llm/anthropic/types';\nimport { _makeMessageChunkFromAnthropicEvent } from './utils/message_outputs';\nimport { _convertMessagesToAnthropicPayload } from './utils/message_inputs';\nimport { TextStream } from '@/llm/text';\n\nfunction _toolsInParams(params: AnthropicMessageCreateParams): boolean {\n return !!(params.tools && params.tools.length > 0);\n}\n\nfunction extractToken(chunk: AIMessageChunk): [string, 'string' | 'input' | 'content'] | [undefined] {\n if (typeof chunk.content === 'string') {\n return [chunk.content, 'string'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'input' in chunk.content[0]\n ) {\n return typeof chunk.content[0].input === 'string'\n ? [chunk.content[0].input, 'input']\n : [JSON.stringify(chunk.content[0].input), 'input'];\n } else if (\n Array.isArray(chunk.content) &&\n chunk.content.length >= 1 &&\n 'text' in chunk.content[0]\n ) {\n return [chunk.content[0].text, 'content'];\n }\n return [undefined];\n}\n\nfunction cloneChunk(text: string, tokenType: string, chunk: AIMessageChunk): AIMessageChunk {\n if (tokenType === 'string') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: text }));\n } else if (tokenType === 'input') {\n return chunk;\n }\n const content = chunk.content[0] as MessageContentComplex;\n if (tokenType === 'content' && content.type === 'text') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n } else if (tokenType === 'content' && content.type === 'text_delta') {\n return new AIMessageChunk(Object.assign({}, chunk, { content: [Object.assign({}, content, { text })] }));\n }\n\n return chunk;\n}\n\nexport type CustomAnthropicInput = AnthropicInput & { _lc_stream_delay?: number };\n\nexport class CustomAnthropic extends ChatAnthropicMessages {\n _lc_stream_delay: number;\n constructor(fields: CustomAnthropicInput) {\n super(fields);\n this._lc_stream_delay = fields._lc_stream_delay ?? 25;\n }\n\n private createGenerationChunk(text: string, chunk: AIMessageChunk): ChatGenerationChunk {\n return new ChatGenerationChunk({\n message: new AIMessageChunk({\n content: chunk.content,\n additional_kwargs: chunk.additional_kwargs,\n tool_call_chunks: chunk.tool_call_chunks,\n usage_metadata: chunk.usage_metadata,\n response_metadata: chunk.response_metadata,\n id: chunk.id,\n }),\n text,\n });\n }\n\n async *_streamResponseChunks(\n messages: BaseMessage[],\n options: this['ParsedCallOptions'],\n runManager?: CallbackManagerForLLMRun\n ): AsyncGenerator<ChatGenerationChunk> {\n const params = this.invocationParams(options);\n const formattedMessages = _convertMessagesToAnthropicPayload(messages);\n const coerceContentToString = !_toolsInParams({\n ...params,\n ...formattedMessages,\n stream: false,\n });\n\n const stream = await this.createStreamWithRetry(\n {\n ...params,\n ...formattedMessages,\n stream: true,\n },\n {\n headers: options.headers,\n }\n );\n\n for await (const data of stream) {\n if (options.signal?.aborted === true) {\n stream.controller.abort();\n throw new Error('AbortError: User aborted the request.');\n }\n\n const shouldStreamUsage = this.streamUsage ?? options.streamUsage;\n const result = _makeMessageChunkFromAnthropicEvent(data, {\n streamUsage: shouldStreamUsage,\n coerceContentToString,\n });\n if (!result) continue;\n\n const { chunk } = result;\n const [token = '', tokenType] = extractToken(chunk);\n\n if (!tokenType || tokenType === 'input') {\n const generationChunk = this.createGenerationChunk(token, chunk);\n yield generationChunk;\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n continue;\n }\n\n const textStream = new TextStream(token, {\n delay: this._lc_stream_delay,\n firstWordChunk: true,\n minChunkSize: 4,\n maxChunkSize: 8,\n });\n\n const generator = textStream.generateText();\n try {\n for await (const currentToken of generator) {\n const newChunk = cloneChunk(currentToken, tokenType, chunk);\n const generationChunk = this.createGenerationChunk(currentToken, newChunk);\n yield generationChunk;\n\n await runManager?.handleLLMNewToken(\n token,\n undefined,\n undefined,\n undefined,\n undefined,\n { chunk: generationChunk }\n );\n }\n } finally {\n await generator.return();\n }\n }\n }\n}"],"names":[],"mappings":"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"}
@@ -9,5 +9,6 @@ export type CustomAnthropicInput = AnthropicInput & {
9
9
  export declare class CustomAnthropic extends ChatAnthropicMessages {
10
10
  _lc_stream_delay: number;
11
11
  constructor(fields: CustomAnthropicInput);
12
+ private createGenerationChunk;
12
13
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
13
14
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "1.9.2",
3
+ "version": "1.9.4",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -59,6 +59,20 @@ export class CustomAnthropic extends ChatAnthropicMessages {
59
59
  this._lc_stream_delay = fields._lc_stream_delay ?? 25;
60
60
  }
61
61
 
62
+ private createGenerationChunk(text: string, chunk: AIMessageChunk): ChatGenerationChunk {
63
+ return new ChatGenerationChunk({
64
+ message: new AIMessageChunk({
65
+ content: chunk.content,
66
+ additional_kwargs: chunk.additional_kwargs,
67
+ tool_call_chunks: chunk.tool_call_chunks,
68
+ usage_metadata: chunk.usage_metadata,
69
+ response_metadata: chunk.response_metadata,
70
+ id: chunk.id,
71
+ }),
72
+ text,
73
+ });
74
+ }
75
+
62
76
  async *_streamResponseChunks(
63
77
  messages: BaseMessage[],
64
78
  options: this['ParsedCallOptions'],
@@ -88,6 +102,7 @@ export class CustomAnthropic extends ChatAnthropicMessages {
88
102
  stream.controller.abort();
89
103
  throw new Error('AbortError: User aborted the request.');
90
104
  }
105
+
91
106
  const shouldStreamUsage = this.streamUsage ?? options.streamUsage;
92
107
  const result = _makeMessageChunkFromAnthropicEvent(data, {
93
108
  streamUsage: shouldStreamUsage,
@@ -96,26 +111,10 @@ export class CustomAnthropic extends ChatAnthropicMessages {
96
111
  if (!result) continue;
97
112
 
98
113
  const { chunk } = result;
99
-
100
- // Extract the text content token for text field and runManager.
101
114
  const [token = '', tokenType] = extractToken(chunk);
102
- const createGenerationChunk = (text: string, incomingChunk: AIMessageChunk): ChatGenerationChunk => {
103
- return new ChatGenerationChunk({
104
- message: new AIMessageChunk({
105
- // Just yield chunk as it is and tool_use will be concat by BaseChatModel._generateUncached().
106
- content: incomingChunk.content,
107
- additional_kwargs: incomingChunk.additional_kwargs,
108
- tool_call_chunks: incomingChunk.tool_call_chunks,
109
- usage_metadata: shouldStreamUsage ? incomingChunk.usage_metadata : undefined,
110
- response_metadata: incomingChunk.response_metadata,
111
- id: incomingChunk.id,
112
- }),
113
- text,
114
- });
115
- };
116
115
 
117
116
  if (!tokenType || tokenType === 'input') {
118
- const generationChunk = createGenerationChunk(token, chunk);
117
+ const generationChunk = this.createGenerationChunk(token, chunk);
119
118
  yield generationChunk;
120
119
  await runManager?.handleLLMNewToken(
121
120
  token,
@@ -125,15 +124,21 @@ export class CustomAnthropic extends ChatAnthropicMessages {
125
124
  undefined,
126
125
  { chunk: generationChunk }
127
126
  );
128
- } else {
129
- const textStream = new TextStream(token, { delay: this._lc_stream_delay });
130
- const generator = textStream.generateText();
131
- let result = await generator.next();
127
+ continue;
128
+ }
129
+
130
+ const textStream = new TextStream(token, {
131
+ delay: this._lc_stream_delay,
132
+ firstWordChunk: true,
133
+ minChunkSize: 4,
134
+ maxChunkSize: 8,
135
+ });
132
136
 
133
- while (result.done !== true) {
134
- const currentToken = result.value;
137
+ const generator = textStream.generateText();
138
+ try {
139
+ for await (const currentToken of generator) {
135
140
  const newChunk = cloneChunk(currentToken, tokenType, chunk);
136
- const generationChunk = createGenerationChunk(currentToken, newChunk);
141
+ const generationChunk = this.createGenerationChunk(currentToken, newChunk);
137
142
  yield generationChunk;
138
143
 
139
144
  await runManager?.handleLLMNewToken(
@@ -144,21 +149,10 @@ export class CustomAnthropic extends ChatAnthropicMessages {
144
149
  undefined,
145
150
  { chunk: generationChunk }
146
151
  );
147
-
148
- result = await generator.next();
149
152
  }
150
- }
151
- }
152
-
153
- /** Hack to force langgraph to continue */
154
- if (options.signal?.aborted !== true) {
155
- try {
156
- stream.controller.abort();
157
- } catch (e) {
158
- console.warn('Error aborting stream after data stream', e);
159
- console.error(e);
160
- // Ignore
153
+ } finally {
154
+ await generator.return();
161
155
  }
162
156
  }
163
157
  }
164
- }
158
+ }