@librechat/agents 3.0.772 → 3.0.773

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.
@@ -16,8 +16,8 @@ function deepCloneContent(content) {
16
16
  return content;
17
17
  }
18
18
  /**
19
- * Creates a shallow clone of a message with deep-cloned content.
20
- * This ensures modifications to content don't affect the original message.
19
+ * Clones a message with deep-cloned content.
20
+ * For LangChain messages, also syncs lc_kwargs.content.
21
21
  */
22
22
  function cloneMessageWithContent(message) {
23
23
  if (message.content === undefined) {
@@ -28,23 +28,22 @@ function cloneMessageWithContent(message) {
28
28
  ...message,
29
29
  content: clonedContent,
30
30
  };
31
- /**
32
- * LangChain messages store internal state in lc_kwargs.
33
- * Clone it but don't sync content yet - that happens after all modifications.
34
- */
35
- const lcKwargs = message.lc_kwargs;
36
- if (lcKwargs != null && typeof lcKwargs === 'object') {
37
- cloned.lc_kwargs = { ...lcKwargs };
31
+ const lcKwargs = cloned.lc_kwargs;
32
+ if (lcKwargs != null) {
33
+ cloned.lc_kwargs = {
34
+ ...lcKwargs,
35
+ content: clonedContent,
36
+ };
38
37
  }
39
38
  return cloned;
40
39
  }
41
40
  /**
42
- * Syncs lc_kwargs.content with the message's content property.
43
- * Call this after all modifications to ensure LangChain serialization works correctly.
41
+ * Syncs lc_kwargs.content with message.content after modifications.
42
+ * Call this after all content modifications are done.
44
43
  */
45
- function syncLcKwargsContent(message) {
44
+ function syncLcKwargs(message) {
46
45
  const lcKwargs = message.lc_kwargs;
47
- if (lcKwargs != null && typeof lcKwargs === 'object') {
46
+ if (lcKwargs != null) {
48
47
  lcKwargs.content = message.content;
49
48
  }
50
49
  }
@@ -102,7 +101,7 @@ function addCacheControl(messages) {
102
101
  }
103
102
  }
104
103
  if (userMessagesModified >= 2 || !isUserMessage) {
105
- syncLcKwargsContent(message);
104
+ syncLcKwargs(message);
106
105
  continue;
107
106
  }
108
107
  if (typeof message.content === 'string') {
@@ -127,7 +126,7 @@ function addCacheControl(messages) {
127
126
  }
128
127
  }
129
128
  }
130
- syncLcKwargsContent(message);
129
+ syncLcKwargs(message);
131
130
  }
132
131
  return updatedMessages;
133
132
  }
@@ -252,7 +251,7 @@ function addBedrockCacheControl(messages) {
252
251
  }
253
252
  }
254
253
  if (messagesModified >= 2 || isToolMessage || isEmptyString) {
255
- syncLcKwargsContent(message);
254
+ syncLcKwargs(message);
256
255
  continue;
257
256
  }
258
257
  if (typeof message.content === 'string') {
@@ -261,7 +260,7 @@ function addBedrockCacheControl(messages) {
261
260
  { cachePoint: { type: 'default' } },
262
261
  ];
263
262
  messagesModified++;
264
- syncLcKwargsContent(message);
263
+ syncLcKwargs(message);
265
264
  continue;
266
265
  }
267
266
  if (Array.isArray(message.content)) {
@@ -275,7 +274,7 @@ function addBedrockCacheControl(messages) {
275
274
  }
276
275
  }
277
276
  if (!hasCacheableContent) {
278
- syncLcKwargsContent(message);
277
+ syncLcKwargs(message);
279
278
  continue;
280
279
  }
281
280
  let inserted = false;
@@ -301,7 +300,7 @@ function addBedrockCacheControl(messages) {
301
300
  }
302
301
  messagesModified++;
303
302
  }
304
- syncLcKwargsContent(message);
303
+ syncLcKwargs(message);
305
304
  }
306
305
  return updatedMessages;
