@librechat/agents 3.1.56 → 3.1.60

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.
Files changed (214) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +326 -62
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/common/enum.cjs +13 -0
  4. package/dist/cjs/common/enum.cjs.map +1 -1
  5. package/dist/cjs/events.cjs +7 -27
  6. package/dist/cjs/events.cjs.map +1 -1
  7. package/dist/cjs/graphs/Graph.cjs +303 -222
  8. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  9. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +4 -4
  10. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +6 -2
  12. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  13. package/dist/cjs/llm/init.cjs +60 -0
  14. package/dist/cjs/llm/init.cjs.map +1 -0
  15. package/dist/cjs/llm/invoke.cjs +90 -0
  16. package/dist/cjs/llm/invoke.cjs.map +1 -0
  17. package/dist/cjs/llm/openai/index.cjs +2 -0
  18. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  19. package/dist/cjs/llm/request.cjs +41 -0
  20. package/dist/cjs/llm/request.cjs.map +1 -0
  21. package/dist/cjs/main.cjs +40 -0
  22. package/dist/cjs/main.cjs.map +1 -1
  23. package/dist/cjs/messages/cache.cjs +76 -89
  24. package/dist/cjs/messages/cache.cjs.map +1 -1
  25. package/dist/cjs/messages/contextPruning.cjs +156 -0
  26. package/dist/cjs/messages/contextPruning.cjs.map +1 -0
  27. package/dist/cjs/messages/contextPruningSettings.cjs +53 -0
  28. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -0
  29. package/dist/cjs/messages/core.cjs +23 -37
  30. package/dist/cjs/messages/core.cjs.map +1 -1
  31. package/dist/cjs/messages/format.cjs +156 -11
  32. package/dist/cjs/messages/format.cjs.map +1 -1
  33. package/dist/cjs/messages/prune.cjs +1161 -49
  34. package/dist/cjs/messages/prune.cjs.map +1 -1
  35. package/dist/cjs/messages/reducer.cjs +87 -0
  36. package/dist/cjs/messages/reducer.cjs.map +1 -0
  37. package/dist/cjs/run.cjs +81 -42
  38. package/dist/cjs/run.cjs.map +1 -1
  39. package/dist/cjs/stream.cjs +54 -7
  40. package/dist/cjs/stream.cjs.map +1 -1
  41. package/dist/cjs/summarization/index.cjs +75 -0
  42. package/dist/cjs/summarization/index.cjs.map +1 -0
  43. package/dist/cjs/summarization/node.cjs +663 -0
  44. package/dist/cjs/summarization/node.cjs.map +1 -0
  45. package/dist/cjs/tools/ToolNode.cjs +16 -8
  46. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  47. package/dist/cjs/tools/handlers.cjs +2 -0
  48. package/dist/cjs/tools/handlers.cjs.map +1 -1
  49. package/dist/cjs/utils/errors.cjs +115 -0
  50. package/dist/cjs/utils/errors.cjs.map +1 -0
  51. package/dist/cjs/utils/events.cjs +17 -0
  52. package/dist/cjs/utils/events.cjs.map +1 -1
  53. package/dist/cjs/utils/handlers.cjs +16 -0
  54. package/dist/cjs/utils/handlers.cjs.map +1 -1
  55. package/dist/cjs/utils/llm.cjs +10 -0
  56. package/dist/cjs/utils/llm.cjs.map +1 -1
  57. package/dist/cjs/utils/tokens.cjs +247 -14
  58. package/dist/cjs/utils/tokens.cjs.map +1 -1
  59. package/dist/cjs/utils/truncation.cjs +107 -0
  60. package/dist/cjs/utils/truncation.cjs.map +1 -0
  61. package/dist/esm/agents/AgentContext.mjs +325 -61
  62. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  63. package/dist/esm/common/enum.mjs +13 -0
  64. package/dist/esm/common/enum.mjs.map +1 -1
  65. package/dist/esm/events.mjs +8 -28
  66. package/dist/esm/events.mjs.map +1 -1
  67. package/dist/esm/graphs/Graph.mjs +307 -226
  68. package/dist/esm/graphs/Graph.mjs.map +1 -1
  69. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +4 -4
  70. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  71. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +6 -2
  72. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  73. package/dist/esm/llm/init.mjs +58 -0
  74. package/dist/esm/llm/init.mjs.map +1 -0
  75. package/dist/esm/llm/invoke.mjs +87 -0
  76. package/dist/esm/llm/invoke.mjs.map +1 -0
  77. package/dist/esm/llm/openai/index.mjs +2 -0
  78. package/dist/esm/llm/openai/index.mjs.map +1 -1
  79. package/dist/esm/llm/request.mjs +38 -0
  80. package/dist/esm/llm/request.mjs.map +1 -0
  81. package/dist/esm/main.mjs +13 -3
  82. package/dist/esm/main.mjs.map +1 -1
  83. package/dist/esm/messages/cache.mjs +76 -89
  84. package/dist/esm/messages/cache.mjs.map +1 -1
  85. package/dist/esm/messages/contextPruning.mjs +154 -0
  86. package/dist/esm/messages/contextPruning.mjs.map +1 -0
  87. package/dist/esm/messages/contextPruningSettings.mjs +50 -0
  88. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -0
  89. package/dist/esm/messages/core.mjs +23 -37
  90. package/dist/esm/messages/core.mjs.map +1 -1
  91. package/dist/esm/messages/format.mjs +156 -11
  92. package/dist/esm/messages/format.mjs.map +1 -1
  93. package/dist/esm/messages/prune.mjs +1158 -52
  94. package/dist/esm/messages/prune.mjs.map +1 -1
  95. package/dist/esm/messages/reducer.mjs +83 -0
  96. package/dist/esm/messages/reducer.mjs.map +1 -0
  97. package/dist/esm/run.mjs +82 -43
  98. package/dist/esm/run.mjs.map +1 -1
  99. package/dist/esm/stream.mjs +54 -7
  100. package/dist/esm/stream.mjs.map +1 -1
  101. package/dist/esm/summarization/index.mjs +73 -0
  102. package/dist/esm/summarization/index.mjs.map +1 -0
  103. package/dist/esm/summarization/node.mjs +659 -0
  104. package/dist/esm/summarization/node.mjs.map +1 -0
  105. package/dist/esm/tools/ToolNode.mjs +16 -8
  106. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  107. package/dist/esm/tools/handlers.mjs +2 -0
  108. package/dist/esm/tools/handlers.mjs.map +1 -1
  109. package/dist/esm/utils/errors.mjs +111 -0
  110. package/dist/esm/utils/errors.mjs.map +1 -0
  111. package/dist/esm/utils/events.mjs +17 -1
  112. package/dist/esm/utils/events.mjs.map +1 -1
  113. package/dist/esm/utils/handlers.mjs +16 -0
  114. package/dist/esm/utils/handlers.mjs.map +1 -1
  115. package/dist/esm/utils/llm.mjs +10 -1
  116. package/dist/esm/utils/llm.mjs.map +1 -1
  117. package/dist/esm/utils/tokens.mjs +245 -15
  118. package/dist/esm/utils/tokens.mjs.map +1 -1
  119. package/dist/esm/utils/truncation.mjs +102 -0
  120. package/dist/esm/utils/truncation.mjs.map +1 -0
  121. package/dist/types/agents/AgentContext.d.ts +124 -6
  122. package/dist/types/common/enum.d.ts +14 -1
  123. package/dist/types/graphs/Graph.d.ts +22 -27
  124. package/dist/types/index.d.ts +5 -0
  125. package/dist/types/llm/init.d.ts +18 -0
  126. package/dist/types/llm/invoke.d.ts +48 -0
  127. package/dist/types/llm/request.d.ts +14 -0
  128. package/dist/types/messages/contextPruning.d.ts +42 -0
  129. package/dist/types/messages/contextPruningSettings.d.ts +44 -0
  130. package/dist/types/messages/core.d.ts +1 -1
  131. package/dist/types/messages/format.d.ts +17 -1
  132. package/dist/types/messages/index.d.ts +3 -0
  133. package/dist/types/messages/prune.d.ts +162 -1
  134. package/dist/types/messages/reducer.d.ts +18 -0
  135. package/dist/types/run.d.ts +12 -1
  136. package/dist/types/summarization/index.d.ts +20 -0
  137. package/dist/types/summarization/node.d.ts +29 -0
  138. package/dist/types/tools/ToolNode.d.ts +3 -1
  139. package/dist/types/types/graph.d.ts +44 -6
  140. package/dist/types/types/index.d.ts +1 -0
  141. package/dist/types/types/run.d.ts +30 -0
  142. package/dist/types/types/stream.d.ts +31 -4
  143. package/dist/types/types/summarize.d.ts +47 -0
  144. package/dist/types/types/tools.d.ts +7 -0
  145. package/dist/types/utils/errors.d.ts +28 -0
  146. package/dist/types/utils/events.d.ts +13 -0
  147. package/dist/types/utils/index.d.ts +2 -0
  148. package/dist/types/utils/llm.d.ts +4 -0
  149. package/dist/types/utils/tokens.d.ts +14 -1
  150. package/dist/types/utils/truncation.d.ts +49 -0
  151. package/package.json +2 -2
  152. package/src/agents/AgentContext.ts +388 -58
  153. package/src/agents/__tests__/AgentContext.test.ts +265 -5
  154. package/src/common/enum.ts +13 -0
  155. package/src/events.ts +9 -39
  156. package/src/graphs/Graph.ts +468 -331
  157. package/src/index.ts +7 -0
  158. package/src/llm/anthropic/llm.spec.ts +3 -3
  159. package/src/llm/anthropic/utils/message_inputs.ts +6 -4
  160. package/src/llm/bedrock/llm.spec.ts +1 -1
  161. package/src/llm/bedrock/utils/message_inputs.ts +6 -2
  162. package/src/llm/init.ts +63 -0
  163. package/src/llm/invoke.ts +144 -0
  164. package/src/llm/request.ts +55 -0
  165. package/src/messages/__tests__/observationMasking.test.ts +221 -0
  166. package/src/messages/cache.ts +77 -102
  167. package/src/messages/contextPruning.ts +191 -0
  168. package/src/messages/contextPruningSettings.ts +90 -0
  169. package/src/messages/core.ts +32 -53
  170. package/src/messages/ensureThinkingBlock.test.ts +39 -39
  171. package/src/messages/format.ts +227 -15
  172. package/src/messages/formatAgentMessages.test.ts +511 -1
  173. package/src/messages/index.ts +3 -0
  174. package/src/messages/prune.ts +1548 -62
  175. package/src/messages/reducer.ts +22 -0
  176. package/src/run.ts +104 -51
  177. package/src/scripts/bedrock-merge-test.ts +1 -1
  178. package/src/scripts/test-thinking-handoff-bedrock.ts +1 -1
  179. package/src/scripts/test-thinking-handoff.ts +1 -1
  180. package/src/scripts/thinking-bedrock.ts +1 -1
  181. package/src/scripts/thinking.ts +1 -1
  182. package/src/specs/anthropic.simple.test.ts +1 -1
  183. package/src/specs/multi-agent-summarization.test.ts +396 -0
  184. package/src/specs/prune.test.ts +1196 -23
  185. package/src/specs/summarization-unit.test.ts +868 -0
  186. package/src/specs/summarization.test.ts +3810 -0
  187. package/src/specs/summarize-prune.test.ts +376 -0
  188. package/src/specs/thinking-handoff.test.ts +10 -10
  189. package/src/specs/thinking-prune.test.ts +7 -4
  190. package/src/specs/token-accounting-e2e.test.ts +1034 -0
  191. package/src/specs/token-accounting-pipeline.test.ts +882 -0
  192. package/src/specs/token-distribution-edge-case.test.ts +25 -26
  193. package/src/splitStream.test.ts +42 -33
  194. package/src/stream.ts +64 -11
  195. package/src/summarization/__tests__/aggregator.test.ts +153 -0
  196. package/src/summarization/__tests__/node.test.ts +708 -0
  197. package/src/summarization/__tests__/trigger.test.ts +50 -0
  198. package/src/summarization/index.ts +102 -0
  199. package/src/summarization/node.ts +982 -0
  200. package/src/tools/ToolNode.ts +25 -3
  201. package/src/types/graph.ts +62 -7
  202. package/src/types/index.ts +1 -0
  203. package/src/types/run.ts +32 -0
  204. package/src/types/stream.ts +45 -5
  205. package/src/types/summarize.ts +58 -0
  206. package/src/types/tools.ts +7 -0
  207. package/src/utils/errors.ts +117 -0
  208. package/src/utils/events.ts +31 -0
  209. package/src/utils/handlers.ts +18 -0
  210. package/src/utils/index.ts +2 -0
  211. package/src/utils/llm.ts +12 -0
  212. package/src/utils/tokens.ts +336 -18
  213. package/src/utils/truncation.ts +124 -0
  214. package/src/scripts/image.ts +0 -180
