@librechat/agents 3.8.0 → 3.8.2

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 (248) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +13 -3
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +176 -55
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs +16 -6
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/hitl/approvalReview.cjs +89 -0
  8. package/dist/cjs/hitl/approvalReview.cjs.map +1 -0
  9. package/dist/cjs/langfuse.cjs +42 -0
  10. package/dist/cjs/langfuse.cjs.map +1 -1
  11. package/dist/cjs/langfuseToolOutputTracing.cjs +42 -0
  12. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  13. package/dist/cjs/langfuseTraceShaping.cjs +7 -1
  14. package/dist/cjs/langfuseTraceShaping.cjs.map +1 -1
  15. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +6 -10
  16. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  17. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +2 -7
  18. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  19. package/dist/cjs/llm/contextPressureMeter.cjs +51 -10
  20. package/dist/cjs/llm/contextPressureMeter.cjs.map +1 -1
  21. package/dist/cjs/llm/init.cjs +1 -1
  22. package/dist/cjs/llm/invoke.cjs +2 -2
  23. package/dist/cjs/llm/openai/index.cjs +4 -3
  24. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  25. package/dist/cjs/llm/openai/utils/index.cjs +5 -4
  26. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  27. package/dist/cjs/llm/preempt.cjs +3 -2
  28. package/dist/cjs/llm/preempt.cjs.map +1 -1
  29. package/dist/cjs/llm/prepareProviderRequest.cjs +9 -7
  30. package/dist/cjs/llm/prepareProviderRequest.cjs.map +1 -1
  31. package/dist/cjs/llm/providers.cjs +1 -1
  32. package/dist/cjs/main.cjs +14 -8
  33. package/dist/cjs/messages/alternation.cjs +1 -5
  34. package/dist/cjs/messages/alternation.cjs.map +1 -1
  35. package/dist/cjs/messages/budget.cjs +206 -7
  36. package/dist/cjs/messages/budget.cjs.map +1 -1
  37. package/dist/cjs/messages/cache.cjs +3 -9
  38. package/dist/cjs/messages/cache.cjs.map +1 -1
  39. package/dist/cjs/messages/core.cjs +26 -38
  40. package/dist/cjs/messages/core.cjs.map +1 -1
  41. package/dist/cjs/messages/format.cjs +132 -43
  42. package/dist/cjs/messages/format.cjs.map +1 -1
  43. package/dist/cjs/messages/index.cjs +2 -0
  44. package/dist/cjs/messages/prune.cjs +14 -9
  45. package/dist/cjs/messages/prune.cjs.map +1 -1
  46. package/dist/cjs/messages/reasoningTypes.cjs +21 -0
  47. package/dist/cjs/messages/reasoningTypes.cjs.map +1 -0
  48. package/dist/cjs/messages/recency.cjs +15 -94
  49. package/dist/cjs/messages/recency.cjs.map +1 -1
  50. package/dist/cjs/messages/toolHistoryProjection.cjs +243 -0
  51. package/dist/cjs/messages/toolHistoryProjection.cjs.map +1 -0
  52. package/dist/cjs/messages/toolResultTypes.cjs +145 -4
  53. package/dist/cjs/messages/toolResultTypes.cjs.map +1 -1
  54. package/dist/cjs/run.cjs +22 -10
  55. package/dist/cjs/run.cjs.map +1 -1
  56. package/dist/cjs/session/AgentSession.cjs +7 -5
  57. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  58. package/dist/cjs/session/JsonlSessionStore.cjs +3 -0
  59. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  60. package/dist/cjs/session/index.cjs +1 -1
  61. package/dist/cjs/session/sessionProjection.cjs +75 -0
  62. package/dist/cjs/session/sessionProjection.cjs.map +1 -0
  63. package/dist/cjs/stream.cjs +20 -19
  64. package/dist/cjs/stream.cjs.map +1 -1
  65. package/dist/cjs/summarization/index.cjs.map +1 -1
  66. package/dist/cjs/summarization/node.cjs +19 -9
  67. package/dist/cjs/summarization/node.cjs.map +1 -1
  68. package/dist/cjs/summarization/shared.cjs +9 -0
  69. package/dist/cjs/summarization/shared.cjs.map +1 -1
  70. package/dist/cjs/tools/ToolNode.cjs +256 -84
  71. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  72. package/dist/cjs/tools/local/CompileCheckTool.cjs +1 -1
  73. package/dist/cjs/tools/local/LocalCodingTools.cjs +1 -1
  74. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +24 -9
  75. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  76. package/dist/cjs/tools/subagent/SubagentReplay.cjs +2 -0
  77. package/dist/cjs/tools/subagent/SubagentReplay.cjs.map +1 -1
  78. package/dist/cjs/tools/toolBatchReplay.cjs +187 -0
  79. package/dist/cjs/tools/toolBatchReplay.cjs.map +1 -0
  80. package/dist/cjs/tools/toolOutputReferences.cjs +12 -0
  81. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  82. package/dist/cjs/types/hitl.cjs +4 -0
  83. package/dist/cjs/types/hitl.cjs.map +1 -1
  84. package/dist/cjs/utils/events.cjs +13 -0
  85. package/dist/cjs/utils/events.cjs.map +1 -1
  86. package/dist/cjs/utils/tokens.cjs +105 -0
  87. package/dist/cjs/utils/tokens.cjs.map +1 -1
  88. package/dist/esm/agents/AgentContext.mjs +13 -3
  89. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  90. package/dist/esm/graphs/Graph.mjs +178 -57
  91. package/dist/esm/graphs/Graph.mjs.map +1 -1
  92. package/dist/esm/graphs/MultiAgentGraph.mjs +16 -6
  93. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  94. package/dist/esm/hitl/approvalReview.mjs +83 -0
  95. package/dist/esm/hitl/approvalReview.mjs.map +1 -0
  96. package/dist/esm/langfuse.mjs +43 -2
  97. package/dist/esm/langfuse.mjs.map +1 -1
  98. package/dist/esm/langfuseToolOutputTracing.mjs +41 -1
  99. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  100. package/dist/esm/langfuseTraceShaping.mjs +7 -1
  101. package/dist/esm/langfuseTraceShaping.mjs.map +1 -1
  102. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +6 -10
  103. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  104. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +2 -7
  105. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  106. package/dist/esm/llm/contextPressureMeter.mjs +52 -11
  107. package/dist/esm/llm/contextPressureMeter.mjs.map +1 -1
  108. package/dist/esm/llm/init.mjs +1 -1
  109. package/dist/esm/llm/invoke.mjs +2 -2
  110. package/dist/esm/llm/openai/index.mjs +2 -1
  111. package/dist/esm/llm/openai/index.mjs.map +1 -1
  112. package/dist/esm/llm/openai/utils/index.mjs +5 -4
  113. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  114. package/dist/esm/llm/preempt.mjs +2 -1
  115. package/dist/esm/llm/preempt.mjs.map +1 -1
  116. package/dist/esm/llm/prepareProviderRequest.mjs +9 -7
  117. package/dist/esm/llm/prepareProviderRequest.mjs.map +1 -1
  118. package/dist/esm/llm/providers.mjs +1 -1
  119. package/dist/esm/main.mjs +13 -10
  120. package/dist/esm/messages/alternation.mjs +2 -6
  121. package/dist/esm/messages/alternation.mjs.map +1 -1
  122. package/dist/esm/messages/budget.mjs +206 -8
  123. package/dist/esm/messages/budget.mjs.map +1 -1
  124. package/dist/esm/messages/cache.mjs +3 -9
  125. package/dist/esm/messages/cache.mjs.map +1 -1
  126. package/dist/esm/messages/core.mjs +24 -34
  127. package/dist/esm/messages/core.mjs.map +1 -1
  128. package/dist/esm/messages/format.mjs +133 -44
  129. package/dist/esm/messages/format.mjs.map +1 -1
  130. package/dist/esm/messages/index.mjs +2 -0
  131. package/dist/esm/messages/prune.mjs +14 -9
  132. package/dist/esm/messages/prune.mjs.map +1 -1
  133. package/dist/esm/messages/reasoningTypes.mjs +20 -0
  134. package/dist/esm/messages/reasoningTypes.mjs.map +1 -0
  135. package/dist/esm/messages/recency.mjs +16 -95
  136. package/dist/esm/messages/recency.mjs.map +1 -1
  137. package/dist/esm/messages/toolHistoryProjection.mjs +237 -0
  138. package/dist/esm/messages/toolHistoryProjection.mjs.map +1 -0
  139. package/dist/esm/messages/toolResultTypes.mjs +141 -4
  140. package/dist/esm/messages/toolResultTypes.mjs.map +1 -1
  141. package/dist/esm/run.mjs +23 -11
  142. package/dist/esm/run.mjs.map +1 -1
  143. package/dist/esm/session/AgentSession.mjs +7 -5
  144. package/dist/esm/session/AgentSession.mjs.map +1 -1
  145. package/dist/esm/session/JsonlSessionStore.mjs +3 -0
  146. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  147. package/dist/esm/session/index.mjs +1 -1
  148. package/dist/esm/session/sessionProjection.mjs +72 -0
  149. package/dist/esm/session/sessionProjection.mjs.map +1 -0
  150. package/dist/esm/stream.mjs +17 -16
  151. package/dist/esm/stream.mjs.map +1 -1
  152. package/dist/esm/summarization/index.mjs.map +1 -1
  153. package/dist/esm/summarization/node.mjs +20 -10
  154. package/dist/esm/summarization/node.mjs.map +1 -1
  155. package/dist/esm/summarization/shared.mjs +9 -1
  156. package/dist/esm/summarization/shared.mjs.map +1 -1
  157. package/dist/esm/tools/ToolNode.mjs +256 -84
  158. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  159. package/dist/esm/tools/local/CompileCheckTool.mjs +1 -1
  160. package/dist/esm/tools/local/LocalCodingTools.mjs +1 -1
  161. package/dist/esm/tools/subagent/SubagentExecutor.mjs +24 -9
  162. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  163. package/dist/esm/tools/subagent/SubagentReplay.mjs +1 -1
  164. package/dist/esm/tools/subagent/SubagentReplay.mjs.map +1 -1
  165. package/dist/esm/tools/toolBatchReplay.mjs +176 -0
  166. package/dist/esm/tools/toolBatchReplay.mjs.map +1 -0
  167. package/dist/esm/tools/toolOutputReferences.mjs +12 -0
  168. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  169. package/dist/esm/types/hitl.mjs +4 -1
  170. package/dist/esm/types/hitl.mjs.map +1 -1
  171. package/dist/esm/utils/events.mjs +13 -0
  172. package/dist/esm/utils/events.mjs.map +1 -1
  173. package/dist/esm/utils/tokens.mjs +105 -1
  174. package/dist/esm/utils/tokens.mjs.map +1 -1
  175. package/dist/types/agents/AgentContext.d.ts +13 -1
  176. package/dist/types/graphs/Graph.d.ts +27 -0
  177. package/dist/types/hitl/approvalReview.d.ts +32 -0
  178. package/dist/types/hooks/types.d.ts +4 -2
  179. package/dist/types/index.d.ts +1 -0
  180. package/dist/types/langfuse.d.ts +5 -0
  181. package/dist/types/langfuseToolOutputTracing.d.ts +2 -0
  182. package/dist/types/llm/contextPressureMeter.d.ts +2 -1
  183. package/dist/types/llm/prepareProviderRequest.d.ts +7 -1
  184. package/dist/types/messages/budget.d.ts +15 -10
  185. package/dist/types/messages/core.d.ts +8 -17
  186. package/dist/types/messages/format.d.ts +3 -2
  187. package/dist/types/messages/index.d.ts +1 -1
  188. package/dist/types/messages/prune.d.ts +1 -1
  189. package/dist/types/messages/reasoningTypes.d.ts +7 -0
  190. package/dist/types/messages/recency.d.ts +3 -0
  191. package/dist/types/messages/toolHistoryProjection.d.ts +65 -0
  192. package/dist/types/messages/toolResultTypes.d.ts +31 -1
  193. package/dist/types/session/sessionProjection.d.ts +10 -0
  194. package/dist/types/summarization/index.d.ts +2 -1
  195. package/dist/types/summarization/node.d.ts +1 -0
  196. package/dist/types/summarization/shared.d.ts +12 -0
  197. package/dist/types/tools/ToolNode.d.ts +12 -6
  198. package/dist/types/tools/subagent/SubagentReplay.d.ts +2 -0
  199. package/dist/types/tools/toolBatchReplay.d.ts +54 -0
  200. package/dist/types/tools/toolOutputReferences.d.ts +2 -0
  201. package/dist/types/types/graph.d.ts +20 -0
  202. package/dist/types/types/run.d.ts +4 -0
  203. package/dist/types/types/summarize.d.ts +4 -1
  204. package/dist/types/utils/tokens.d.ts +2 -1
  205. package/package.json +1 -1
  206. package/src/agents/AgentContext.ts +34 -3
  207. package/src/graphs/Graph.ts +465 -147
  208. package/src/graphs/MultiAgentGraph.ts +28 -6
  209. package/src/hitl/approvalReview.ts +209 -0
  210. package/src/hooks/types.ts +4 -1
  211. package/src/index.ts +1 -0
  212. package/src/langfuse.ts +67 -9
  213. package/src/langfuseToolOutputTracing.ts +91 -0
  214. package/src/langfuseTraceShaping.ts +17 -4
  215. package/src/llm/anthropic/utils/message_inputs.ts +5 -10
  216. package/src/llm/bedrock/utils/message_inputs.ts +2 -8
  217. package/src/llm/contextPressureMeter.ts +80 -12
  218. package/src/llm/openai/utils/index.ts +5 -4
  219. package/src/llm/prepareProviderRequest.ts +21 -16
  220. package/src/messages/alternation.ts +2 -15
  221. package/src/messages/budget.ts +439 -23
  222. package/src/messages/cache.ts +8 -9
  223. package/src/messages/core.ts +65 -95
  224. package/src/messages/format.ts +262 -78
  225. package/src/messages/index.ts +1 -1
  226. package/src/messages/prune.ts +31 -12
  227. package/src/messages/reasoningTypes.ts +23 -0
  228. package/src/messages/recency.ts +35 -179
  229. package/src/messages/toolHistoryProjection.ts +460 -0
  230. package/src/messages/toolResultTypes.ts +331 -100
  231. package/src/run.ts +44 -22
  232. package/src/session/AgentSession.ts +33 -16
  233. package/src/session/JsonlSessionStore.ts +6 -0
  234. package/src/session/sessionProjection.ts +126 -0
  235. package/src/stream.ts +14 -19
  236. package/src/summarization/index.ts +2 -0
  237. package/src/summarization/node.ts +62 -13
  238. package/src/summarization/shared.ts +23 -0
  239. package/src/tools/ToolNode.ts +518 -184
  240. package/src/tools/subagent/SubagentExecutor.ts +35 -6
  241. package/src/tools/subagent/SubagentReplay.ts +2 -2
  242. package/src/tools/toolBatchReplay.ts +395 -0
  243. package/src/tools/toolOutputReferences.ts +16 -0
  244. package/src/types/graph.ts +20 -0
  245. package/src/types/run.ts +4 -0
  246. package/src/types/summarize.ts +4 -1
  247. package/src/utils/events.ts +19 -0
  248. package/src/utils/tokens.ts +183 -0