307
306
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache.cjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { AnthropicMessage } from '@/types/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { ContentTypes } from '@/common/enum';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n * Handles both string and array content types.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Creates a shallow clone of a message with deep-cloned content.\n * This ensures modifications to content don't affect the original message.\n */\nfunction cloneMessageWithContent<T extends MessageWithContent>(message: T): T {\n if (message.content === undefined) {\n return { ...message };\n }\n\n const clonedContent = deepCloneContent(message.content);\n const cloned = {\n ...message,\n content: clonedContent,\n };\n\n /**\n * LangChain messages store internal state in lc_kwargs.\n * Clone it but don't sync content yet - that happens after all modifications.\n */\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs;\n if (lcKwargs != null && typeof lcKwargs === 'object') {\n (cloned as Record<string, unknown>).lc_kwargs = { ...lcKwargs };\n }\n\n return cloned;\n}\n\n/**\n * Syncs lc_kwargs.content with the message's content property.\n * Call this after all modifications to ensure LangChain serialization works correctly.\n */\nfunction syncLcKwargsContent<T extends MessageWithContent>(message: T): void {\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs;\n if (lcKwargs != null && typeof lcKwargs === 'object') {\n (lcKwargs as Record<string, unknown>).content = message.content;\n }\n}\n\n/**\n * Checks if a message's content needs cache control stripping.\n * Returns true if content has cachePoint blocks or cache_control fields.\n */\nfunction needsCacheStripping(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n const block = content[i];\n if (isCachePoint(block)) return true;\n if ('cache_control' in block) return true;\n }\n return false;\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n\n const hasArrayContent = Array.isArray(originalMessage.content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(originalMessage.content as MessageContentComplex[]);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof originalMessage.content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(\n originalMessage as MessageWithContent\n ) as T;\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof message.content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (userMessagesModified >= 2 || !isUserMessage) {\n syncLcKwargsContent(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n {\n type: 'text',\n text: message.content,\n cache_control: { type: 'ephemeral' },\n },\n ];\n userMessagesModified++;\n } else if (Array.isArray(message.content)) {\n for (let j = message.content.length - 1; j >= 0; j--) {\n const contentPart = message.content[j];\n if ('type' in contentPart && contentPart.type === 'text') {\n (contentPart as Anthropic.TextBlockParam).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n break;\n }\n }\n }\n\n syncLcKwargsContent(message);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof content;\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the last two messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the last 2 messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends Partial<BaseMessage> & MessageWithContent,\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let messagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isToolMessage =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function' &&\n originalMessage.getType() === 'tool';\n\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(content as MessageContentComplex[]);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n messagesModified < 2 &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block)\n ) as typeof content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (messagesModified >= 2 || isToolMessage || isEmptyString) {\n syncLcKwargsContent(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, text: message.content },\n { cachePoint: { type: 'default' } },\n ] as MessageContentComplex[];\n messagesModified++;\n syncLcKwargsContent(message);\n continue;\n }\n\n if (Array.isArray(message.content)) {\n let hasCacheableContent = false;\n for (const block of message.content) {\n if (block.type === ContentTypes.TEXT) {\n if (typeof block.text === 'string' && block.text !== '') {\n hasCacheableContent = true;\n break;\n }\n }\n }\n\n if (!hasCacheableContent) {\n syncLcKwargsContent(message);\n continue;\n }\n\n let inserted = false;\n for (let j = message.content.length - 1; j >= 0; j--) {\n const block = message.content[j] as MessageContentComplex;\n const type = (block as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (block as { text?: string }).text;\n if (text === '' || text === undefined) {\n continue;\n }\n message.content.splice(j + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n message.content.push({\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n }\n messagesModified++;\n }\n\n syncLcKwargsContent(message);\n }\n\n return updatedMessages;\n}\n"],"names":["ContentTypes"],"mappings":"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"}
1
+ {"version":3,"file":"cache.cjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { AnthropicMessage } from '@/types/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { ContentTypes } from '@/common/enum';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n * Handles both string and array content types.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Clones a message with deep-cloned content.\n * For LangChain messages, also syncs lc_kwargs.content.\n */\nfunction cloneMessageWithContent<T extends MessageWithContent>(message: T): T {\n if (message.content === undefined) {\n return { ...message };\n }\n\n const clonedContent = deepCloneContent(message.content);\n const cloned = {\n ...message,\n content: clonedContent,\n } as T;\n\n const lcKwargs = (cloned as Record<string, unknown>).lc_kwargs as\n | Record<string, unknown>\n | undefined;\n if (lcKwargs != null) {\n (cloned as Record<string, unknown>).lc_kwargs = {\n ...lcKwargs,\n content: clonedContent,\n };\n }\n\n return cloned;\n}\n\n/**\n * Syncs lc_kwargs.content with message.content after modifications.\n * Call this after all content modifications are done.\n */\nfunction syncLcKwargs<T extends MessageWithContent>(message: T): void {\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs as\n | Record<string, unknown>\n | undefined;\n if (lcKwargs != null) {\n lcKwargs.content = message.content;\n }\n}\n\n/**\n * Checks if a message's content needs cache control stripping.\n * Returns true if content has cachePoint blocks or cache_control fields.\n */\nfunction needsCacheStripping(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n const block = content[i];\n if (isCachePoint(block)) return true;\n if ('cache_control' in block) return true;\n }\n return false;\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n\n const hasArrayContent = Array.isArray(originalMessage.content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(originalMessage.content as MessageContentComplex[]);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof originalMessage.content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(\n originalMessage as MessageWithContent\n ) as T;\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof message.content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (userMessagesModified >= 2 || !isUserMessage) {\n syncLcKwargs(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n {\n type: 'text',\n text: message.content,\n cache_control: { type: 'ephemeral' },\n },\n ];\n userMessagesModified++;\n } else if (Array.isArray(message.content)) {\n for (let j = message.content.length - 1; j >= 0; j--) {\n const contentPart = message.content[j];\n if ('type' in contentPart && contentPart.type === 'text') {\n (contentPart as Anthropic.TextBlockParam).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n break;\n }\n }\n }\n\n syncLcKwargs(message);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof content;\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the last two messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the last 2 messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends Partial<BaseMessage> & MessageWithContent,\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let messagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isToolMessage =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function' &&\n originalMessage.getType() === 'tool';\n\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(content as MessageContentComplex[]);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n messagesModified < 2 &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block)\n ) as typeof content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (messagesModified >= 2 || isToolMessage || isEmptyString) {\n syncLcKwargs(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, text: message.content },\n { cachePoint: { type: 'default' } },\n ] as MessageContentComplex[];\n messagesModified++;\n syncLcKwargs(message);\n continue;\n }\n\n if (Array.isArray(message.content)) {\n let hasCacheableContent = false;\n for (const block of message.content) {\n if (block.type === ContentTypes.TEXT) {\n if (typeof block.text === 'string' && block.text !== '') {\n hasCacheableContent = true;\n break;\n }\n }\n }\n\n if (!hasCacheableContent) {\n syncLcKwargs(message);\n continue;\n }\n\n let inserted = false;\n for (let j = message.content.length - 1; j >= 0; j--) {\n const block = message.content[j] as MessageContentComplex;\n const type = (block as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (block as { text?: string }).text;\n if (text === '' || text === undefined) {\n continue;\n }\n message.content.splice(j + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n message.content.push({\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n }\n messagesModified++;\n }\n\n syncLcKwargs(message);\n }\n\n return updatedMessages;\n}\n"],"names":["ContentTypes"],"mappings":"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"}
@@ -14,8 +14,8 @@ function deepCloneContent(content) {
14
14
  return content;
15
15
  }