@@ -1 +1 @@
1
- {"version":3,"file":"prune.cjs","sources":["../../../src/messages/prune.ts"],"sourcesContent":["import {\n AIMessage,\n BaseMessage,\n UsageMetadata,\n} from '@langchain/core/messages';\nimport type {\n ThinkingContentText,\n MessageContentComplex,\n ReasoningContentText,\n} from '@/types/stream';\nimport type { TokenCounter } from '@/types/run';\nimport { ContentTypes, Providers } from '@/common';\n\nexport type PruneMessagesFactoryParams = {\n provider?: Providers;\n maxTokens: number;\n startIndex: number;\n tokenCounter: TokenCounter;\n indexTokenCountMap: Record<string, number | undefined>;\n thinkingEnabled?: boolean;\n};\nexport type PruneMessagesParams = {\n messages: BaseMessage[];\n usageMetadata?: Partial<UsageMetadata>;\n startType?: ReturnType<BaseMessage['getType']>;\n};\n\nfunction isIndexInContext(\n arrayA: unknown[],\n arrayB: unknown[],\n targetIndex: number\n): boolean {\n const startingIndexInA = arrayA.length - arrayB.length;\n return targetIndex >= startingIndexInA;\n}\n\nfunction addThinkingBlock(\n message: AIMessage,\n thinkingBlock: ThinkingContentText | ReasoningContentText\n): AIMessage {\n const content: MessageContentComplex[] = Array.isArray(message.content)\n ? (message.content as MessageContentComplex[])\n : [\n {\n type: ContentTypes.TEXT,\n text: message.content,\n },\n ];\n /** Edge case, the message already has the thinking block */\n if (content[0].type === thinkingBlock.type) {\n return message;\n }\n content.unshift(thinkingBlock);\n return new AIMessage({\n ...message,\n content,\n });\n}\n\n/**\n * Calculates the total tokens from a single usage object\n *\n * @param usage The usage metadata object containing token information\n * @returns An object containing the total input and output tokens\n */\nexport function calculateTotalTokens(\n usage: Partial<UsageMetadata>\n): UsageMetadata {\n const baseInputTokens = Number(usage.input_tokens) || 0;\n const cacheCreation = Number(usage.input_token_details?.cache_creation) || 0;\n const cacheRead = Number(usage.input_token_details?.cache_read) || 0;\n\n const totalInputTokens = baseInputTokens + cacheCreation + cacheRead;\n const totalOutputTokens = Number(usage.output_tokens) || 0;\n\n return {\n input_tokens: totalInputTokens,\n output_tokens: totalOutputTokens,\n total_tokens: totalInputTokens + totalOutputTokens,\n };\n}\n\nexport type PruningResult = {\n context: BaseMessage[];\n remainingContextTokens: number;\n messagesToRefine: BaseMessage[];\n thinkingStartIndex?: number;\n};\n\n/**\n * Processes an array of messages and returns a context of messages that fit within a specified token limit.\n * It iterates over the messages from newest to oldest, adding them to the context until the token limit is reached.\n *\n * @param options Configuration options for processing messages\n * @returns Object containing the message context, remaining tokens, messages not included, and summary index\n */\nexport function getMessagesWithinTokenLimit({\n messages: _messages,\n maxContextTokens,\n indexTokenCountMap,\n startType: _startType,\n thinkingEnabled,\n tokenCounter,\n thinkingStartIndex: _thinkingStartIndex = -1,\n reasoningType = ContentTypes.THINKING,\n}: {\n messages: BaseMessage[];\n maxContextTokens: number;\n indexTokenCountMap: Record<string, number | undefined>;\n startType?: string | string[];\n thinkingEnabled?: boolean;\n tokenCounter: TokenCounter;\n thinkingStartIndex?: number;\n reasoningType?: ContentTypes.THINKING | ContentTypes.REASONING_CONTENT;\n}): PruningResult {\n // Every reply is primed with <|start|>assistant<|message|>, so we\n // start with 3 tokens for the label after all messages have been counted.\n let currentTokenCount = 3;\n const instructions =\n _messages[0]?.getType() === 'system' ? _messages[0] : undefined;\n const instructionsTokenCount =\n instructions != null ? (indexTokenCountMap[0] ?? 0) : 0;\n const initialContextTokens = maxContextTokens - instructionsTokenCount;\n let remainingContextTokens = initialContextTokens;\n let startType = _startType;\n const originalLength = _messages.length;\n const messages = [..._messages];\n /**\n * IMPORTANT: this context array gets reversed at the end, since the latest messages get pushed first.\n *\n * This may be confusing to read, but it is done to ensure the context is in the correct order for the model.\n * */\n let context: Array<BaseMessage | undefined> = [];\n\n let thinkingStartIndex = _thinkingStartIndex;\n let thinkingEndIndex = -1;\n let thinkingBlock: ThinkingContentText | ReasoningContentText | undefined;\n const endIndex = instructions != null ? 1 : 0;\n const prunedMemory: BaseMessage[] = [];\n\n if (_thinkingStartIndex > -1) {\n const thinkingMessageContent = messages[_thinkingStartIndex]?.content;\n if (Array.isArray(thinkingMessageContent)) {\n thinkingBlock = thinkingMessageContent.find(\n (content) => content.type === reasoningType\n ) as ThinkingContentText | undefined;\n }\n }\n\n if (currentTokenCount < remainingContextTokens) {\n let currentIndex = messages.length;\n while (\n messages.length > 0 &&\n currentTokenCount < remainingContextTokens &&\n currentIndex > endIndex\n ) {\n currentIndex--;\n if (messages.length === 1 && instructions) {\n break;\n }\n const poppedMessage = messages.pop();\n if (!poppedMessage) continue;\n const messageType = poppedMessage.getType();\n if (\n thinkingEnabled === true &&\n thinkingEndIndex === -1 &&\n currentIndex === originalLength - 1 &&\n (messageType === 'ai' || messageType === 'tool')\n ) {\n thinkingEndIndex = currentIndex;\n }\n if (\n thinkingEndIndex > -1 &&\n !thinkingBlock &&\n thinkingStartIndex < 0 &&\n messageType === 'ai' &&\n Array.isArray(poppedMessage.content)\n ) {\n thinkingBlock = poppedMessage.content.find(\n (content) => content.type === reasoningType\n ) as ThinkingContentText | undefined;\n thinkingStartIndex = thinkingBlock != null ? currentIndex : -1;\n }\n /** False start, the latest message was not part of a multi-assistant/tool sequence of messages */\n if (\n thinkingEndIndex > -1 &&\n currentIndex === thinkingEndIndex - 1 &&\n messageType !== 'ai' &&\n messageType !== 'tool'\n ) {\n thinkingEndIndex = -1;\n }\n\n const tokenCount = indexTokenCountMap[currentIndex] ?? 0;\n\n if (\n prunedMemory.length === 0 &&\n currentTokenCount + tokenCount <= remainingContextTokens\n ) {\n context.push(poppedMessage);\n currentTokenCount += tokenCount;\n } else {\n prunedMemory.push(poppedMessage);\n if (thinkingEndIndex > -1 && thinkingStartIndex < 0) {\n continue;\n }\n break;\n }\n }\n\n if (context[context.length - 1]?.getType() === 'tool') {\n startType = ['ai', 'human'];\n }\n\n if (startType != null && startType.length > 0 && context.length > 0) {\n let requiredTypeIndex = -1;\n\n let totalTokens = 0;\n for (let i = context.length - 1; i >= 0; i--) {\n const currentType = context[i]?.getType() ?? '';\n if (\n Array.isArray(startType)\n ? startType.includes(currentType)\n : currentType === startType\n ) {\n requiredTypeIndex = i + 1;\n break;\n }\n const originalIndex = originalLength - 1 - i;\n totalTokens += indexTokenCountMap[originalIndex] ?? 0;\n }\n\n if (requiredTypeIndex > 0) {\n currentTokenCount -= totalTokens;\n context = context.slice(0, requiredTypeIndex);\n }\n }\n }\n\n if (instructions && originalLength > 0) {\n context.push(_messages[0] as BaseMessage);\n messages.shift();\n }\n\n remainingContextTokens -= currentTokenCount;\n const result: PruningResult = {\n remainingContextTokens,\n context: [] as BaseMessage[],\n messagesToRefine: prunedMemory,\n };\n\n if (thinkingStartIndex > -1) {\n result.thinkingStartIndex = thinkingStartIndex;\n }\n\n if (\n prunedMemory.length === 0 ||\n thinkingEndIndex < 0 ||\n (thinkingStartIndex > -1 &&\n isIndexInContext(_messages, context, thinkingStartIndex))\n ) {\n // we reverse at this step to ensure the context is in the correct order for the model, and we need to work backwards\n result.context = context.reverse() as BaseMessage[];\n return result;\n }\n\n if (thinkingEndIndex > -1 && thinkingStartIndex < 0) {\n throw new Error(\n 'The payload is malformed. There is a thinking sequence but no \"AI\" messages with thinking blocks.'\n );\n }\n\n if (!thinkingBlock) {\n throw new Error(\n 'The payload is malformed. There is a thinking sequence but no thinking block found.'\n );\n }\n\n // Since we have a thinking sequence, we need to find the last assistant message\n // in the latest AI/tool sequence to add the thinking block that falls outside of the current context\n // Latest messages are ordered first.\n let assistantIndex = -1;\n for (let i = 0; i < context.length; i++) {\n const currentMessage = context[i];\n const type = currentMessage?.getType();\n if (type === 'ai') {\n assistantIndex = i;\n }\n if (assistantIndex > -1 && (type === 'human' || type === 'system')) {\n break;\n }\n }\n\n if (assistantIndex === -1) {\n throw new Error(\n 'Context window exceeded: aggressive pruning removed all AI messages (likely due to an oversized tool response). Increase max context tokens or reduce tool output size.'\n );\n }\n\n thinkingStartIndex = originalLength - 1 - assistantIndex;\n const thinkingTokenCount = tokenCounter(\n new AIMessage({ content: [thinkingBlock] })\n );\n const newRemainingCount = remainingContextTokens - thinkingTokenCount;\n const newMessage = addThinkingBlock(\n context[assistantIndex] as AIMessage,\n thinkingBlock\n );\n context[assistantIndex] = newMessage;\n if (newRemainingCount > 0) {\n result.context = context.reverse() as BaseMessage[];\n return result;\n }\n\n const thinkingMessage: AIMessage = context[assistantIndex] as AIMessage;\n // now we need to an additional round of pruning but making the thinking block fit\n const newThinkingMessageTokenCount =\n (indexTokenCountMap[thinkingStartIndex] ?? 0) + thinkingTokenCount;\n remainingContextTokens = initialContextTokens - newThinkingMessageTokenCount;\n currentTokenCount = 3;\n let newContext: BaseMessage[] = [];\n const secondRoundMessages = [..._messages];\n let currentIndex = secondRoundMessages.length;\n while (\n secondRoundMessages.length > 0 &&\n currentTokenCount < remainingContextTokens &&\n currentIndex > thinkingStartIndex\n ) {\n currentIndex--;\n const poppedMessage = secondRoundMessages.pop();\n if (!poppedMessage) continue;\n const tokenCount = indexTokenCountMap[currentIndex] ?? 0;\n if (currentTokenCount + tokenCount <= remainingContextTokens) {\n newContext.push(poppedMessage);\n currentTokenCount += tokenCount;\n } else {\n messages.push(poppedMessage);\n break;\n }\n }\n\n const firstMessage: AIMessage = newContext[newContext.length - 1];\n const firstMessageType = newContext[newContext.length - 1].getType();\n if (firstMessageType === 'tool') {\n startType = ['ai', 'human'];\n }\n\n if (startType != null && startType.length > 0 && newContext.length > 0) {\n let requiredTypeIndex = -1;\n\n let totalTokens = 0;\n for (let i = newContext.length - 1; i >= 0; i--) {\n const currentType = newContext[i]?.getType() ?? '';\n if (\n Array.isArray(startType)\n ? startType.includes(currentType)\n : currentType === startType\n ) {\n requiredTypeIndex = i + 1;\n break;\n }\n const originalIndex = originalLength - 1 - i;\n totalTokens += indexTokenCountMap[originalIndex] ?? 0;\n }\n\n if (requiredTypeIndex > 0) {\n currentTokenCount -= totalTokens;\n newContext = newContext.slice(0, requiredTypeIndex);\n }\n }\n\n if (firstMessageType === 'ai') {\n const newMessage = addThinkingBlock(firstMessage, thinkingBlock);\n newContext[newContext.length - 1] = newMessage;\n } else {\n newContext.push(thinkingMessage);\n }\n\n if (instructions && originalLength > 0) {\n newContext.push(_messages[0] as BaseMessage);\n secondRoundMessages.shift();\n }\n\n result.context = newContext.reverse();\n return result;\n}\n\nexport function checkValidNumber(value: unknown): value is number {\n return typeof value === 'number' && !isNaN(value) && value > 0;\n}\n\ntype ThinkingBlocks = {\n thinking_blocks?: Array<{\n type: 'thinking';\n thinking: string;\n signature: string;\n }>;\n};\n\nexport function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {\n const indexTokenCountMap = { ...factoryParams.indexTokenCountMap };\n let lastTurnStartIndex = factoryParams.startIndex;\n let lastCutOffIndex = 0;\n let totalTokens = Object.values(indexTokenCountMap).reduce(\n (a = 0, b = 0) => a + b,\n 0\n ) as number;\n let runThinkingStartIndex = -1;\n return function pruneMessages(params: PruneMessagesParams): {\n context: BaseMessage[];\n indexTokenCountMap: Record<string, number | undefined>;\n } {\n if (\n factoryParams.provider === Providers.OPENAI &&\n factoryParams.thinkingEnabled === true\n ) {\n for (let i = lastTurnStartIndex; i < params.messages.length; i++) {\n const m = params.messages[i];\n if (\n m.getType() === 'ai' &&\n typeof m.additional_kwargs.reasoning_content === 'string' &&\n Array.isArray(\n (\n m.additional_kwargs.provider_specific_fields as\n | ThinkingBlocks\n | undefined\n )?.thinking_blocks\n ) &&\n (m as AIMessage).tool_calls &&\n ((m as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n const message = m as AIMessage;\n const thinkingBlocks = (\n message.additional_kwargs.provider_specific_fields as ThinkingBlocks\n ).thinking_blocks;\n const signature =\n thinkingBlocks?.[thinkingBlocks.length - 1].signature;\n const thinkingBlock: ThinkingContentText = {\n signature,\n type: ContentTypes.THINKING,\n thinking: message.additional_kwargs.reasoning_content as string,\n };\n\n params.messages[i] = new AIMessage({\n ...message,\n content: [thinkingBlock],\n additional_kwargs: {\n ...message.additional_kwargs,\n reasoning_content: undefined,\n },\n });\n }\n }\n }\n\n let currentUsage: UsageMetadata | undefined;\n if (\n params.usageMetadata &&\n (checkValidNumber(params.usageMetadata.input_tokens) ||\n (checkValidNumber(params.usageMetadata.input_token_details) &&\n (checkValidNumber(\n params.usageMetadata.input_token_details.cache_creation\n ) ||\n checkValidNumber(\n params.usageMetadata.input_token_details.cache_read\n )))) &&\n checkValidNumber(params.usageMetadata.output_tokens)\n ) {\n currentUsage = calculateTotalTokens(params.usageMetadata);\n totalTokens = currentUsage.total_tokens;\n }\n\n const newOutputs = new Set<number>();\n for (let i = lastTurnStartIndex; i < params.messages.length; i++) {\n const message = params.messages[i];\n if (\n i === lastTurnStartIndex &&\n indexTokenCountMap[i] === undefined &&\n currentUsage\n ) {\n indexTokenCountMap[i] = currentUsage.output_tokens;\n } else if (indexTokenCountMap[i] === undefined) {\n indexTokenCountMap[i] = factoryParams.tokenCounter(message);\n if (currentUsage) {\n newOutputs.add(i);\n }\n totalTokens += indexTokenCountMap[i] ?? 0;\n }\n }\n\n // If `currentUsage` is defined, we need to distribute the current total tokens to our `indexTokenCountMap`,\n // We must distribute it in a weighted manner, so that the total token count is equal to `currentUsage.total_tokens`,\n // relative the manually counted tokens in `indexTokenCountMap`.\n // EDGE CASE: when the resulting context gets pruned, we should not distribute the usage for messages that are not in the context.\n if (currentUsage) {\n let totalIndexTokens = 0;\n if (params.messages[0].getType() === 'system') {\n totalIndexTokens += indexTokenCountMap[0] ?? 0;\n }\n for (let i = lastCutOffIndex; i < params.messages.length; i++) {\n if (i === 0 && params.messages[0].getType() === 'system') {\n continue;\n }\n if (newOutputs.has(i)) {\n continue;\n }\n totalIndexTokens += indexTokenCountMap[i] ?? 0;\n }\n\n // Calculate ratio based only on messages that remain in the context\n const ratio = currentUsage.total_tokens / totalIndexTokens;\n const isRatioSafe = ratio >= 1 / 3 && ratio <= 2.5;\n\n // Apply the ratio adjustment only to messages at or after lastCutOffIndex, and only if the ratio is safe\n if (isRatioSafe) {\n if (\n params.messages[0].getType() === 'system' &&\n lastCutOffIndex !== 0\n ) {\n indexTokenCountMap[0] = Math.round(\n (indexTokenCountMap[0] ?? 0) * ratio\n );\n }\n\n for (let i = lastCutOffIndex; i < params.messages.length; i++) {\n if (newOutputs.has(i)) {\n continue;\n }\n indexTokenCountMap[i] = Math.round(\n (indexTokenCountMap[i] ?? 0) * ratio\n );\n }\n }\n }\n\n lastTurnStartIndex = params.messages.length;\n if (lastCutOffIndex === 0 && totalTokens <= factoryParams.maxTokens) {\n return { context: params.messages, indexTokenCountMap };\n }\n\n const { context, thinkingStartIndex } = getMessagesWithinTokenLimit({\n maxContextTokens: factoryParams.maxTokens,\n messages: params.messages,\n indexTokenCountMap,\n startType: params.startType,\n thinkingEnabled: factoryParams.thinkingEnabled,\n tokenCounter: factoryParams.tokenCounter,\n reasoningType:\n factoryParams.provider === Providers.BEDROCK\n ? ContentTypes.REASONING_CONTENT\n : ContentTypes.THINKING,\n thinkingStartIndex:\n factoryParams.thinkingEnabled === true\n ? runThinkingStartIndex\n : undefined,\n });\n runThinkingStartIndex = thinkingStartIndex ?? -1;\n /** The index is the first value of `context`, index relative to `params.messages` */\n lastCutOffIndex = Math.max(\n params.messages.length -\n (context.length - (context[0]?.getType() === 'system' ? 1 : 0)),\n 0\n );\n\n return { context, indexTokenCountMap };\n };\n}\n"],"names":["ContentTypes","AIMessage","messages","Providers"],"mappings":"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"}
1
+ {"version":3,"file":"prune.cjs","sources":["../../../src/messages/prune.ts"],"sourcesContent":["import {\n AIMessage,\n BaseMessage,\n ToolMessage,\n UsageMetadata,\n} from '@langchain/core/messages';\nimport type {\n ThinkingContentText,\n MessageContentComplex,\n ReasoningContentText,\n} from '@/types/stream';\nimport type { TokenCounter } from '@/types/run';\nimport type { ContextPruningConfig } from '@/types/graph';\nimport {\n calculateMaxToolResultChars,\n truncateToolResultContent,\n truncateToolInput,\n} from '@/utils/truncation';\nimport { resolveContextPruningSettings } from './contextPruningSettings';\nimport { ContentTypes, Providers, Constants } from '@/common';\nimport { applyContextPruning } from './contextPruning';\n\nfunction sumTokenCounts(\n tokenMap: Record<string, number | undefined>,\n count: number\n): number {\n let total = 0;\n for (let i = 0; i < count; i++) {\n total += tokenMap[i] ?? 0;\n }\n return total;\n}\n\n/** Default fraction of the token budget reserved as headroom (5 %). */\nexport const DEFAULT_RESERVE_RATIO = 0.05;\n\n/** Context pressure at which observation masking and context fading activate. */\nconst PRESSURE_THRESHOLD_MASKING = 0.8;\n\n/** Pressure band thresholds paired with budget factors for progressive context fading. */\nconst PRESSURE_BANDS: [number, number][] = [\n [0.99, 0.05],\n [0.9, 0.2],\n [0.85, 0.5],\n [0.8, 1.0],\n];\n\n/** Maximum character length for masked (consumed) tool results. */\nconst MASKED_RESULT_MAX_CHARS = 300;\n\n/** Hard cap for the originalToolContent store (~2 MB estimated from char length). */\nconst ORIGINAL_CONTENT_MAX_CHARS = 2_000_000;\n\n/** Minimum cumulative calibration ratio — provider can't count fewer tokens\n * than our raw estimate (within reason). Prevents divide-by-zero edge cases. */\nconst CALIBRATION_RATIO_MIN = 0.5;\n\n/** Maximum cumulative calibration ratio — sanity cap for the running ratio. */\nconst CALIBRATION_RATIO_MAX = 5;\n\nexport type PruneMessagesFactoryParams = {\n provider?: Providers;\n maxTokens: number;\n startIndex: number;\n tokenCounter: TokenCounter;\n indexTokenCountMap: Record<string, number | undefined>;\n thinkingEnabled?: boolean;\n /** Context pruning configuration for position-based tool result degradation. */\n contextPruningConfig?: ContextPruningConfig;\n /**\n * When true, context pressure fading (pre-flight tool result truncation)\n * is skipped. Summarization replaces pruning as the primary context\n * management strategy — the summarizer needs full un-truncated tool results\n * to produce an accurate summary. Hard pruning still runs as a fallback\n * when summarization is skipped or capped.\n */\n summarizationEnabled?: boolean;\n /**\n * Returns the current instruction-token overhead (system message + tool schemas + summary).\n * Called on each prune invocation so the budget reflects dynamic changes\n * (e.g. summary added between turns). When messages don't include a leading\n * SystemMessage, these tokens are subtracted from the available budget so\n * the pruner correctly reserves space for the system prompt that will be\n * prepended later by `buildSystemRunnable`.\n */\n getInstructionTokens?: () => number;\n /**\n * Fraction of the effective token budget to reserve as headroom (0–1).\n * When set, pruning triggers at `effectiveMax * (1 - reserveRatio)` instead of\n * filling the context window to 100%. Defaults to 5 % (0.05) when omitted.\n */\n reserveRatio?: number;\n /**\n * Initial calibration ratio from a previous run's persisted contextMeta.\n * Seeds the running EMA so new messages are scaled immediately instead\n * of waiting for the first provider response. Ignored when <= 0.\n */\n calibrationRatio?: number;\n /** Optional diagnostic log callback wired by the graph for observability. */\n log?: (\n level: 'debug' | 'info' | 'warn' | 'error',\n message: string,\n data?: Record<string, unknown>\n ) => void;\n};\nexport type PruneMessagesParams = {\n messages: BaseMessage[];\n usageMetadata?: Partial<UsageMetadata>;\n startType?: ReturnType<BaseMessage['getType']>;\n /**\n * Usage from the most recent LLM call only (not accumulated).\n * When provided, calibration uses this instead of usageMetadata\n * to avoid inflated ratios from N×cacheRead accumulation.\n */\n lastCallUsage?: {\n totalTokens: number;\n inputTokens?: number;\n };\n /**\n * Whether the token data is fresh (from a just-completed LLM call).\n * When false, provider calibration is skipped to avoid applying\n * stale ratios.\n */\n totalTokensFresh?: boolean;\n};\n\nfunction getToolCallIds(message: BaseMessage): Set<string> {\n if (message.getType() !== 'ai') {\n return new Set<string>();\n }\n\n const ids = new Set<string>();\n const aiMessage = message as AIMessage;\n for (const toolCall of aiMessage.tool_calls ?? []) {\n if (typeof toolCall.id === 'string' && toolCall.id.length > 0) {\n ids.add(toolCall.id);\n }\n }\n\n if (Array.isArray(aiMessage.content)) {\n for (const part of aiMessage.content) {\n if (typeof part !== 'object') {\n continue;\n }\n const record = part as { type?: unknown; id?: unknown };\n if (\n (record.type === 'tool_use' || record.type === 'tool_call') &&\n typeof record.id === 'string' &&\n record.id.length > 0\n ) {\n ids.add(record.id);\n }\n }\n }\n\n return ids;\n}\n\nfunction getToolResultId(message: BaseMessage): string | null {\n if (message.getType() !== 'tool') {\n return null;\n }\n const toolMessage = message as ToolMessage & {\n tool_call_id?: unknown;\n toolCallId?: unknown;\n };\n if (\n typeof toolMessage.tool_call_id === 'string' &&\n toolMessage.tool_call_id.length > 0\n ) {\n return toolMessage.tool_call_id;\n }\n if (\n typeof toolMessage.toolCallId === 'string' &&\n toolMessage.toolCallId.length > 0\n ) {\n return toolMessage.toolCallId;\n }\n return null;\n}\n\nfunction resolveTokenCountForMessage({\n message,\n messageIndexMap,\n tokenCounter,\n indexTokenCountMap,\n}: {\n message: BaseMessage;\n messageIndexMap: Map<BaseMessage, number>;\n tokenCounter: TokenCounter;\n indexTokenCountMap: Record<string, number | undefined>;\n}): number {\n const originalIndex = messageIndexMap.get(message) ?? -1;\n if (originalIndex > -1 && indexTokenCountMap[originalIndex] != null) {\n return indexTokenCountMap[originalIndex] as number;\n }\n return tokenCounter(message);\n}\n\nexport function repairOrphanedToolMessages({\n context,\n allMessages,\n tokenCounter,\n indexTokenCountMap,\n}: {\n context: BaseMessage[];\n allMessages: BaseMessage[];\n tokenCounter: TokenCounter;\n indexTokenCountMap: Record<string, number | undefined>;\n}): {\n context: BaseMessage[];\n reclaimedTokens: number;\n droppedOrphanCount: number;\n /** Messages removed from context during orphan repair. These should be\n * appended to `messagesToRefine` so that summarization can still see them\n * (e.g. a ToolMessage whose parent AI was pruned). */\n droppedMessages: BaseMessage[];\n} {\n const messageIndexMap = new Map<BaseMessage, number>();\n for (let i = 0; i < allMessages.length; i++) {\n messageIndexMap.set(allMessages[i], i);\n }\n\n const validToolCallIds = new Set<string>();\n const presentToolResultIds = new Set<string>();\n for (const message of context) {\n for (const id of getToolCallIds(message)) {\n validToolCallIds.add(id);\n }\n const resultId = getToolResultId(message);\n if (resultId != null) {\n presentToolResultIds.add(resultId);\n }\n }\n\n let reclaimedTokens = 0;\n let droppedOrphanCount = 0;\n const repairedContext: BaseMessage[] = [];\n const droppedMessages: BaseMessage[] = [];\n\n for (const message of context) {\n if (message.getType() === 'tool') {\n const toolResultId = getToolResultId(message);\n if (toolResultId == null || !validToolCallIds.has(toolResultId)) {\n droppedOrphanCount += 1;\n reclaimedTokens += resolveTokenCountForMessage({\n message,\n tokenCounter,\n messageIndexMap,\n indexTokenCountMap,\n });\n droppedMessages.push(message);\n continue;\n }\n repairedContext.push(message);\n continue;\n }\n\n if (message.getType() === 'ai' && message instanceof AIMessage) {\n const toolCallIds = getToolCallIds(message);\n if (toolCallIds.size > 0) {\n let hasOrphanToolCalls = false;\n for (const id of toolCallIds) {\n if (!presentToolResultIds.has(id)) {\n hasOrphanToolCalls = true;\n break;\n }\n }\n if (hasOrphanToolCalls) {\n const originalTokens = resolveTokenCountForMessage({\n message,\n messageIndexMap,\n tokenCounter,\n indexTokenCountMap,\n });\n const stripped = stripOrphanToolUseBlocks(\n message,\n presentToolResultIds\n );\n if (stripped != null) {\n const strippedTokens = tokenCounter(stripped);\n reclaimedTokens += originalTokens - strippedTokens;\n repairedContext.push(stripped);\n } else {\n droppedOrphanCount += 1;\n reclaimedTokens += originalTokens;\n droppedMessages.push(message);\n }\n continue;\n }\n }\n }\n\n repairedContext.push(message);\n }\n\n return {\n context: repairedContext,\n reclaimedTokens,\n droppedOrphanCount,\n droppedMessages,\n };\n}\n\n/**\n * Strips tool_use content blocks and tool_calls entries from an AI message\n * when their corresponding ToolMessages are not in the context.\n * Returns null if the message has no content left after stripping.\n */\nfunction stripOrphanToolUseBlocks(\n message: AIMessage,\n presentToolResultIds: Set<string>\n): AIMessage | null {\n const keptToolCalls = (message.tool_calls ?? []).filter(\n (tc) => typeof tc.id === 'string' && presentToolResultIds.has(tc.id)\n );\n\n let keptContent: MessageContentComplex[] | string;\n if (Array.isArray(message.content)) {\n const filtered = (message.content as MessageContentComplex[]).filter(\n (block) => {\n if (typeof block !== 'object') {\n return true;\n }\n const record = block as { type?: unknown; id?: unknown };\n if (\n (record.type === 'tool_use' || record.type === 'tool_call') &&\n typeof record.id === 'string'\n ) {\n return presentToolResultIds.has(record.id);\n }\n return true;\n }\n );\n\n if (filtered.length === 0) {\n return null;\n }\n keptContent = filtered;\n } else {\n keptContent = message.content;\n }\n\n return new AIMessage({\n ...message,\n content: keptContent,\n tool_calls: keptToolCalls.length > 0 ? keptToolCalls : undefined,\n });\n}\n\n/**\n * Lightweight structural cleanup: strips orphan tool_use blocks from AI messages\n * and drops orphan ToolMessages whose AI counterpart is missing.\n *\n * Unlike `repairOrphanedToolMessages`, this does NOT track tokens — it is\n * intended as a final safety net in Graph.ts right before model invocation\n * to prevent Anthropic/Bedrock structural validation errors.\n *\n * Uses duck-typing instead of `getType()` because messages at this stage\n * may be plain objects (from LangGraph state serialization) rather than\n * proper BaseMessage class instances.\n *\n * Includes a fast-path: if every tool_call has a matching tool_result and\n * vice-versa, the original array is returned immediately with zero allocation.\n */\nexport function sanitizeOrphanToolBlocks(\n messages: BaseMessage[]\n): BaseMessage[] {\n const allToolCallIds = new Set<string>();\n const allToolResultIds = new Set<string>();\n\n for (const msg of messages) {\n const msgAny = msg as unknown as Record<string, unknown>;\n const toolCalls = msgAny.tool_calls as Array<{ id?: string }> | undefined;\n if (Array.isArray(toolCalls)) {\n for (const tc of toolCalls) {\n if (\n typeof tc.id === 'string' &&\n tc.id.length > 0 &&\n !tc.id.startsWith(Constants.ANTHROPIC_SERVER_TOOL_PREFIX)\n ) {\n allToolCallIds.add(tc.id);\n }\n }\n }\n if (Array.isArray(msgAny.content)) {\n for (const block of msgAny.content as Array<Record<string, unknown>>) {\n if (\n typeof block === 'object' &&\n (block.type === 'tool_use' || block.type === 'tool_call') &&\n typeof block.id === 'string' &&\n !block.id.startsWith(Constants.ANTHROPIC_SERVER_TOOL_PREFIX)\n ) {\n allToolCallIds.add(block.id);\n }\n }\n }\n const toolCallId = msgAny.tool_call_id as string | undefined;\n if (typeof toolCallId === 'string' && toolCallId.length > 0) {\n allToolResultIds.add(toolCallId);\n }\n }\n\n let hasOrphans = false;\n for (const id of allToolCallIds) {\n if (!allToolResultIds.has(id)) {\n hasOrphans = true;\n break;\n }\n }\n if (!hasOrphans) {\n for (const id of allToolResultIds) {\n if (!allToolCallIds.has(id)) {\n hasOrphans = true;\n break;\n }\n }\n }\n if (!hasOrphans) {\n return messages;\n }\n\n const result: BaseMessage[] = [];\n const strippedAiIndices = new Set<number>();\n\n for (const msg of messages) {\n const msgAny = msg as unknown as Record<string, unknown>;\n const msgType =\n typeof (msg as { getType?: unknown }).getType === 'function'\n ? msg.getType()\n : ((msgAny.role as string | undefined) ??\n (msgAny._type as string | undefined));\n\n const toolCallId = msgAny.tool_call_id as string | undefined;\n if (\n (msgType === 'tool' || msg instanceof ToolMessage) &&\n typeof toolCallId === 'string' &&\n !allToolCallIds.has(toolCallId)\n ) {\n continue;\n }\n\n const toolCalls = msgAny.tool_calls as Array<{ id?: string }> | undefined;\n if (\n (msgType === 'ai' ||\n msgType === 'assistant' ||\n msg instanceof AIMessage) &&\n Array.isArray(toolCalls) &&\n toolCalls.length > 0\n ) {\n const hasOrphanCalls = toolCalls.some(\n (tc) => typeof tc.id === 'string' && !allToolResultIds.has(tc.id)\n );\n if (hasOrphanCalls) {\n if (msg instanceof AIMessage) {\n const stripped = stripOrphanToolUseBlocks(msg, allToolResultIds);\n if (stripped != null) {\n strippedAiIndices.add(result.length);\n result.push(stripped);\n }\n continue;\n }\n const keptToolCalls = toolCalls.filter(\n (tc) => typeof tc.id === 'string' && allToolResultIds.has(tc.id)\n );\n const keptContent = Array.isArray(msgAny.content)\n ? (msgAny.content as Array<Record<string, unknown>>).filter(\n (block) => {\n if (typeof block !== 'object') return true;\n if (\n (block.type === 'tool_use' || block.type === 'tool_call') &&\n typeof block.id === 'string'\n ) {\n return allToolResultIds.has(block.id);\n }\n return true;\n }\n )\n : msgAny.content;\n if (\n keptToolCalls.length === 0 &&\n Array.isArray(keptContent) &&\n keptContent.length === 0\n ) {\n continue;\n }\n strippedAiIndices.add(result.length);\n const patched = Object.create(\n Object.getPrototypeOf(msg),\n Object.getOwnPropertyDescriptors(msg)\n );\n patched.tool_calls = keptToolCalls.length > 0 ? keptToolCalls : [];\n patched.content = keptContent;\n result.push(patched as BaseMessage);\n continue;\n }\n }\n\n result.push(msg);\n }\n\n // Bedrock/Anthropic require the conversation to end with a user message;\n // a stripped AI message (tool_use removed) represents a dead-end exchange.\n while (result.length > 0 && strippedAiIndices.has(result.length - 1)) {\n result.pop();\n }\n\n return result;\n}\n\n/**\n * Truncates an oversized tool_use `input` field using head+tail, preserving\n * it as a valid JSON object. Head gets ~70%, tail gets ~30% so the model\n * sees both the beginning (what was called) and end (closing structure/values).\n * Falls back to head-only when the budget is too small for a meaningful tail.\n */\nfunction isIndexInContext(\n arrayA: unknown[],\n arrayB: unknown[],\n targetIndex: number\n): boolean {\n const startingIndexInA = arrayA.length - arrayB.length;\n return targetIndex >= startingIndexInA;\n}\n\nfunction addThinkingBlock(\n message: AIMessage,\n thinkingBlock: ThinkingContentText | ReasoningContentText\n): AIMessage {\n const content: MessageContentComplex[] = Array.isArray(message.content)\n ? (message.content as MessageContentComplex[])\n : [\n {\n type: ContentTypes.TEXT,\n text: message.content,\n },\n ];\n /** Edge case, the message already has the thinking block */\n if (content[0].type === thinkingBlock.type) {\n return message;\n }\n content.unshift(thinkingBlock);\n return new AIMessage({\n ...message,\n content,\n });\n}\n\n/**\n * Calculates the total tokens from a single usage object\n *\n * @param usage The usage metadata object containing token information\n * @returns An object containing the total input and output tokens\n */\nexport function calculateTotalTokens(\n usage: Partial<UsageMetadata>\n): UsageMetadata {\n const baseInputTokens = Number(usage.input_tokens) || 0;\n const cacheCreation = Number(usage.input_token_details?.cache_creation) || 0;\n const cacheRead = Number(usage.input_token_details?.cache_read) || 0;\n const totalOutputTokens = Number(usage.output_tokens) || 0;\n const cacheSum = cacheCreation + cacheRead;\n // Anthropic: input_tokens excludes cache, cache_read can be much larger than input_tokens.\n // OpenAI: input_tokens includes cache, cache_read is always <= input_tokens.\n const cacheIsAdditive = cacheSum > 0 && cacheSum > baseInputTokens;\n const totalInputTokens = cacheIsAdditive\n ? baseInputTokens + cacheSum\n : baseInputTokens;\n\n return {\n input_tokens: totalInputTokens,\n output_tokens: totalOutputTokens,\n total_tokens: totalInputTokens + totalOutputTokens,\n };\n}\n\nexport type PruningResult = {\n context: BaseMessage[];\n remainingContextTokens: number;\n messagesToRefine: BaseMessage[];\n thinkingStartIndex?: number;\n};\n\n/**\n * Processes an array of messages and returns a context of messages that fit within a specified token limit.\n * It iterates over the messages from newest to oldest, adding them to the context until the token limit is reached.\n *\n * @param options Configuration options for processing messages\n * @returns Object containing the message context, remaining tokens, messages not included, and summary index\n */\nexport function getMessagesWithinTokenLimit({\n messages: _messages,\n maxContextTokens,\n indexTokenCountMap,\n startType: _startType,\n thinkingEnabled,\n tokenCounter,\n thinkingStartIndex: _thinkingStartIndex = -1,\n reasoningType = ContentTypes.THINKING,\n instructionTokens: _instructionTokens = 0,\n}: {\n messages: BaseMessage[];\n maxContextTokens: number;\n indexTokenCountMap: Record<string, number | undefined>;\n startType?: string | string[];\n thinkingEnabled?: boolean;\n tokenCounter: TokenCounter;\n thinkingStartIndex?: number;\n reasoningType?: ContentTypes.THINKING | ContentTypes.REASONING_CONTENT;\n /**\n * Token overhead for instructions (system message + tool schemas + summary)\n * that are NOT included in `messages`. When messages[0] is already a\n * SystemMessage the budget is deducted from its indexTokenCountMap entry\n * as before; otherwise this value is subtracted from the available budget.\n */\n instructionTokens?: number;\n}): PruningResult {\n // Every reply is primed with <|start|>assistant<|message|>, so we\n // start with 3 tokens for the label after all messages have been counted.\n let currentTokenCount = 3;\n const instructions =\n _messages[0]?.getType() === 'system' ? _messages[0] : undefined;\n const instructionsTokenCount =\n instructions != null ? (indexTokenCountMap[0] ?? 0) : _instructionTokens;\n const initialContextTokens = maxContextTokens - instructionsTokenCount;\n let remainingContextTokens = initialContextTokens;\n let startType = _startType;\n const originalLength = _messages.length;\n const messages = [..._messages];\n /**\n * IMPORTANT: this context array gets reversed at the end, since the latest messages get pushed first.\n *\n * This may be confusing to read, but it is done to ensure the context is in the correct order for the model.\n * */\n let context: Array<BaseMessage | undefined> = [];\n\n let thinkingStartIndex = _thinkingStartIndex;\n let thinkingEndIndex = -1;\n let thinkingBlock: ThinkingContentText | ReasoningContentText | undefined;\n const endIndex = instructions != null ? 1 : 0;\n const prunedMemory: BaseMessage[] = [];\n\n if (_thinkingStartIndex > -1) {\n const thinkingMessageContent = messages[_thinkingStartIndex]?.content;\n if (Array.isArray(thinkingMessageContent)) {\n thinkingBlock = thinkingMessageContent.find(\n (content) => content.type === reasoningType\n ) as ThinkingContentText | undefined;\n }\n }\n\n if (currentTokenCount < remainingContextTokens) {\n let currentIndex = messages.length;\n while (\n messages.length > 0 &&\n currentTokenCount < remainingContextTokens &&\n currentIndex > endIndex\n ) {\n currentIndex--;\n if (messages.length === 1 && instructions) {\n break;\n }\n const poppedMessage = messages.pop();\n if (!poppedMessage) continue;\n const messageType = poppedMessage.getType();\n if (\n thinkingEnabled === true &&\n thinkingEndIndex === -1 &&\n currentIndex === originalLength - 1 &&\n (messageType === 'ai' || messageType === 'tool')\n ) {\n thinkingEndIndex = currentIndex;\n }\n if (\n thinkingEndIndex > -1 &&\n !thinkingBlock &&\n thinkingStartIndex < 0 &&\n messageType === 'ai' &&\n Array.isArray(poppedMessage.content)\n ) {\n thinkingBlock = poppedMessage.content.find(\n (content) => content.type === reasoningType\n ) as ThinkingContentText | undefined;\n thinkingStartIndex = thinkingBlock != null ? currentIndex : -1;\n }\n /** False start, the latest message was not part of a multi-assistant/tool sequence of messages */\n if (\n thinkingEndIndex > -1 &&\n currentIndex === thinkingEndIndex - 1 &&\n messageType !== 'ai' &&\n messageType !== 'tool'\n ) {\n thinkingEndIndex = -1;\n }\n\n const tokenCount = indexTokenCountMap[currentIndex] ?? 0;\n\n if (\n prunedMemory.length === 0 &&\n currentTokenCount + tokenCount <= remainingContextTokens\n ) {\n context.push(poppedMessage);\n currentTokenCount += tokenCount;\n } else {\n prunedMemory.push(poppedMessage);\n if (thinkingEndIndex > -1 && thinkingStartIndex < 0) {\n continue;\n }\n break;\n }\n }\n\n if (context[context.length - 1]?.getType() === 'tool') {\n startType = ['ai', 'human'];\n }\n\n if (startType != null && startType.length > 0 && context.length > 0) {\n let requiredTypeIndex = -1;\n\n let totalTokens = 0;\n for (let i = context.length - 1; i >= 0; i--) {\n const currentType = context[i]?.getType() ?? '';\n if (\n Array.isArray(startType)\n ? startType.includes(currentType)\n : currentType === startType\n ) {\n requiredTypeIndex = i + 1;\n break;\n }\n const originalIndex = originalLength - 1 - i;\n totalTokens += indexTokenCountMap[originalIndex] ?? 0;\n }\n\n if (requiredTypeIndex > 0) {\n currentTokenCount -= totalTokens;\n context = context.slice(0, requiredTypeIndex);\n }\n }\n }\n\n if (instructions && originalLength > 0) {\n context.push(_messages[0] as BaseMessage);\n messages.shift();\n }\n\n // The backward iteration pushed messages in reverse chronological order\n // (newest first). Restore correct chronological order before prepending\n // the remaining (older) messages so that messagesToRefine is always\n // ordered oldest → newest. Without this, callers that rely on\n // messagesToRefine order (e.g. the summarization node extracting the\n // latest turn) would see tool_use/tool_result pairs in the wrong order.\n prunedMemory.reverse();\n\n if (messages.length > 0) {\n prunedMemory.unshift(...messages);\n }\n\n remainingContextTokens -= currentTokenCount;\n const result: PruningResult = {\n remainingContextTokens,\n context: [] as BaseMessage[],\n messagesToRefine: prunedMemory,\n };\n\n if (thinkingStartIndex > -1) {\n result.thinkingStartIndex = thinkingStartIndex;\n }\n\n if (\n prunedMemory.length === 0 ||\n thinkingEndIndex < 0 ||\n (thinkingStartIndex > -1 &&\n isIndexInContext(_messages, context, thinkingStartIndex))\n ) {\n result.context = context.reverse() as BaseMessage[];\n return result;\n }\n\n if (thinkingEndIndex > -1 && thinkingStartIndex < 0) {\n throw new Error(\n 'The payload is malformed. There is a thinking sequence but no \"AI\" messages with thinking blocks.'\n );\n }\n\n if (!thinkingBlock) {\n throw new Error(\n 'The payload is malformed. There is a thinking sequence but no thinking block found.'\n );\n }\n\n let assistantIndex = -1;\n for (let i = 0; i < context.length; i++) {\n const currentMessage = context[i];\n const type = currentMessage?.getType();\n if (type === 'ai') {\n assistantIndex = i;\n }\n if (assistantIndex > -1 && (type === 'human' || type === 'system')) {\n break;\n }\n }\n\n if (assistantIndex === -1) {\n // No AI messages survived pruning — skip thinking block reattachment.\n // The caller handles empty/insufficient context via overflow recovery.\n result.context = context.reverse() as BaseMessage[];\n return result;\n }\n\n thinkingStartIndex = originalLength - 1 - assistantIndex;\n const thinkingTokenCount = tokenCounter(\n new AIMessage({ content: [thinkingBlock] })\n );\n const newRemainingCount = remainingContextTokens - thinkingTokenCount;\n const newMessage = addThinkingBlock(\n context[assistantIndex] as AIMessage,\n thinkingBlock\n );\n context[assistantIndex] = newMessage;\n if (newRemainingCount > 0) {\n result.context = context.reverse() as BaseMessage[];\n return result;\n }\n\n const thinkingMessage: AIMessage = context[assistantIndex] as AIMessage;\n const newThinkingMessageTokenCount =\n (indexTokenCountMap[thinkingStartIndex] ?? 0) + thinkingTokenCount;\n remainingContextTokens = initialContextTokens - newThinkingMessageTokenCount;\n currentTokenCount = 3;\n let newContext: BaseMessage[] = [];\n const secondRoundMessages = [..._messages];\n let currentIndex = secondRoundMessages.length;\n while (\n secondRoundMessages.length > 0 &&\n currentTokenCount < remainingContextTokens &&\n currentIndex > thinkingStartIndex\n ) {\n currentIndex--;\n const poppedMessage = secondRoundMessages.pop();\n if (!poppedMessage) continue;\n const tokenCount = indexTokenCountMap[currentIndex] ?? 0;\n if (currentTokenCount + tokenCount <= remainingContextTokens) {\n newContext.push(poppedMessage);\n currentTokenCount += tokenCount;\n } else {\n messages.push(poppedMessage);\n break;\n }\n }\n\n const firstMessage: AIMessage = newContext[newContext.length - 1];\n const firstMessageType = newContext[newContext.length - 1].getType();\n if (firstMessageType === 'tool') {\n startType = ['ai', 'human'];\n }\n\n if (startType != null && startType.length > 0 && newContext.length > 0) {\n let requiredTypeIndex = -1;\n\n let totalTokens = 0;\n for (let i = newContext.length - 1; i >= 0; i--) {\n const currentType = newContext[i]?.getType() ?? '';\n if (\n Array.isArray(startType)\n ? startType.includes(currentType)\n : currentType === startType\n ) {\n requiredTypeIndex = i + 1;\n break;\n }\n const originalIndex = originalLength - 1 - i;\n totalTokens += indexTokenCountMap[originalIndex] ?? 0;\n }\n\n if (requiredTypeIndex > 0) {\n currentTokenCount -= totalTokens;\n newContext = newContext.slice(0, requiredTypeIndex);\n }\n }\n\n if (firstMessageType === 'ai') {\n const newMessage = addThinkingBlock(firstMessage, thinkingBlock);\n newContext[newContext.length - 1] = newMessage;\n } else {\n newContext.push(thinkingMessage);\n }\n\n if (instructions && originalLength > 0) {\n newContext.push(_messages[0] as BaseMessage);\n secondRoundMessages.shift();\n }\n\n result.context = newContext.reverse();\n return result;\n}\n\nexport function checkValidNumber(value: unknown): value is number {\n return typeof value === 'number' && !isNaN(value) && value > 0;\n}\n\n/**\n * Observation masking: replaces consumed ToolMessage content with tight\n * head+tail truncations that serve as informative placeholders.\n *\n * A ToolMessage is \"consumed\" when a subsequent AI message exists that is NOT\n * purely tool calls — meaning the model has already read and acted on the\n * result. Unconsumed results (the latest tool outputs the model hasn't\n * responded to yet) are left intact so the model can still use them.\n *\n * AI messages are never masked — they contain the model's own reasoning and\n * conclusions, which is what prevents the model from repeating work after\n * its tool results are masked.\n *\n * @returns The number of tool messages that were masked.\n */\nexport function maskConsumedToolResults(params: {\n messages: BaseMessage[];\n indexTokenCountMap: Record<string, number | undefined>;\n tokenCounter: TokenCounter;\n /** Raw-space token budget available for all consumed tool results combined.\n * When provided, the budget is distributed across consumed results weighted\n * by recency (newest get the most, oldest get MASKED_RESULT_MAX_CHARS min).\n * When omitted, falls back to a flat MASKED_RESULT_MAX_CHARS per result. */\n availableRawBudget?: number;\n /** When provided, original (pre-masking) content is stored here keyed by\n * message index — only for entries that actually get truncated. */\n originalContentStore?: Map<number, string>;\n /** Called after storing content with the char length of the stored entry. */\n onContentStored?: (charLength: number) => void;\n}): number {\n const { messages, indexTokenCountMap, tokenCounter } = params;\n let maskedCount = 0;\n\n // Pass 1 (backward): identify consumed tool message indices.\n // A ToolMessage is \"consumed\" once we've seen a subsequent AI message with\n // substantive text content (not just tool calls).\n // Collected in forward order (oldest first) for recency weighting.\n let seenNonToolCallAI = false;\n const consumedIndices: number[] = [];\n\n for (let i = messages.length - 1; i >= 0; i--) {\n const msg = messages[i];\n const type = msg.getType();\n\n if (type === 'ai') {\n const hasText =\n typeof msg.content === 'string'\n ? msg.content.trim().length > 0\n : Array.isArray(msg.content) &&\n msg.content.some(\n (b) =>\n typeof b === 'object' &&\n (b as Record<string, unknown>).type === 'text' &&\n typeof (b as Record<string, unknown>).text === 'string' &&\n ((b as Record<string, unknown>).text as string).trim().length >\n 0\n );\n if (hasText) {\n seenNonToolCallAI = true;\n }\n } else if (type === 'tool' && seenNonToolCallAI) {\n consumedIndices.push(i);\n }\n }\n\n if (consumedIndices.length === 0) {\n return 0;\n }\n\n consumedIndices.reverse();\n\n const totalBudgetChars =\n params.availableRawBudget != null && params.availableRawBudget > 0\n ? params.availableRawBudget * 4\n : 0;\n\n const count = consumedIndices.length;\n\n for (let c = 0; c < count; c++) {\n const i = consumedIndices[c];\n const message = messages[i];\n const content = message.content;\n if (typeof content !== 'string') {\n continue;\n }\n\n let maxChars: number;\n if (totalBudgetChars > 0) {\n const position = count > 1 ? c / (count - 1) : 1;\n const weight = 0.2 + 0.8 * position;\n const totalWeight = count > 1 ? 0.6 * count : 1;\n const share = (weight / totalWeight) * totalBudgetChars;\n maxChars = Math.max(MASKED_RESULT_MAX_CHARS, Math.floor(share));\n } else {\n maxChars = MASKED_RESULT_MAX_CHARS;\n }\n\n if (content.length <= maxChars) {\n continue;\n }\n\n if (params.originalContentStore && !params.originalContentStore.has(i)) {\n params.originalContentStore.set(i, content);\n if (params.onContentStored) {\n params.onContentStored(content.length);\n }\n }\n\n const cloned = new ToolMessage({\n content: truncateToolResultContent(content, maxChars),\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n maskedCount++;\n }\n\n return maskedCount;\n}\n\n/**\n * Pre-flight truncation: truncates oversized ToolMessage content before the\n * main backward-iteration pruning runs. Unlike the ingestion guard (which caps\n * at tool-execution time), pre-flight truncation applies per-turn based on the\n * current context window budget (which may have shrunk due to growing conversation).\n *\n * After truncation, recounts tokens via tokenCounter and updates indexTokenCountMap\n * so subsequent pruning works with accurate counts.\n *\n * @returns The number of tool messages that were truncated.\n */\nexport function preFlightTruncateToolResults(params: {\n messages: BaseMessage[];\n maxContextTokens: number;\n indexTokenCountMap: Record<string, number | undefined>;\n tokenCounter: TokenCounter;\n}): number {\n const { messages, maxContextTokens, indexTokenCountMap, tokenCounter } =\n params;\n const baseMaxChars = calculateMaxToolResultChars(maxContextTokens);\n let truncatedCount = 0;\n\n const toolIndices: number[] = [];\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].getType() === 'tool') {\n toolIndices.push(i);\n }\n }\n\n for (let t = 0; t < toolIndices.length; t++) {\n const i = toolIndices[t];\n const message = messages[i];\n const content = message.content;\n if (typeof content !== 'string') {\n continue;\n }\n\n const position = toolIndices.length > 1 ? t / (toolIndices.length - 1) : 1;\n const recencyFactor = 0.2 + 0.8 * position;\n const maxChars = Math.max(200, Math.floor(baseMaxChars * recencyFactor));\n\n if (content.length <= maxChars) {\n continue;\n }\n\n const truncated = truncateToolResultContent(content, maxChars);\n const cloned = new ToolMessage({\n content: truncated,\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n messages[i] = cloned;\n indexTokenCountMap[i] = tokenCounter(cloned);\n truncatedCount++;\n }\n\n return truncatedCount;\n}\n\n/**\n * Pre-flight truncation: truncates oversized `tool_use` input fields in AI messages.\n *\n * Tool call inputs (arguments) can be very large — e.g., code evaluation payloads from\n * MCP tools like chrome-devtools. Since these tool calls have already been executed,\n * the model only needs a summary of what was called, not the full arguments. Truncating\n * them before pruning can prevent entire messages from being dropped.\n *\n * Uses 15% of the context window (in estimated characters, ~4 chars/token) as the\n * per-input cap, capped at 200K chars.\n *\n * @returns The number of AI messages that had tool_use inputs truncated.\n */\nexport function preFlightTruncateToolCallInputs(params: {\n messages: BaseMessage[];\n maxContextTokens: number;\n indexTokenCountMap: Record<string, number | undefined>;\n tokenCounter: TokenCounter;\n}): number {\n const { messages, maxContextTokens, indexTokenCountMap, tokenCounter } =\n params;\n const maxInputChars = Math.min(\n Math.floor(maxContextTokens * 0.15) * 4,\n 200_000\n );\n let truncatedCount = 0;\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (message.getType() !== 'ai') {\n continue;\n }\n if (!Array.isArray(message.content)) {\n continue;\n }\n\n const originalContent = message.content as MessageContentComplex[];\n const state = { changed: false };\n const newContent = originalContent.map((block) => {\n if (typeof block !== 'object') {\n return block;\n }\n const record = block as Record<string, unknown>;\n if (record.type !== 'tool_use' && record.type !== 'tool_call') {\n return block;\n }\n\n const input = record.input;\n if (input == null) {\n return block;\n }\n const serialized =\n typeof input === 'string' ? input : JSON.stringify(input);\n if (serialized.length <= maxInputChars) {\n return block;\n }\n\n state.changed = true;\n // Replaces original input with { _truncated, _originalChars } —\n // safe because the tool call already executed in a prior turn.\n return {\n ...record,\n input: truncateToolInput(serialized, maxInputChars),\n };\n });\n\n if (!state.changed) {\n continue;\n }\n\n const aiMsg = message as AIMessage;\n const newToolCalls = (aiMsg.tool_calls ?? []).map((tc) => {\n const serializedArgs = JSON.stringify(tc.args);\n if (serializedArgs.length <= maxInputChars) {\n return tc;\n }\n // Replaces original args with { _truncated, _originalChars } —\n // safe because the tool call already executed in a prior turn.\n return {\n ...tc,\n args: truncateToolInput(serializedArgs, maxInputChars),\n };\n });\n\n messages[i] = new AIMessage({\n ...aiMsg,\n content: newContent,\n tool_calls: newToolCalls.length > 0 ? newToolCalls : undefined,\n });\n indexTokenCountMap[i] = tokenCounter(messages[i]);\n truncatedCount++;\n }\n\n return truncatedCount;\n}\n\ntype ThinkingBlocks = {\n thinking_blocks?: Array<{\n type: 'thinking';\n thinking: string;\n signature: string;\n }>;\n};\n\nexport function createPruneMessages(factoryParams: PruneMessagesFactoryParams) {\n const indexTokenCountMap = { ...factoryParams.indexTokenCountMap };\n let lastTurnStartIndex = factoryParams.startIndex;\n let lastCutOffIndex = 0;\n let totalTokens = 0;\n for (const key in indexTokenCountMap) {\n totalTokens += indexTokenCountMap[key] ?? 0;\n }\n let runThinkingStartIndex = -1;\n /** Cumulative raw tiktoken tokens we've sent to the provider (messages only,\n * excludes instruction overhead and new outputs not yet seen by provider). */\n let cumulativeRawSent = 0;\n /** Cumulative provider-reported message tokens (providerInput - instructionOverhead). */\n let cumulativeProviderReported = 0;\n /** Stable calibration ratio = cumulativeProviderReported / cumulativeRawSent.\n * Converges monotonically as data accumulates. Falls back to seeded value. */\n let calibrationRatio =\n factoryParams.calibrationRatio != null && factoryParams.calibrationRatio > 0\n ? factoryParams.calibrationRatio\n : 1;\n /** Best observed instruction overhead from a near-zero variance turn.\n * Self-seeds from provider observations within the run. */\n let bestInstructionOverhead: number | undefined;\n let bestVarianceAbs = Infinity;\n /** Local estimate at the time bestInstructionOverhead was observed.\n * Used to invalidate the cached overhead when instructions change\n * mid-run (e.g. tool discovery adds tools to the bound set). */\n let bestInstructionEstimate: number | undefined;\n /** Original (pre-masking) tool result content keyed by message index.\n * Allows the summarizer to see full tool outputs even after masking\n * has truncated them in the live message array. Cleared when the\n * pruner is recreated after summarization. */\n const originalToolContent = new Map<number, string>();\n let originalToolContentSize = 0;\n const contextPruningSettings = resolveContextPruningSettings(\n factoryParams.contextPruningConfig\n );\n\n return function pruneMessages(params: PruneMessagesParams): {\n context: BaseMessage[];\n indexTokenCountMap: Record<string, number | undefined>;\n messagesToRefine?: BaseMessage[];\n prePruneContextTokens?: number;\n remainingContextTokens?: number;\n contextPressure?: number;\n originalToolContent?: Map<number, string>;\n calibrationRatio?: number;\n resolvedInstructionOverhead?: number;\n } {\n if (params.messages.length === 0) {\n return {\n context: [],\n indexTokenCountMap,\n messagesToRefine: [],\n prePruneContextTokens: 0,\n remainingContextTokens: factoryParams.maxTokens,\n calibrationRatio,\n resolvedInstructionOverhead: bestInstructionOverhead,\n };\n }\n\n if (\n factoryParams.provider === Providers.OPENAI &&\n factoryParams.thinkingEnabled === true\n ) {\n for (let i = lastTurnStartIndex; i < params.messages.length; i++) {\n const m = params.messages[i];\n if (\n m.getType() === 'ai' &&\n typeof m.additional_kwargs.reasoning_content === 'string' &&\n Array.isArray(\n (\n m.additional_kwargs.provider_specific_fields as\n | ThinkingBlocks\n | undefined\n )?.thinking_blocks\n ) &&\n (m as AIMessage).tool_calls &&\n ((m as AIMessage).tool_calls?.length ?? 0) > 0\n ) {\n const message = m as AIMessage;\n const thinkingBlocks = (\n message.additional_kwargs.provider_specific_fields as ThinkingBlocks\n ).thinking_blocks;\n const signature =\n thinkingBlocks?.[thinkingBlocks.length - 1].signature;\n const thinkingBlock: ThinkingContentText = {\n signature,\n type: ContentTypes.THINKING,\n thinking: message.additional_kwargs.reasoning_content as string,\n };\n\n params.messages[i] = new AIMessage({\n ...message,\n content: [thinkingBlock],\n additional_kwargs: {\n ...message.additional_kwargs,\n reasoning_content: undefined,\n },\n });\n }\n }\n }\n\n let currentUsage: UsageMetadata | undefined;\n if (\n params.usageMetadata &&\n (checkValidNumber(params.usageMetadata.input_tokens) ||\n (checkValidNumber(params.usageMetadata.input_token_details) &&\n (checkValidNumber(\n params.usageMetadata.input_token_details.cache_creation\n ) ||\n checkValidNumber(\n params.usageMetadata.input_token_details.cache_read\n )))) &&\n checkValidNumber(params.usageMetadata.output_tokens)\n ) {\n currentUsage = calculateTotalTokens(params.usageMetadata);\n }\n\n const newOutputs = new Set<number>();\n let outputTokensAssigned = false;\n for (let i = lastTurnStartIndex; i < params.messages.length; i++) {\n const message = params.messages[i];\n if (indexTokenCountMap[i] !== undefined) {\n continue;\n }\n\n // Assign output_tokens to the first uncounted AI message — this is the\n // model's response. Previous code blindly targeted lastTurnStartIndex\n // which could hit a pre-counted HumanMessage or miss the AI entirely.\n if (!outputTokensAssigned && currentUsage && message.getType() === 'ai') {\n indexTokenCountMap[i] = currentUsage.output_tokens;\n newOutputs.add(i);\n outputTokensAssigned = true;\n } else {\n // Always store raw tiktoken count — the map stays in raw space.\n // Budget decisions multiply by calibrationRatio on the fly.\n indexTokenCountMap[i] = factoryParams.tokenCounter(message);\n if (currentUsage) {\n newOutputs.add(i);\n }\n }\n totalTokens += indexTokenCountMap[i] ?? 0;\n }\n\n // Cumulative calibration: accumulate raw tiktoken tokens and provider-\n // reported tokens across turns. The ratio of the two running totals\n // converges monotonically to the true provider multiplier — no EMA,\n // no per-turn oscillation, no map mutation.\n if (currentUsage && params.totalTokensFresh !== false) {\n const instructionOverhead = factoryParams.getInstructionTokens?.() ?? 0;\n const providerInputTokens =\n params.lastCallUsage?.inputTokens ?? currentUsage.input_tokens;\n\n // Sum raw tiktoken counts for messages the provider saw (excludes\n // new outputs from this turn — the provider hasn't seen them yet).\n let rawSentThisTurn = 0;\n const firstIsSystem =\n params.messages.length > 0 && params.messages[0].getType() === 'system';\n if (firstIsSystem) {\n rawSentThisTurn += indexTokenCountMap[0] ?? 0;\n }\n for (let i = lastCutOffIndex; i < params.messages.length; i++) {\n if ((i === 0 && firstIsSystem) || newOutputs.has(i)) {\n continue;\n }\n rawSentThisTurn += indexTokenCountMap[i] ?? 0;\n }\n\n const providerMessageTokens = Math.max(\n 0,\n providerInputTokens - instructionOverhead\n );\n\n if (rawSentThisTurn > 0 && providerMessageTokens > 0) {\n cumulativeRawSent += rawSentThisTurn;\n cumulativeProviderReported += providerMessageTokens;\n const newRatio = cumulativeProviderReported / cumulativeRawSent;\n calibrationRatio = Math.max(\n CALIBRATION_RATIO_MIN,\n Math.min(CALIBRATION_RATIO_MAX, newRatio)\n );\n }\n\n const calibratedOurTotal =\n instructionOverhead + rawSentThisTurn * calibrationRatio;\n const overallRatio =\n calibratedOurTotal > 0 ? providerInputTokens / calibratedOurTotal : 0;\n const variancePct = Math.round((overallRatio - 1) * 100);\n\n const absVariance = Math.abs(overallRatio - 1);\n if (absVariance < bestVarianceAbs && rawSentThisTurn > 0) {\n bestVarianceAbs = absVariance;\n bestInstructionOverhead = Math.max(\n 0,\n Math.round(providerInputTokens - rawSentThisTurn * calibrationRatio)\n );\n bestInstructionEstimate = factoryParams.getInstructionTokens?.() ?? 0;\n }\n\n factoryParams.log?.('debug', 'Calibration observed', {\n providerInputTokens,\n calibratedEstimate: Math.round(calibratedOurTotal),\n variance: `${variancePct > 0 ? '+' : ''}${variancePct}%`,\n calibrationRatio: Math.round(calibrationRatio * 100) / 100,\n instructionOverhead,\n cumulativeRawSent,\n cumulativeProviderReported,\n });\n }\n\n // Computed BEFORE pre-flight truncation so the effective budget can drive\n // truncation thresholds — without this, thresholds based on maxTokens are\n // too generous and leave individual messages larger than the actual budget.\n const estimatedInstructionTokens =\n factoryParams.getInstructionTokens?.() ?? 0;\n const estimateStable =\n bestInstructionEstimate != null &&\n bestInstructionEstimate > 0 &&\n Math.abs(estimatedInstructionTokens - bestInstructionEstimate) /\n bestInstructionEstimate <\n 0.1;\n const currentInstructionTokens =\n bestInstructionOverhead != null &&\n bestInstructionOverhead <= estimatedInstructionTokens &&\n estimateStable\n ? bestInstructionOverhead\n : estimatedInstructionTokens;\n\n const reserveRatio = factoryParams.reserveRatio ?? DEFAULT_RESERVE_RATIO;\n const reserveTokens =\n reserveRatio > 0 && reserveRatio < 1\n ? Math.round(factoryParams.maxTokens * reserveRatio)\n : 0;\n const pruningBudget = factoryParams.maxTokens - reserveTokens;\n\n const effectiveMaxTokens = Math.max(\n 0,\n pruningBudget - currentInstructionTokens\n );\n\n let calibratedTotalTokens = Math.round(totalTokens * calibrationRatio);\n\n factoryParams.log?.('debug', 'Budget', {\n maxTokens: factoryParams.maxTokens,\n pruningBudget,\n effectiveMax: effectiveMaxTokens,\n instructionTokens: currentInstructionTokens,\n messageCount: params.messages.length,\n calibratedTotalTokens,\n calibrationRatio: Math.round(calibrationRatio * 100) / 100,\n });\n\n // When instructions alone consume the entire budget, no message can\n // fit regardless of truncation. Short-circuit: yield all messages for\n // summarization and return an empty context so the Graph can route to\n // the summarize node immediately instead of falling through to the\n // emergency path that would reach the same outcome more expensively.\n if (\n effectiveMaxTokens === 0 &&\n factoryParams.summarizationEnabled === true &&\n params.messages.length > 0\n ) {\n factoryParams.log?.(\n 'warn',\n 'Instructions consume entire budget — yielding all messages for summarization',\n {\n instructionTokens: currentInstructionTokens,\n pruningBudget,\n messageCount: params.messages.length,\n }\n );\n\n lastTurnStartIndex = params.messages.length;\n return {\n context: [],\n indexTokenCountMap,\n messagesToRefine: [...params.messages],\n prePruneContextTokens: calibratedTotalTokens,\n remainingContextTokens: 0,\n contextPressure:\n pruningBudget > 0 ? calibratedTotalTokens / pruningBudget : 0,\n calibrationRatio,\n resolvedInstructionOverhead: bestInstructionOverhead,\n };\n }\n\n // ---------------------------------------------------------------------------\n // Progressive context fading — inspired by Claude Code's staged compaction.\n // Below 80%: no modifications, tool results retain full size.\n // Above 80%: graduated truncation with increasing aggression per pressure band.\n // Recency weighting ensures older results fade first, newer results last.\n //\n // At the gentlest level, truncation preserves most content (head+tail).\n // At the most aggressive level, the result is effectively a one-line placeholder.\n //\n // 80%: gentle — budget factor 1.0, oldest get light truncation\n // 85%: moderate — budget factor 0.50, older results shrink significantly\n // 90%: aggressive — budget factor 0.20, most results heavily truncated\n // 99%: emergency — budget factor 0.05, effectively placeholders for old results\n // ---------------------------------------------------------------------------\n totalTokens = sumTokenCounts(indexTokenCountMap, params.messages.length);\n calibratedTotalTokens = Math.round(totalTokens * calibrationRatio);\n const contextPressure =\n pruningBudget > 0 ? calibratedTotalTokens / pruningBudget : 0;\n let preFlightResultCount = 0;\n let preFlightInputCount = 0;\n\n // -----------------------------------------------------------------------\n // Observation masking (80%+ pressure, both paths):\n // Replace consumed ToolMessage content with tight head+tail placeholders.\n // AI messages stay intact so the model can read its own prior reasoning\n // and won't repeat work. Unconsumed results (latest tool outputs the\n // model hasn't acted on yet) stay full.\n //\n // When summarization is enabled, snapshot messages first so the\n // summarizer can see the full originals when compaction fires.\n // -----------------------------------------------------------------------\n let observationsMasked = 0;\n\n if (contextPressure >= PRESSURE_THRESHOLD_MASKING) {\n const rawMessageBudget =\n calibrationRatio > 0\n ? Math.floor(effectiveMaxTokens / calibrationRatio)\n : effectiveMaxTokens;\n // When summarization is enabled, use half the reserve ratio as extra\n // masking headroom — the LLM keeps more context while the summarizer\n // gets full content from originalToolContent regardless. The remaining\n // half of the reserve covers estimation errors.\n const reserveHeadroom =\n factoryParams.summarizationEnabled === true\n ? Math.floor(\n rawMessageBudget *\n (factoryParams.reserveRatio ?? DEFAULT_RESERVE_RATIO) *\n 0.5\n )\n : 0;\n observationsMasked = maskConsumedToolResults({\n messages: params.messages,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n availableRawBudget: rawMessageBudget + reserveHeadroom,\n originalContentStore:\n factoryParams.summarizationEnabled === true\n ? originalToolContent\n : undefined,\n onContentStored:\n factoryParams.summarizationEnabled === true\n ? (charLen: number): void => {\n originalToolContentSize += charLen;\n while (\n originalToolContentSize > ORIGINAL_CONTENT_MAX_CHARS &&\n originalToolContent.size > 0\n ) {\n const oldest = originalToolContent.keys().next();\n if (oldest.done === true) {\n break;\n }\n const removed = originalToolContent.get(oldest.value);\n if (removed != null) {\n originalToolContentSize -= removed.length;\n }\n originalToolContent.delete(oldest.value);\n }\n }\n : undefined,\n });\n if (observationsMasked > 0) {\n cumulativeRawSent = 0;\n cumulativeProviderReported = 0;\n }\n }\n\n if (\n contextPressure >= PRESSURE_THRESHOLD_MASKING &&\n factoryParams.summarizationEnabled !== true\n ) {\n const budgetFactor =\n PRESSURE_BANDS.find(\n ([threshold]) => contextPressure >= threshold\n )?.[1] ?? 1.0;\n\n const baseBudget = Math.max(\n 1024,\n Math.floor(effectiveMaxTokens * budgetFactor)\n );\n\n preFlightResultCount = preFlightTruncateToolResults({\n messages: params.messages,\n maxContextTokens: baseBudget,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n\n preFlightInputCount = preFlightTruncateToolCallInputs({\n messages: params.messages,\n maxContextTokens: baseBudget,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n }\n if (\n factoryParams.contextPruningConfig?.enabled === true &&\n factoryParams.summarizationEnabled !== true\n ) {\n applyContextPruning({\n messages: params.messages,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n resolvedSettings: contextPruningSettings,\n });\n }\n\n // Fit-to-budget: when summarization is enabled and individual messages\n // exceed the effective budget, truncate them so every message can fit in\n // a single context slot. Without this, oversized tool results (e.g.\n // take_snapshot at 9K chars) cause empty context → emergency truncation\n // → immediate re-summarization after just one tool call.\n //\n // This is NOT the lossy position-based fading above — it only targets\n // messages that individually exceed the budget, using the full effective\n // budget as the cap (not a pressure-scaled fraction).\n // Fit-to-budget caps are in raw space (divide by ratio) so that after\n // calibration the truncated results actually fit within the budget.\n const rawSpaceEffectiveMax =\n calibrationRatio > 0\n ? Math.round(effectiveMaxTokens / calibrationRatio)\n : effectiveMaxTokens;\n\n if (\n factoryParams.summarizationEnabled === true &&\n rawSpaceEffectiveMax > 0\n ) {\n preFlightResultCount = preFlightTruncateToolResults({\n messages: params.messages,\n maxContextTokens: rawSpaceEffectiveMax,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n\n preFlightInputCount = preFlightTruncateToolCallInputs({\n messages: params.messages,\n maxContextTokens: rawSpaceEffectiveMax,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n }\n\n const preTruncationTotalTokens = totalTokens;\n totalTokens = sumTokenCounts(indexTokenCountMap, params.messages.length);\n calibratedTotalTokens = Math.round(totalTokens * calibrationRatio);\n\n const anyAdjustment =\n observationsMasked > 0 ||\n preFlightResultCount > 0 ||\n preFlightInputCount > 0 ||\n totalTokens !== preTruncationTotalTokens;\n\n if (anyAdjustment) {\n factoryParams.log?.('debug', 'Context adjusted', {\n contextPressure: Math.round(contextPressure * 100),\n observationsMasked,\n toolOutputsTruncated: preFlightResultCount,\n toolInputsTruncated: preFlightInputCount,\n tokensBefore: preTruncationTotalTokens,\n tokensAfter: totalTokens,\n tokensSaved: preTruncationTotalTokens - totalTokens,\n });\n }\n\n lastTurnStartIndex = params.messages.length;\n if (\n lastCutOffIndex === 0 &&\n calibratedTotalTokens + currentInstructionTokens <= pruningBudget\n ) {\n return {\n context: params.messages,\n indexTokenCountMap,\n messagesToRefine: [],\n prePruneContextTokens: calibratedTotalTokens,\n remainingContextTokens:\n pruningBudget - calibratedTotalTokens - currentInstructionTokens,\n contextPressure,\n originalToolContent:\n originalToolContent.size > 0 ? originalToolContent : undefined,\n calibrationRatio,\n resolvedInstructionOverhead: bestInstructionOverhead,\n };\n }\n\n const rawSpaceBudget =\n calibrationRatio > 0\n ? Math.round(pruningBudget / calibrationRatio)\n : pruningBudget;\n\n const rawSpaceInstructionTokens =\n calibrationRatio > 0\n ? Math.round(currentInstructionTokens / calibrationRatio)\n : currentInstructionTokens;\n\n const {\n context: initialContext,\n thinkingStartIndex,\n messagesToRefine,\n remainingContextTokens: initialRemainingContextTokens,\n } = getMessagesWithinTokenLimit({\n maxContextTokens: rawSpaceBudget,\n messages: params.messages,\n indexTokenCountMap,\n startType: params.startType,\n thinkingEnabled: factoryParams.thinkingEnabled,\n tokenCounter: factoryParams.tokenCounter,\n instructionTokens: rawSpaceInstructionTokens,\n reasoningType:\n factoryParams.provider === Providers.BEDROCK\n ? ContentTypes.REASONING_CONTENT\n : ContentTypes.THINKING,\n thinkingStartIndex:\n factoryParams.thinkingEnabled === true\n ? runThinkingStartIndex\n : undefined,\n });\n\n const {\n context: repairedContext,\n reclaimedTokens: initialReclaimedTokens,\n droppedMessages,\n } = repairOrphanedToolMessages({\n context: initialContext,\n allMessages: params.messages,\n tokenCounter: factoryParams.tokenCounter,\n indexTokenCountMap,\n });\n\n const contextBreakdown = repairedContext.map((msg) => {\n const type = msg.getType();\n const name = type === 'tool' ? (msg.name ?? 'unknown') : '';\n return name !== '' ? `${type}(${name})` : type;\n });\n factoryParams.log?.('debug', 'Pruning complete', {\n contextLength: repairedContext.length,\n contextTypes: contextBreakdown.join(', '),\n messagesToRefineCount: messagesToRefine.length,\n droppedOrphans: droppedMessages.length,\n remainingTokens: initialRemainingContextTokens,\n });\n\n let context = repairedContext;\n let reclaimedTokens = initialReclaimedTokens;\n\n // Orphan repair may drop ToolMessages whose parent AI was pruned.\n // Append them to messagesToRefine so summarization can still see the\n // tool results (otherwise the summary says \"in progress\" for a tool\n // call that already completed, causing the model to repeat it).\n if (droppedMessages.length > 0) {\n messagesToRefine.push(...droppedMessages);\n }\n\n // ---------------------------------------------------------------\n // Fallback fading: when summarization skipped fading earlier and\n // pruning still produced an empty context, apply lossy pressure-band\n // fading and retry. This is a last resort before emergency truncation\n // — the summarizer already saw the full messages, so fading the\n // surviving context for the LLM is acceptable.\n // ---------------------------------------------------------------\n if (\n context.length === 0 &&\n params.messages.length > 0 &&\n effectiveMaxTokens > 0 &&\n factoryParams.summarizationEnabled === true\n ) {\n const fadingBudget = Math.max(1024, effectiveMaxTokens);\n\n factoryParams.log?.(\n 'debug',\n 'Fallback fading — empty context with summarization',\n {\n messageCount: params.messages.length,\n effectiveMaxTokens,\n fadingBudget,\n }\n );\n\n const fadedMessages = [...params.messages];\n const preFadingTokenCounts: Record<string, number | undefined> = {};\n for (let i = 0; i < params.messages.length; i++) {\n preFadingTokenCounts[i] = indexTokenCountMap[i];\n }\n\n preFlightTruncateToolResults({\n messages: fadedMessages,\n maxContextTokens: fadingBudget,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n preFlightTruncateToolCallInputs({\n messages: fadedMessages,\n maxContextTokens: fadingBudget,\n indexTokenCountMap,\n tokenCounter: factoryParams.tokenCounter,\n });\n\n const fadingRetry = getMessagesWithinTokenLimit({\n maxContextTokens: pruningBudget,\n messages: fadedMessages,\n indexTokenCountMap,\n startType: params.startType,\n thinkingEnabled: factoryParams.thinkingEnabled,\n tokenCounter: factoryParams.tokenCounter,\n instructionTokens: currentInstructionTokens,\n reasoningType:\n factoryParams.provider === Providers.BEDROCK\n ? ContentTypes.REASONING_CONTENT\n : ContentTypes.THINKING,\n thinkingStartIndex:\n factoryParams.thinkingEnabled === true\n ? runThinkingStartIndex\n : undefined,\n });\n\n const fadingRepaired = repairOrphanedToolMessages({\n context: fadingRetry.context,\n allMessages: fadedMessages,\n tokenCounter: factoryParams.tokenCounter,\n indexTokenCountMap,\n });\n\n if (fadingRepaired.context.length > 0) {\n context = fadingRepaired.context;\n reclaimedTokens = fadingRepaired.reclaimedTokens;\n messagesToRefine.push(...fadingRetry.messagesToRefine);\n if (fadingRepaired.droppedMessages.length > 0) {\n messagesToRefine.push(...fadingRepaired.droppedMessages);\n }\n\n factoryParams.log?.('debug', 'Fallback fading recovered context', {\n contextLength: context.length,\n messagesToRefineCount: messagesToRefine.length,\n remainingTokens: fadingRetry.remainingContextTokens,\n });\n\n for (const [key, value] of Object.entries(preFadingTokenCounts)) {\n indexTokenCountMap[key] = value;\n }\n } else {\n for (const [key, value] of Object.entries(preFadingTokenCounts)) {\n indexTokenCountMap[key] = value;\n }\n }\n }\n\n // ---------------------------------------------------------------\n // Emergency truncation: if pruning produced an empty context but\n // messages exist, aggressively truncate all tool_call inputs and\n // tool results, then retry. Budget is proportional to the\n // effective token limit (~4 chars/token, spread across messages)\n // with a floor of 200 chars so content is never completely blank.\n // Uses head+tail so the model sees both what was called and the\n // final outcome (e.g., return value at the end of a script eval).\n // ---------------------------------------------------------------\n if (\n context.length === 0 &&\n params.messages.length > 0 &&\n effectiveMaxTokens > 0\n ) {\n const perMessageTokenBudget = Math.floor(\n effectiveMaxTokens / Math.max(1, params.messages.length)\n );\n const emergencyMaxChars = Math.max(200, perMessageTokenBudget * 4);\n\n factoryParams.log?.(\n 'warn',\n 'Empty context, entering emergency truncation',\n {\n messageCount: params.messages.length,\n effectiveMax: effectiveMaxTokens,\n emergencyMaxChars,\n }\n );\n\n // Clone the messages array so emergency truncation doesn't permanently\n // mutate graph state. The originals remain intact for future turns\n // where more budget may be available. Also snapshot indexTokenCountMap\n // entries so the closure doesn't retain stale (too-small) counts for\n // the original un-truncated messages on the next turn.\n const emergencyMessages = [...params.messages];\n const preEmergencyTokenCounts: Record<string, number | undefined> = {};\n for (let i = 0; i < params.messages.length; i++) {\n preEmergencyTokenCounts[i] = indexTokenCountMap[i];\n }\n\n try {\n let emergencyTruncatedCount = 0;\n for (let i = 0; i < emergencyMessages.length; i++) {\n const message = emergencyMessages[i];\n if (message.getType() === 'tool') {\n const content = message.content;\n if (\n typeof content === 'string' &&\n content.length > emergencyMaxChars\n ) {\n const cloned = new ToolMessage({\n content: truncateToolResultContent(content, emergencyMaxChars),\n tool_call_id: (message as ToolMessage).tool_call_id,\n name: message.name,\n id: message.id,\n additional_kwargs: message.additional_kwargs,\n response_metadata: message.response_metadata,\n });\n emergencyMessages[i] = cloned;\n indexTokenCountMap[i] = factoryParams.tokenCounter(cloned);\n emergencyTruncatedCount++;\n }\n }\n if (message.getType() === 'ai' && Array.isArray(message.content)) {\n const aiMsg = message as AIMessage;\n const contentBlocks = aiMsg.content as MessageContentComplex[];\n const needsTruncation = contentBlocks.some((block) => {\n if (typeof block !== 'object') return false;\n const record = block as Record<string, unknown>;\n if (\n (record.type === 'tool_use' || record.type === 'tool_call') &&\n record.input != null\n ) {\n const serialized =\n typeof record.input === 'string'\n ? record.input\n : JSON.stringify(record.input);\n return serialized.length > emergencyMaxChars;\n }\n return false;\n });\n if (needsTruncation) {\n const newContent = contentBlocks.map((block) => {\n if (typeof block !== 'object') return block;\n const record = block as Record<string, unknown>;\n if (\n (record.type === 'tool_use' || record.type === 'tool_call') &&\n record.input != null\n ) {\n const serialized =\n typeof record.input === 'string'\n ? record.input\n : JSON.stringify(record.input);\n if (serialized.length > emergencyMaxChars) {\n // Replaces original input with { _truncated, _originalChars } —\n // safe because the tool call already executed in a prior turn.\n return {\n ...record,\n input: truncateToolInput(serialized, emergencyMaxChars),\n };\n }\n }\n return block;\n });\n const newToolCalls = (aiMsg.tool_calls ?? []).map((tc) => {\n const serializedArgs = JSON.stringify(tc.args);\n if (serializedArgs.length > emergencyMaxChars) {\n // Replaces original args with { _truncated, _originalChars } —\n // safe because the tool call already executed in a prior turn.\n return {\n ...tc,\n args: truncateToolInput(serializedArgs, emergencyMaxChars),\n };\n }\n return tc;\n });\n emergencyMessages[i] = new AIMessage({\n ...aiMsg,\n content: newContent,\n tool_calls: newToolCalls.length > 0 ? newToolCalls : undefined,\n });\n indexTokenCountMap[i] = factoryParams.tokenCounter(\n emergencyMessages[i]\n );\n emergencyTruncatedCount++;\n }\n }\n }\n\n factoryParams.log?.('info', 'Emergency truncation complete');\n factoryParams.log?.('debug', 'Emergency truncation details', {\n truncatedCount: emergencyTruncatedCount,\n emergencyMaxChars,\n });\n\n const retryResult = getMessagesWithinTokenLimit({\n maxContextTokens: pruningBudget,\n messages: emergencyMessages,\n indexTokenCountMap,\n startType: params.startType,\n thinkingEnabled: factoryParams.thinkingEnabled,\n tokenCounter: factoryParams.tokenCounter,\n instructionTokens: currentInstructionTokens,\n reasoningType:\n factoryParams.provider === Providers.BEDROCK\n ? ContentTypes.REASONING_CONTENT\n : ContentTypes.THINKING,\n thinkingStartIndex:\n factoryParams.thinkingEnabled === true\n ? runThinkingStartIndex\n : undefined,\n });\n\n const repaired = repairOrphanedToolMessages({\n context: retryResult.context,\n allMessages: emergencyMessages,\n tokenCounter: factoryParams.tokenCounter,\n indexTokenCountMap,\n });\n\n context = repaired.context;\n reclaimedTokens = repaired.reclaimedTokens;\n messagesToRefine.push(...retryResult.messagesToRefine);\n if (repaired.droppedMessages.length > 0) {\n messagesToRefine.push(...repaired.droppedMessages);\n }\n\n factoryParams.log?.('debug', 'Emergency truncation retry result', {\n contextLength: context.length,\n messagesToRefineCount: messagesToRefine.length,\n remainingTokens: retryResult.remainingContextTokens,\n });\n } finally {\n // Restore the closure's indexTokenCountMap to pre-emergency values so the\n // next turn counts old messages at their original (un-truncated) size.\n // The emergency-truncated counts were only needed for this turn's\n // getMessagesWithinTokenLimit retry.\n for (const [key, value] of Object.entries(preEmergencyTokenCounts)) {\n indexTokenCountMap[key] = value;\n }\n }\n }\n\n const remainingContextTokens = Math.max(\n 0,\n Math.min(pruningBudget, initialRemainingContextTokens + reclaimedTokens)\n );\n\n runThinkingStartIndex = thinkingStartIndex ?? -1;\n /** The index is the first value of `context`, index relative to `params.messages` */\n lastCutOffIndex = Math.max(\n params.messages.length -\n (context.length - (context[0]?.getType() === 'system' ? 1 : 0)),\n 0\n );\n\n return {\n context,\n indexTokenCountMap,\n messagesToRefine,\n prePruneContextTokens: calibratedTotalTokens,\n remainingContextTokens,\n contextPressure,\n originalToolContent:\n originalToolContent.size > 0 ? originalToolContent : undefined,\n calibrationRatio,\n resolvedInstructionOverhead: bestInstructionOverhead,\n };\n };\n}\n"],"names":["AIMessage","messages","Constants","ToolMessage","ContentTypes","truncateToolResultContent","calculateMaxToolResultChars","truncateToolInput","contextPruningSettings","resolveContextPruningSettings","Providers","applyContextPruning"],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ 'use strict';
2
+
3
+ var messages = require('@langchain/core/messages');
4
+ var uuid = require('uuid');
5
+
6
+ const REMOVE_ALL_MESSAGES = '__remove_all__';
7
+ /**
8
+ * Creates a message that instructs messagesStateReducer to remove ALL
9
+ * existing messages from state. Messages appearing after this one in
10
+ * the array become the new state.
11
+ *
12
+ * Usage (in a node return value):
13
+ * ```ts
14
+ * return { messages: [createRemoveAllMessage(), ...survivingMessages] };
15
+ * ```
16
+ *
17
+ * This works because the reducer checks for `getType() === 'remove'`
18
+ * with `id === REMOVE_ALL_MESSAGES` and discards everything before it.
19
+ *
20
+ * NOTE: Uses RemoveMessage from @langchain/core with a sentinel id so
21
+ * the reducer can distinguish a "remove-all" marker from a single-message
22
+ * removal.
23
+ */
24
+ function createRemoveAllMessage() {
25
+ return new messages.RemoveMessage({ id: REMOVE_ALL_MESSAGES });
26
+ }
27
+ /**
28
+ * Prebuilt reducer that combines returned messages.
29
+ * Can handle standard messages and special modifiers like {@link RemoveMessage}
30
+ * instances.
31
+ */
32
+ function messagesStateReducer(left, right) {
33
+ const leftArray = Array.isArray(left) ? left : [left];
34
+ const rightArray = Array.isArray(right) ? right : [right];
35
+ // coerce to message
36
+ const leftMessages = leftArray.map(messages.coerceMessageLikeToMessage);
37
+ const rightMessages = rightArray.map(messages.coerceMessageLikeToMessage);
38
+ // assign missing ids
39
+ for (const m of leftMessages) {
40
+ if (m.id === null || m.id === undefined) {
41
+ m.id = uuid.v4();
42
+ m.lc_kwargs.id = m.id;
43
+ }
44
+ }
45
+ let removeAllIdx;
46
+ for (let i = 0; i < rightMessages.length; i += 1) {
47
+ const m = rightMessages[i];
48
+ if (m.id === null || m.id === undefined) {
49
+ m.id = uuid.v4();
50
+ m.lc_kwargs.id = m.id;
51
+ }
52
+ if (m.getType() === 'remove' && m.id === REMOVE_ALL_MESSAGES) {
53
+ removeAllIdx = i;
54
+ }
55
+ }
56
+ if (removeAllIdx != null)
57
+ return rightMessages.slice(removeAllIdx + 1);
58
+ // merge
59
+ const merged = [...leftMessages];
60
+ const mergedById = new Map(merged.map((m, i) => [m.id, i]));
61
+ const idsToRemove = new Set();
62
+ for (const m of rightMessages) {
63
+ const existingIdx = mergedById.get(m.id);
64
+ if (existingIdx !== undefined) {
65
+ if (m.getType() === 'remove') {
66
+ idsToRemove.add(m.id);
67
+ }
68
+ else {
69
+ idsToRemove.delete(m.id);
70
+ merged[existingIdx] = m;
71
+ }
72
+ }
73
+ else {
74
+ if (m.getType() === 'remove') {
75
+ throw new Error(`Attempting to delete a message with an ID that doesn't exist ('${m.id}')`);
76
+ }
77
+ mergedById.set(m.id, merged.length);
78
+ merged.push(m);
79
+ }
80
+ }
81
+ return merged.filter((m) => !idsToRemove.has(m.id));
82
+ }
83
+
84
+ exports.REMOVE_ALL_MESSAGES = REMOVE_ALL_MESSAGES;
85
+ exports.createRemoveAllMessage = createRemoveAllMessage;
86
+ exports.messagesStateReducer = messagesStateReducer;
87
+ //# sourceMappingURL=reducer.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducer.cjs","sources":["../../../src/messages/reducer.ts"],"sourcesContent":["import {\n BaseMessage,\n RemoveMessage,\n BaseMessageLike,\n coerceMessageLikeToMessage,\n} from '@langchain/core/messages';\nimport { v4 } from 'uuid';\n\nexport const REMOVE_ALL_MESSAGES = '__remove_all__';\n\n/**\n * Creates a message that instructs messagesStateReducer to remove ALL\n * existing messages from state. Messages appearing after this one in\n * the array become the new state.\n *\n * Usage (in a node return value):\n * ```ts\n * return { messages: [createRemoveAllMessage(), ...survivingMessages] };\n * ```\n *\n * This works because the reducer checks for `getType() === 'remove'`\n * with `id === REMOVE_ALL_MESSAGES` and discards everything before it.\n *\n * NOTE: Uses RemoveMessage from @langchain/core with a sentinel id so\n * the reducer can distinguish a \"remove-all\" marker from a single-message\n * removal.\n */\nexport function createRemoveAllMessage(): BaseMessage {\n return new RemoveMessage({ id: REMOVE_ALL_MESSAGES });\n}\n\nexport type Messages =\n | Array<BaseMessage | BaseMessageLike>\n | BaseMessage\n | BaseMessageLike;\n\n/**\n * Prebuilt reducer that combines returned messages.\n * Can handle standard messages and special modifiers like {@link RemoveMessage}\n * instances.\n */\nexport function messagesStateReducer(\n left: Messages,\n right: Messages\n): BaseMessage[] {\n const leftArray = Array.isArray(left) ? left : [left];\n const rightArray = Array.isArray(right) ? right : [right];\n // coerce to message\n const leftMessages = (leftArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n const rightMessages = (rightArray as BaseMessageLike[]).map(\n coerceMessageLikeToMessage\n );\n // assign missing ids\n for (const m of leftMessages) {\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n }\n\n let removeAllIdx: number | undefined;\n for (let i = 0; i < rightMessages.length; i += 1) {\n const m = rightMessages[i];\n if (m.id === null || m.id === undefined) {\n m.id = v4();\n m.lc_kwargs.id = m.id;\n }\n\n if (m.getType() === 'remove' && m.id === REMOVE_ALL_MESSAGES) {\n removeAllIdx = i;\n }\n }\n\n if (removeAllIdx != null) return rightMessages.slice(removeAllIdx + 1);\n\n // merge\n const merged = [...leftMessages];\n const mergedById = new Map(merged.map((m, i) => [m.id, i]));\n const idsToRemove = new Set();\n for (const m of rightMessages) {\n const existingIdx = mergedById.get(m.id);\n if (existingIdx !== undefined) {\n if (m.getType() === 'remove') {\n idsToRemove.add(m.id);\n } else {\n idsToRemove.delete(m.id);\n merged[existingIdx] = m;\n }\n } else {\n if (m.getType() === 'remove') {\n throw new Error(\n `Attempting to delete a message with an ID that doesn't exist ('${m.id}')`\n );\n }\n mergedById.set(m.id, merged.length);\n merged.push(m);\n }\n }\n return merged.filter((m) => !idsToRemove.has(m.id));\n}\n"],"names":["RemoveMessage","coerceMessageLikeToMessage","v4"],"mappings":"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"}