@@ -2104,7 +2104,8 @@ function projectToolCallInputsInternal(
2104
2104
  messages: BaseMessage[],
2105
2105
  maxInputChars: number,
2106
2106
  dropIncompleteStreamContent: boolean,
2107
- fromIndex = 0
2107
+ fromIndex = 0,
2108
+ retainRawOpenAIToolCalls = true
2108
2109
  ): BaseMessage[] {
2109
2110
  const normalizedMaxInputChars = normalizeToolInputLimit(maxInputChars);
2110
2111
  let projectedMessages: BaseMessage[] | undefined;
@@ -2191,15 +2192,20 @@ function projectToolCallInputsInternal(
2191
2192
  }
2192
2193
  }
2193
2194
 
2194
- const additionalKwargsChanges: Record<string, unknown> =
2195
- rawAdditionalToolCallsProperty.accessor ? { tool_calls: undefined } : {};
2196
- const rawToolCalls = projectRawOpenAIToolCalls(
2197
- rawAdditionalToolCalls,
2198
- normalizedMaxInputChars,
2199
- canonicalArguments
2200
- );
2201
- if (rawToolCalls.changed) {
2202
- additionalKwargsChanges.tool_calls = rawToolCalls.value;
2195
+ const additionalKwargsChanges: Record<string, unknown> = {};
2196
+ if (!retainRawOpenAIToolCalls && rawAdditionalToolCallsProperty.found) {
2197
+ additionalKwargsChanges.tool_calls = undefined;
2198
+ } else if (rawAdditionalToolCallsProperty.accessor) {
2199
+ additionalKwargsChanges.tool_calls = undefined;
2200
+ } else {
2201
+ const rawToolCalls = projectRawOpenAIToolCalls(
2202
+ rawAdditionalToolCalls,
2203
+ normalizedMaxInputChars,
2204
+ canonicalArguments
2205
+ );
2206
+ if (rawToolCalls.changed) {
2207
+ additionalKwargsChanges.tool_calls = rawToolCalls.value;
2208
+ }
2203
2209
  }
2204
2210
  const legacyFunctionCall = projectLegacyFunctionCall(
2205
2211
  readPropertyWithoutAccessors(
@@ -2292,9 +2298,22 @@ export function projectToolCallInputs(
2292
2298
  */
2293
2299
  export function projectToolMessagesForProvider(
2294
2300
  messages: BaseMessage[],
2295
- maxInputChars: number
2301
+ maxInputChars: number,
2302
+ provider?: ProviderName
2296
2303
  ): BaseMessage[] {
2297
- return projectToolCallInputsInternal(messages, maxInputChars, true);
2304
+ const providerFamily =
2305
+ provider == null ? undefined : getProviderFamily(provider);
2306
+ const retainRawOpenAIToolCalls =
2307
+ provider == null ||
2308
+ provider === Providers.OPENAI ||
2309
+ providerFamily === 'openai';
2310
+ return projectToolCallInputsInternal(
2311
+ messages,
2312
+ maxInputChars,
2313
+ true,
2314
+ 0,
2315
+ retainRawOpenAIToolCalls
2316
+ );
2298
2317
  }
2299
2318
 
2300
2319
  function applyToolCallInputCaps(params: {
@@ -0,0 +1,23 @@
1
+ const REASONING_CONTENT_BLOCK_TYPES: ReadonlySet<string> = new Set([
2
+ 'think',
3
+ 'thinking',
4
+ 'thinking_delta',
5
+ 'redacted_thinking',
6
+ 'reasoning',
7
+ 'reasoning-delta',
8
+ 'reasoning_content',
9
+ ]);
10
+
11
+ /** Identifies every persisted or streamed reasoning content-block shape. */
12
+ export function isReasoningContentBlock(block: { type?: unknown }): boolean {
13
+ return (
14
+ typeof block.type === 'string' &&
15
+ REASONING_CONTENT_BLOCK_TYPES.has(block.type)
16
+ );
17
+ }
18
+
19
+ export function isAnthropicThinkingContentBlock(block: {
20
+ type?: unknown;
21
+ }): boolean {
22
+ return block.type === 'thinking';
23
+ }
@@ -1,24 +1,17 @@
1
- import type {
2
- AIMessage,
3
- BaseMessage,
4
- ToolMessage,
5
- } from '@langchain/core/messages';
6
- import type {
7
- ProviderToolCallIndex,
8
- ProviderToolCallPartDescriptor,
9
- ProviderToolResultPartDescriptor,
10
- } from './toolResultTypes';
11
- import { getProviderSourceMessageIds } from './provenance';
1
+ import type { BaseMessage } from '@langchain/core/messages';
2
+ import type { ProviderToolCallIndex } from './toolResultTypes';
3
+ import type { ProviderName } from '@/types/llm';
12
4
  import {
5
+ appendProviderMessageToolCalls,
13
6
  appendProviderToolCallDescriptor,
14
7
  consumeProviderToolResultPair,
15
8
  getBoundedProviderPairingArray,
16
- getBoundedProviderPairingArrayProperty,
17
- getProviderAIMessageToolCallDescriptor,
9
+ getProviderMessageRole,
18
10
  getProviderToolCallPartDescriptor,
11
+ getProviderToolMessageResultDescriptor,
19
12
  getProviderToolResultPartDescriptor,
20
- PROVIDER_TOOL_PAIRING_MAX_IDENTIFIER_CHARS,
21
13
  } from './toolResultTypes';
14
+ import { getProviderSourceMessageIds } from './provenance';
22
15
 
23
16
  export const DEFAULT_RETAIN_RECENT_TURNS = 2;
24
17
  export const DEFAULT_INTRA_TURN_RETAIN_RATIO = 0.16;
@@ -28,6 +21,8 @@ export const DEFAULT_INTRA_TURN_RETAIN_RATIO = 0.16;
28
21
  * and a tail (to be preserved verbatim).
29
22
  */
30
23
  export interface RecencyWindowOptions {
24
+ /** Serving provider used to interpret generic `ChatMessage` roles. */
25
+ provider?: ProviderName;
31
26
  /**
32
27
  * Maximum number of recent user-led turns to keep in the tail. A "turn"
33
28
  * begins at a user-authored HumanMessage and includes every following
@@ -102,168 +97,21 @@ export function resolveIntraTurnRetainTokens({
102
97
  );
103
98
  }
104
99
 
105
- function readOwnString(value: unknown, key: string): string | undefined {
106
- if (value == null || typeof value !== 'object' || Array.isArray(value)) {
107
- return undefined;
108
- }
109
- try {
110
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
111
- return descriptor != null &&
112
- 'value' in descriptor &&
113
- typeof descriptor.value === 'string' &&
114
- descriptor.value !== '' &&
115
- descriptor.value.length <= PROVIDER_TOOL_PAIRING_MAX_IDENTIFIER_CHARS
116
- ? descriptor.value
117
- : undefined;
118
- } catch {
119
- return undefined;
120
- }
121
- }
122
-
123
- function readOwnValue(value: unknown, key: string): unknown {
124
- if (value == null || typeof value !== 'object' || Array.isArray(value)) {
125
- return undefined;
126
- }
127
- try {
128
- const descriptor = Object.getOwnPropertyDescriptor(value, key);
129
- return descriptor != null && 'value' in descriptor
130
- ? descriptor.value
131
- : undefined;
132
- } catch {
133
- return undefined;
134
- }
135
- }
136
-
137
- const LEGACY_FUNCTION_CALL_PREFIX = 'legacy_function:';
138
-
139
- function getLegacyFunctionCallId(name: string): string | undefined {
140
- const callId = `${LEGACY_FUNCTION_CALL_PREFIX}${name}`;
141
- return callId.length <= PROVIDER_TOOL_PAIRING_MAX_IDENTIFIER_CHARS
142
- ? callId
143
- : undefined;
144
- }
145
-
146
- function getRawToolCallDescriptor(
147
- toolCall: unknown
148
- ): ProviderToolCallPartDescriptor | undefined {
149
- const callId = readOwnString(toolCall, 'id');
150
- if (callId == null) {
151
- return undefined;
152
- }
153
- let name: string | undefined;
154
- if (toolCall != null && typeof toolCall === 'object') {
155
- try {
156
- const property = Object.getOwnPropertyDescriptor(toolCall, 'function');
157
- name =
158
- property != null && 'value' in property
159
- ? readOwnString(property.value, 'name')
160
- : undefined;
161
- } catch {
162
- return undefined;
163
- }
164
- }
165
- return {
166
- callId,
167
- kind: 'tool',
168
- sourceType: 'raw_tool_calls',
169
- ...(name == null ? {} : { name }),
170
- };
171
- }
172
-
173
- function appendMessageToolCalls(
174
- message: BaseMessage,
175
- calls: ProviderToolCallIndex
176
- ): void {
177
- const messageRole = (message as BaseMessage & { role?: unknown }).role;
178
- if (message.getType() !== 'ai' && messageRole !== 'assistant') {
179
- return;
180
- }
181
-
182
- for (const toolCall of (message as AIMessage).tool_calls ?? []) {
183
- const descriptor = getProviderAIMessageToolCallDescriptor(toolCall);
184
- if (descriptor != null) {
185
- appendProviderToolCallDescriptor(calls, descriptor);
186
- }
187
- }
188
-
189
- const rawToolCalls = getBoundedProviderPairingArrayProperty(
190
- message.additional_kwargs,
191
- 'tool_calls'
192
- );
193
- if (rawToolCalls != null) {
194
- for (const toolCall of rawToolCalls) {
195
- const descriptor = getRawToolCallDescriptor(toolCall);
196
- if (descriptor != null) {
197
- appendProviderToolCallDescriptor(calls, descriptor);
198
- }
199
- }
200
- }
201
-
202
- const legacyFunctionCall = readOwnValue(
203
- message.additional_kwargs,
204
- 'function_call'
205
- );
206
- const legacyFunctionName = readOwnString(legacyFunctionCall, 'name');
207
- const legacyFunctionCallId =
208
- legacyFunctionName == null
209
- ? undefined
210
- : getLegacyFunctionCallId(legacyFunctionName);
211
- if (legacyFunctionCallId != null) {
212
- appendProviderToolCallDescriptor(calls, {
213
- callId: legacyFunctionCallId,
214
- kind: 'tool',
215
- name: legacyFunctionName,
216
- sourceType: 'legacy_function_call',
217
- });
218
- }
219
- }
220
-
221
- function getToolMessageResultDescriptor(
222
- message: BaseMessage
223
- ): ProviderToolResultPartDescriptor | undefined {
224
- if (message.getType() === 'function' && message.name != null) {
225
- const toolCallId = getLegacyFunctionCallId(message.name);
226
- return toolCallId == null
227
- ? undefined
228
- : {
229
- type: 'function_message',
230
- toolCallId,
231
- compatibleCallKinds: ['tool'],
232
- expectedToolNames: [message.name],
233
- };
234
- }
235
- if (message.getType() !== 'tool') {
236
- return undefined;
237
- }
238
- const toolMessage = message as ToolMessage & { toolCallId?: unknown };
239
- const toolCallId =
240
- typeof toolMessage.tool_call_id === 'string'
241
- ? toolMessage.tool_call_id
242
- : toolMessage.toolCallId;
243
- return typeof toolCallId === 'string' &&
244
- toolCallId !== '' &&
245
- toolCallId.length <= PROVIDER_TOOL_PAIRING_MAX_IDENTIFIER_CHARS
246
- ? {
247
- type: 'tool_message',
248
- toolCallId,
249
- compatibleCallKinds: ['tool'],
250
- }
251
- : undefined;
252
- }
253
-
254
100
  interface MessagePairingResult {
255
101
  completedToolCalls: number;
256
102
  trustedHumanToolResult: boolean;
103
+ userMessage: boolean;
257
104
  }
258
105
 
259
106
  function inspectMessagePairing(
260
107
  message: BaseMessage,
261
- calls: ProviderToolCallIndex
108
+ calls: ProviderToolCallIndex,
109
+ provider?: ProviderName
262
110
  ): MessagePairingResult {
263
- const isHuman = message.getType() === 'human';
111
+ const isHuman = getProviderMessageRole(message, provider) === 'user';
264
112
  const candidateCalls = isHuman ? new Map(calls) : calls;
265
113
  if (!isHuman) {
266
- appendMessageToolCalls(message, candidateCalls);
114
+ appendProviderMessageToolCalls(message, candidateCalls, provider);
267
115
  }
268
116
  const content = getBoundedProviderPairingArray(message.content);
269
117
  let completedToolCalls = 0;
@@ -300,7 +148,10 @@ function inspectMessagePairing(
300
148
  }
301
149
  }
302
150
 
303
- const toolMessageResult = getToolMessageResultDescriptor(message);
151
+ const toolMessageResult = getProviderToolMessageResultDescriptor(
152
+ message,
153
+ provider
154
+ );
304
155
  if (
305
156
  toolMessageResult != null &&
306
157
  consumeProviderToolResultPair(toolMessageResult, candidateCalls)
@@ -319,20 +170,23 @@ function inspectMessagePairing(
319
170
  }
320
171
  }
321
172
  return {
322
- completedToolCalls: isHuman && !trustedHumanToolResult
323
- ? 0
324
- : completedToolCalls,
173
+ completedToolCalls:
174
+ isHuman && !trustedHumanToolResult ? 0 : completedToolCalls,
325
175
  trustedHumanToolResult,
176
+ userMessage: isHuman,
326
177
  };
327
178
  }
328
179
 
329
- function findTurnStarts(messages: BaseMessage[]): number[] {
180
+ function findTurnStarts(
181
+ messages: BaseMessage[],
182
+ provider?: ProviderName
183
+ ): number[] {
330
184
  const turnStarts: number[] = [];
331
185
  const calls: ProviderToolCallIndex = new Map();
332
186
  for (let i = 0; i < messages.length; i++) {
333
187
  const message = messages[i] as BaseMessage;
334
- const pairing = inspectMessagePairing(message, calls);
335
- if (message.getType() !== 'human' || pairing.trustedHumanToolResult) {
188
+ const pairing = inspectMessagePairing(message, calls, provider);
189
+ if (!pairing.userMessage || pairing.trustedHumanToolResult) {
336
190
  continue;
337
191
  }
338
192
  turnStarts.push(i);
@@ -354,7 +208,8 @@ function findIntraTurnBoundary(
354
208
  messages: BaseMessage[],
355
209
  countMessageAt: (index: number) => number,
356
210
  retainTokens: number,
357
- earliestRetainedTurnEndIndex: number
211
+ earliestRetainedTurnEndIndex: number,
212
+ provider?: ProviderName
358
213
  ): number | undefined {
359
214
  let remainingTokens = 0;
360
215
  for (let i = 0; i < messages.length; i++) {
@@ -387,9 +242,9 @@ function findIntraTurnBoundary(
387
242
  const message = messages[i] as BaseMessage;
388
243
  remainingTokens -= countMessageAt(i);
389
244
 
390
- const pairing = inspectMessagePairing(message, pendingToolCalls);
245
+ const pairing = inspectMessagePairing(message, pendingToolCalls, provider);
391
246
  completedToolCalls += pairing.completedToolCalls;
392
- if (message.getType() === 'human' && !pairing.trustedHumanToolResult) {
247
+ if (pairing.userMessage && !pairing.trustedHumanToolResult) {
393
248
  pendingToolCalls.clear();
394
249
  }
395
250
 
@@ -408,7 +263,7 @@ function findIntraTurnBoundary(
408
263
  completedToolCalls > 0 &&
409
264
  pendingToolCalls.size === 0 &&
410
265
  straddlingSourceIds.size === 0 &&
411
- (message.getType() !== 'human' || pairing.trustedHumanToolResult)
266
+ (!pairing.userMessage || pairing.trustedHumanToolResult)
412
267
  ) {
413
268
  boundary = i + 1;
414
269
  }
@@ -450,7 +305,7 @@ export function splitAtRecencyBoundary(
450
305
  };
451
306
  }
452
307
 
453
- const turnStarts = findTurnStarts(messages);
308
+ const turnStarts = findTurnStarts(messages, options.provider);
454
309
 
455
310
  if (turnStarts.length === 0) {
456
311
  return {
@@ -535,7 +390,8 @@ export function splitAtRecencyBoundary(
535
390
  messages,
536
391
  countMessageAt,
537
392
  intraTurnTokens,
538
- turnStarts[1] ?? messages.length
393
+ turnStarts[1] ?? messages.length,
394
+ options.provider
539
395
  );
540
396
  if (intraTurnBoundary != null) {
541
397
  return {