16
16
  /**
17
- * Creates a shallow clone of a message with deep-cloned content.
18
- * This ensures modifications to content don't affect the original message.
17
+ * Clones a message with deep-cloned content.
18
+ * For LangChain messages, also syncs lc_kwargs.content.
19
19
  */
20
20
  function cloneMessageWithContent(message) {
21
21
  if (message.content === undefined) {
@@ -26,23 +26,22 @@ function cloneMessageWithContent(message) {
26
26
  ...message,
27
27
  content: clonedContent,
28
28
  };
29
- /**
30
- * LangChain messages store internal state in lc_kwargs.
31
- * Clone it but don't sync content yet - that happens after all modifications.
32
- */
33
- const lcKwargs = message.lc_kwargs;
34
- if (lcKwargs != null && typeof lcKwargs === 'object') {
35
- cloned.lc_kwargs = { ...lcKwargs };
29
+ const lcKwargs = cloned.lc_kwargs;
30
+ if (lcKwargs != null) {
31
+ cloned.lc_kwargs = {
32
+ ...lcKwargs,
33
+ content: clonedContent,
34
+ };
36
35
  }
37
36
  return cloned;
38
37
  }
39
38
  /**
40
- * Syncs lc_kwargs.content with the message's content property.
41
- * Call this after all modifications to ensure LangChain serialization works correctly.
39
+ * Syncs lc_kwargs.content with message.content after modifications.
40
+ * Call this after all content modifications are done.
42
41
  */
43
- function syncLcKwargsContent(message) {
42
+ function syncLcKwargs(message) {
44
43
  const lcKwargs = message.lc_kwargs;
45
- if (lcKwargs != null && typeof lcKwargs === 'object') {
44
+ if (lcKwargs != null) {
46
45
  lcKwargs.content = message.content;
47
46
  }
48
47
  }
@@ -100,7 +99,7 @@ function addCacheControl(messages) {
100
99
  }
101
100
  }
102
101
  if (userMessagesModified >= 2 || !isUserMessage) {
103
- syncLcKwargsContent(message);
102
+ syncLcKwargs(message);
104
103
  continue;
105
104
  }
106
105
  if (typeof message.content === 'string') {
@@ -125,7 +124,7 @@ function addCacheControl(messages) {
125
124
  }
126
125
  }
127
126
  }
128
- syncLcKwargsContent(message);
127
+ syncLcKwargs(message);
129
128
  }
130
129
  return updatedMessages;
131
130
  }
@@ -250,7 +249,7 @@ function addBedrockCacheControl(messages) {
250
249
  }
251
250
  }
252
251
  if (messagesModified >= 2 || isToolMessage || isEmptyString) {
253
- syncLcKwargsContent(message);
252
+ syncLcKwargs(message);
254
253
  continue;
255
254
  }
256
255
  if (typeof message.content === 'string') {
@@ -259,7 +258,7 @@ function addBedrockCacheControl(messages) {
259
258
  { cachePoint: { type: 'default' } },
260
259
  ];
261
260
  messagesModified++;
262
- syncLcKwargsContent(message);
261
+ syncLcKwargs(message);
263
262
  continue;
264
263
  }
265
264
  if (Array.isArray(message.content)) {
@@ -273,7 +272,7 @@ function addBedrockCacheControl(messages) {
273
272
  }
274
273
  }
275
274
  if (!hasCacheableContent) {
276
- syncLcKwargsContent(message);
275
+ syncLcKwargs(message);
277
276
  continue;
278
277
  }
279
278
  let inserted = false;
@@ -299,7 +298,7 @@ function addBedrockCacheControl(messages) {
299
298
  }
300
299
  messagesModified++;
301
300
  }
302
- syncLcKwargsContent(message);
301
+ syncLcKwargs(message);
303
302
  }
304
303
  return updatedMessages;
305
304
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cache.mjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { AnthropicMessage } from '@/types/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { ContentTypes } from '@/common/enum';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n * Handles both string and array content types.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Creates a shallow clone of a message with deep-cloned content.\n * This ensures modifications to content don't affect the original message.\n */\nfunction cloneMessageWithContent<T extends MessageWithContent>(message: T): T {\n if (message.content === undefined) {\n return { ...message };\n }\n\n const clonedContent = deepCloneContent(message.content);\n const cloned = {\n ...message,\n content: clonedContent,\n };\n\n /**\n * LangChain messages store internal state in lc_kwargs.\n * Clone it but don't sync content yet - that happens after all modifications.\n */\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs;\n if (lcKwargs != null && typeof lcKwargs === 'object') {\n (cloned as Record<string, unknown>).lc_kwargs = { ...lcKwargs };\n }\n\n return cloned;\n}\n\n/**\n * Syncs lc_kwargs.content with the message's content property.\n * Call this after all modifications to ensure LangChain serialization works correctly.\n */\nfunction syncLcKwargsContent<T extends MessageWithContent>(message: T): void {\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs;\n if (lcKwargs != null && typeof lcKwargs === 'object') {\n (lcKwargs as Record<string, unknown>).content = message.content;\n }\n}\n\n/**\n * Checks if a message's content needs cache control stripping.\n * Returns true if content has cachePoint blocks or cache_control fields.\n */\nfunction needsCacheStripping(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n const block = content[i];\n if (isCachePoint(block)) return true;\n if ('cache_control' in block) return true;\n }\n return false;\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n\n const hasArrayContent = Array.isArray(originalMessage.content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(originalMessage.content as MessageContentComplex[]);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof originalMessage.content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(\n originalMessage as MessageWithContent\n ) as T;\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof message.content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (userMessagesModified >= 2 || !isUserMessage) {\n syncLcKwargsContent(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n {\n type: 'text',\n text: message.content,\n cache_control: { type: 'ephemeral' },\n },\n ];\n userMessagesModified++;\n } else if (Array.isArray(message.content)) {\n for (let j = message.content.length - 1; j >= 0; j--) {\n const contentPart = message.content[j];\n if ('type' in contentPart && contentPart.type === 'text') {\n (contentPart as Anthropic.TextBlockParam).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n break;\n }\n }\n }\n\n syncLcKwargsContent(message);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof content;\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the last two messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the last 2 messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends Partial<BaseMessage> & MessageWithContent,\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let messagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isToolMessage =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function' &&\n originalMessage.getType() === 'tool';\n\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(content as MessageContentComplex[]);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n messagesModified < 2 &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block)\n ) as typeof content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (messagesModified >= 2 || isToolMessage || isEmptyString) {\n syncLcKwargsContent(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, text: message.content },\n { cachePoint: { type: 'default' } },\n ] as MessageContentComplex[];\n messagesModified++;\n syncLcKwargsContent(message);\n continue;\n }\n\n if (Array.isArray(message.content)) {\n let hasCacheableContent = false;\n for (const block of message.content) {\n if (block.type === ContentTypes.TEXT) {\n if (typeof block.text === 'string' && block.text !== '') {\n hasCacheableContent = true;\n break;\n }\n }\n }\n\n if (!hasCacheableContent) {\n syncLcKwargsContent(message);\n continue;\n }\n\n let inserted = false;\n for (let j = message.content.length - 1; j >= 0; j--) {\n const block = message.content[j] as MessageContentComplex;\n const type = (block as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (block as { text?: string }).text;\n if (text === '' || text === undefined) {\n continue;\n }\n message.content.splice(j + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n message.content.push({\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n }\n messagesModified++;\n }\n\n syncLcKwargsContent(message);\n }\n\n return updatedMessages;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache.mjs","sources":["../../../src/messages/cache.ts"],"sourcesContent":["import { BaseMessage, MessageContentComplex } from '@langchain/core/messages';\nimport type { AnthropicMessage } from '@/types/messages';\nimport type Anthropic from '@anthropic-ai/sdk';\nimport { ContentTypes } from '@/common/enum';\n\ntype MessageWithContent = {\n content?: string | MessageContentComplex[];\n};\n\n/**\n * Deep clones a message's content to prevent mutation of the original.\n * Handles both string and array content types.\n */\nfunction deepCloneContent<T extends string | MessageContentComplex[]>(\n content: T\n): T {\n if (typeof content === 'string') {\n return content;\n }\n if (Array.isArray(content)) {\n return content.map((block) => ({ ...block })) as T;\n }\n return content;\n}\n\n/**\n * Clones a message with deep-cloned content.\n * For LangChain messages, also syncs lc_kwargs.content.\n */\nfunction cloneMessageWithContent<T extends MessageWithContent>(message: T): T {\n if (message.content === undefined) {\n return { ...message };\n }\n\n const clonedContent = deepCloneContent(message.content);\n const cloned = {\n ...message,\n content: clonedContent,\n } as T;\n\n const lcKwargs = (cloned as Record<string, unknown>).lc_kwargs as\n | Record<string, unknown>\n | undefined;\n if (lcKwargs != null) {\n (cloned as Record<string, unknown>).lc_kwargs = {\n ...lcKwargs,\n content: clonedContent,\n };\n }\n\n return cloned;\n}\n\n/**\n * Syncs lc_kwargs.content with message.content after modifications.\n * Call this after all content modifications are done.\n */\nfunction syncLcKwargs<T extends MessageWithContent>(message: T): void {\n const lcKwargs = (message as Record<string, unknown>).lc_kwargs as\n | Record<string, unknown>\n | undefined;\n if (lcKwargs != null) {\n lcKwargs.content = message.content;\n }\n}\n\n/**\n * Checks if a message's content needs cache control stripping.\n * Returns true if content has cachePoint blocks or cache_control fields.\n */\nfunction needsCacheStripping(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n const block = content[i];\n if (isCachePoint(block)) return true;\n if ('cache_control' in block) return true;\n }\n return false;\n}\n\n/**\n * Anthropic API: Adds cache control to the appropriate user messages in the payload.\n * Strips ALL existing cache control (both Anthropic and Bedrock formats) from all messages,\n * then adds fresh cache control to the last 2 user messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache control added.\n */\nexport function addCacheControl<T extends AnthropicMessage | BaseMessage>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let userMessagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isUserMessage =\n ('getType' in originalMessage && originalMessage.getType() === 'human') ||\n ('role' in originalMessage && originalMessage.role === 'user');\n\n const hasArrayContent = Array.isArray(originalMessage.content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(originalMessage.content as MessageContentComplex[]);\n const needsCacheAdd =\n userMessagesModified < 2 &&\n isUserMessage &&\n (typeof originalMessage.content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(\n originalMessage as MessageWithContent\n ) as T;\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof message.content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (userMessagesModified >= 2 || !isUserMessage) {\n syncLcKwargs(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n {\n type: 'text',\n text: message.content,\n cache_control: { type: 'ephemeral' },\n },\n ];\n userMessagesModified++;\n } else if (Array.isArray(message.content)) {\n for (let j = message.content.length - 1; j >= 0; j--) {\n const contentPart = message.content[j];\n if ('type' in contentPart && contentPart.type === 'text') {\n (contentPart as Anthropic.TextBlockParam).cache_control = {\n type: 'ephemeral',\n };\n userMessagesModified++;\n break;\n }\n }\n }\n\n syncLcKwargs(message);\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a content block is a cache point\n */\nfunction isCachePoint(block: MessageContentComplex): boolean {\n return 'cachePoint' in block && !('type' in block);\n}\n\n/**\n * Checks if a message's content has Anthropic cache_control fields.\n */\nfunction hasAnthropicCacheControl(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if ('cache_control' in content[i]) return true;\n }\n return false;\n}\n\n/**\n * Removes all Anthropic cache_control fields from messages\n * Used when switching from Anthropic to Bedrock provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripAnthropicCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasAnthropicCacheControl(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n return updatedMessages;\n}\n\n/**\n * Checks if a message's content has Bedrock cachePoint blocks.\n */\nfunction hasBedrockCachePoint(content: MessageContentComplex[]): boolean {\n for (let i = 0; i < content.length; i++) {\n if (isCachePoint(content[i])) return true;\n }\n return false;\n}\n\n/**\n * Removes all Bedrock cachePoint blocks from messages\n * Used when switching from Bedrock to Anthropic provider\n * Returns a new array - only clones messages that require modification.\n */\nexport function stripBedrockCacheControl<T extends MessageWithContent>(\n messages: T[]\n): T[] {\n if (!Array.isArray(messages)) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n\n for (let i = 0; i < updatedMessages.length; i++) {\n const originalMessage = updatedMessages[i];\n const content = originalMessage.content;\n\n if (!Array.isArray(content) || !hasBedrockCachePoint(content)) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block as MessageContentComplex)\n ) as typeof content;\n }\n\n return updatedMessages;\n}\n\n/**\n * Adds Bedrock Converse API cache points to the last two messages.\n * Inserts `{ cachePoint: { type: 'default' } }` as a separate content block\n * immediately after the last text block in each targeted message.\n * Strips ALL existing cache control (both Bedrock and Anthropic formats) from all messages,\n * then adds fresh cache points to the last 2 messages in a single backward pass.\n * This ensures we don't accumulate stale cache points across multiple turns.\n * Returns a new array - only clones messages that require modification.\n * @param messages - The array of message objects.\n * @returns - A new array of message objects with cache points added.\n */\nexport function addBedrockCacheControl<\n T extends Partial<BaseMessage> & MessageWithContent,\n>(messages: T[]): T[] {\n if (!Array.isArray(messages) || messages.length < 2) {\n return messages;\n }\n\n const updatedMessages: T[] = [...messages];\n let messagesModified = 0;\n\n for (let i = updatedMessages.length - 1; i >= 0; i--) {\n const originalMessage = updatedMessages[i];\n const isToolMessage =\n 'getType' in originalMessage &&\n typeof originalMessage.getType === 'function' &&\n originalMessage.getType() === 'tool';\n\n const content = originalMessage.content;\n const hasArrayContent = Array.isArray(content);\n const needsStripping =\n hasArrayContent &&\n needsCacheStripping(content as MessageContentComplex[]);\n const isEmptyString = typeof content === 'string' && content === '';\n const needsCacheAdd =\n messagesModified < 2 &&\n !isToolMessage &&\n !isEmptyString &&\n (typeof content === 'string' || hasArrayContent);\n\n if (!needsStripping && !needsCacheAdd) {\n continue;\n }\n\n const message = cloneMessageWithContent(originalMessage);\n updatedMessages[i] = message;\n\n if (hasArrayContent) {\n message.content = (message.content as MessageContentComplex[]).filter(\n (block) => !isCachePoint(block)\n ) as typeof content;\n\n for (\n let j = 0;\n j < (message.content as MessageContentComplex[]).length;\n j++\n ) {\n const block = (message.content as MessageContentComplex[])[j] as Record<\n string,\n unknown\n >;\n if ('cache_control' in block) {\n delete block.cache_control;\n }\n }\n }\n\n if (messagesModified >= 2 || isToolMessage || isEmptyString) {\n syncLcKwargs(message);\n continue;\n }\n\n if (typeof message.content === 'string') {\n message.content = [\n { type: ContentTypes.TEXT, text: message.content },\n { cachePoint: { type: 'default' } },\n ] as MessageContentComplex[];\n messagesModified++;\n syncLcKwargs(message);\n continue;\n }\n\n if (Array.isArray(message.content)) {\n let hasCacheableContent = false;\n for (const block of message.content) {\n if (block.type === ContentTypes.TEXT) {\n if (typeof block.text === 'string' && block.text !== '') {\n hasCacheableContent = true;\n break;\n }\n }\n }\n\n if (!hasCacheableContent) {\n syncLcKwargs(message);\n continue;\n }\n\n let inserted = false;\n for (let j = message.content.length - 1; j >= 0; j--) {\n const block = message.content[j] as MessageContentComplex;\n const type = (block as { type?: string }).type;\n if (type === ContentTypes.TEXT || type === 'text') {\n const text = (block as { text?: string }).text;\n if (text === '' || text === undefined) {\n continue;\n }\n message.content.splice(j + 1, 0, {\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n inserted = true;\n break;\n }\n }\n if (!inserted) {\n message.content.push({\n cachePoint: { type: 'default' },\n } as MessageContentComplex);\n }\n messagesModified++;\n }\n\n syncLcKwargs(message);\n }\n\n return updatedMessages;\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.0.772",
3
+ "version": "3.0.773",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -24,8 +24,8 @@ function deepCloneContent<T extends string | MessageContentComplex[]>(
24
24
  }
25
25
 
26
26
  /**
27
- * Creates a shallow clone of a message with deep-cloned content.
28
- * This ensures modifications to content don't affect the original message.
27
+ * Clones a message with deep-cloned content.
28
+ * For LangChain messages, also syncs lc_kwargs.content.
29
29
  */
30
30
  function cloneMessageWithContent<T extends MessageWithContent>(message: T): T {
31
31
  if (message.content === undefined) {
@@ -36,28 +36,31 @@ function cloneMessageWithContent<T extends MessageWithContent>(message: T): T {
36
36
  const cloned = {
37
37
  ...message,
38
38
  content: clonedContent,
39
- };
40
-
41
- /**
42
- * LangChain messages store internal state in lc_kwargs.
43
- * Clone it but don't sync content yet - that happens after all modifications.
44
- */
45
- const lcKwargs = (message as Record<string, unknown>).lc_kwargs;
46
- if (lcKwargs != null && typeof lcKwargs === 'object') {
47
- (cloned as Record<string, unknown>).lc_kwargs = { ...lcKwargs };
39
+ } as T;
40
+
41
+ const lcKwargs = (cloned as Record<string, unknown>).lc_kwargs as
42
+ | Record<string, unknown>
43
+ | undefined;
44
+ if (lcKwargs != null) {
45
+ (cloned as Record<string, unknown>).lc_kwargs = {
46
+ ...lcKwargs,
47
+ content: clonedContent,
48
+ };
48
49
  }
49
50
 
50
51
  return cloned;
51
52
  }
52
53
 
53
54
  /**
54
- * Syncs lc_kwargs.content with the message's content property.
55
- * Call this after all modifications to ensure LangChain serialization works correctly.
55
+ * Syncs lc_kwargs.content with message.content after modifications.
56
+ * Call this after all content modifications are done.
56
57
  */
57
- function syncLcKwargsContent<T extends MessageWithContent>(message: T): void {
58
- const lcKwargs = (message as Record<string, unknown>).lc_kwargs;
59
- if (lcKwargs != null && typeof lcKwargs === 'object') {
60
- (lcKwargs as Record<string, unknown>).content = message.content;
58
+ function syncLcKwargs<T extends MessageWithContent>(message: T): void {
59
+ const lcKwargs = (message as Record<string, unknown>).lc_kwargs as
60
+ | Record<string, unknown>
61
+ | undefined;
62
+ if (lcKwargs != null) {
63
+ lcKwargs.content = message.content;
61
64
  }
62
65
  }
63
66
 
@@ -138,7 +141,7 @@ export function addCacheControl<T extends AnthropicMessage | BaseMessage>(
138
141
  }
139
142
 
140
143
  if (userMessagesModified >= 2 || !isUserMessage) {
141
- syncLcKwargsContent(message);
144
+ syncLcKwargs(message);
142
145
  continue;
143
146
  }
144
147
 
@@ -164,7 +167,7 @@ export function addCacheControl<T extends AnthropicMessage | BaseMessage>(
164
167
  }
165
168
  }
166
169
 
167
- syncLcKwargsContent(message);
170
+ syncLcKwargs(message);
168
171
  }
169
172
 
170
173
  return updatedMessages;
@@ -341,7 +344,7 @@ export function addBedrockCacheControl<
341
344
  }
342
345
 
343
346
  if (messagesModified >= 2 || isToolMessage || isEmptyString) {
344
- syncLcKwargsContent(message);
347
+ syncLcKwargs(message);
345
348
  continue;
346
349
  }
347
350
 
@@ -351,7 +354,7 @@ export function addBedrockCacheControl<
351
354
  { cachePoint: { type: 'default' } },
352
355
  ] as MessageContentComplex[];
353
356
  messagesModified++;
354
- syncLcKwargsContent(message);
357
+ syncLcKwargs(message);
355
358
  continue;
356
359
  }
357
360
 
@@ -367,7 +370,7 @@ export function addBedrockCacheControl<
367
370
  }
368
371
 
369
372
  if (!hasCacheableContent) {
370
- syncLcKwargsContent(message);
373
+ syncLcKwargs(message);
371
374
  continue;
372
375
  }
373
376
 
@@ -395,7 +398,7 @@ export function addBedrockCacheControl<
395
398
  messagesModified++;
396
399
  }
397
400
 
398
- syncLcKwargsContent(message);
401
+ syncLcKwargs(message);
399
402
  }
400
403
 
401
404
  return updatedMessages;