@illuma-ai/agents 1.5.1 → 2.1.1

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 (319) hide show
  1. package/README.md +0 -62
  2. package/dist/cjs/agents/AgentContext.cjs +160 -259
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/enum.cjs +12 -12
  5. package/dist/cjs/common/enum.cjs.map +1 -1
  6. package/dist/cjs/graphs/Graph.cjs +30 -13
  7. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  8. package/dist/cjs/graphs/MultiAgentGraph.cjs +1 -1
  9. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  10. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs +1 -1
  11. package/dist/cjs/graphs/phases/memoryFlushPhase.cjs.map +1 -1
  12. package/dist/cjs/hooks/HookRegistry.cjs +1 -1
  13. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  14. package/dist/cjs/hooks/matchers.cjs +2 -2
  15. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  16. package/dist/cjs/hooks/types.cjs +1 -1
  17. package/dist/cjs/hooks/types.cjs.map +1 -1
  18. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +1 -5
  19. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  20. package/dist/cjs/llm/bedrock/index.cjs +33 -61
  21. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  22. package/dist/cjs/llm/openai/index.cjs +1 -1
  23. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  24. package/dist/cjs/llm/openai/utils/index.cjs +10 -27
  25. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  26. package/dist/cjs/main.cjs +3 -84
  27. package/dist/cjs/main.cjs.map +1 -1
  28. package/dist/cjs/memory/citations.cjs +4 -4
  29. package/dist/cjs/memory/citations.cjs.map +1 -1
  30. package/dist/cjs/memory/constants.cjs +17 -17
  31. package/dist/cjs/memory/constants.cjs.map +1 -1
  32. package/dist/cjs/memory/mmr.cjs +1 -1
  33. package/dist/cjs/memory/mmr.cjs.map +1 -1
  34. package/dist/cjs/memory/paths.cjs +1 -1
  35. package/dist/cjs/memory/paths.cjs.map +1 -1
  36. package/dist/cjs/memory/recallTracking.cjs +3 -3
  37. package/dist/cjs/memory/recallTracking.cjs.map +1 -1
  38. package/dist/cjs/memory/temporalDecay.cjs +2 -2
  39. package/dist/cjs/memory/temporalDecay.cjs.map +1 -1
  40. package/dist/cjs/messages/cache.cjs +0 -89
  41. package/dist/cjs/messages/cache.cjs.map +1 -1
  42. package/dist/cjs/messages/format.cjs +13 -71
  43. package/dist/cjs/messages/format.cjs.map +1 -1
  44. package/dist/cjs/tools/BashExecutor.cjs +11 -21
  45. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  46. package/dist/cjs/tools/CodeExecutor.cjs +13 -41
  47. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  48. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +11 -16
  49. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  50. package/dist/cjs/tools/ToolNode.cjs +78 -13
  51. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  52. package/dist/cjs/tools/memory/memoryAppendTool.cjs +1 -1
  53. package/dist/cjs/tools/memory/memoryAppendTool.cjs.map +1 -1
  54. package/dist/cjs/tools/memory/memoryGetTool.cjs +2 -2
  55. package/dist/cjs/tools/memory/memoryGetTool.cjs.map +1 -1
  56. package/dist/cjs/tools/memory/memorySearchTool.cjs +3 -3
  57. package/dist/cjs/tools/memory/memorySearchTool.cjs.map +1 -1
  58. package/dist/cjs/tools/memory/shared.cjs +1 -1
  59. package/dist/cjs/tools/memory/shared.cjs.map +1 -1
  60. package/dist/cjs/tools/search/search.cjs +3 -11
  61. package/dist/cjs/tools/search/search.cjs.map +1 -1
  62. package/dist/cjs/tools/search/tool.cjs +4 -28
  63. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  64. package/dist/cjs/tools/search/utils.cjs +3 -10
  65. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  66. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +48 -0
  67. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  68. package/dist/cjs/types/graph.cjs.map +1 -1
  69. package/dist/esm/agents/AgentContext.mjs +160 -259
  70. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  71. package/dist/esm/common/enum.mjs +12 -12
  72. package/dist/esm/common/enum.mjs.map +1 -1
  73. package/dist/esm/graphs/Graph.mjs +30 -13
  74. package/dist/esm/graphs/Graph.mjs.map +1 -1
  75. package/dist/esm/graphs/MultiAgentGraph.mjs +1 -1
  76. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  77. package/dist/esm/graphs/phases/memoryFlushPhase.mjs +1 -1
  78. package/dist/esm/graphs/phases/memoryFlushPhase.mjs.map +1 -1
  79. package/dist/esm/hooks/HookRegistry.mjs +1 -1
  80. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  81. package/dist/esm/hooks/matchers.mjs +2 -2
  82. package/dist/esm/hooks/matchers.mjs.map +1 -1
  83. package/dist/esm/hooks/types.mjs +1 -1
  84. package/dist/esm/hooks/types.mjs.map +1 -1
  85. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +1 -5
  86. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  87. package/dist/esm/llm/bedrock/index.mjs +34 -61
  88. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  89. package/dist/esm/llm/openai/index.mjs +1 -1
  90. package/dist/esm/llm/openai/index.mjs.map +1 -1
  91. package/dist/esm/llm/openai/utils/index.mjs +10 -27
  92. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  93. package/dist/esm/main.mjs +1 -5
  94. package/dist/esm/main.mjs.map +1 -1
  95. package/dist/esm/memory/citations.mjs +4 -4
  96. package/dist/esm/memory/citations.mjs.map +1 -1
  97. package/dist/esm/memory/constants.mjs +17 -17
  98. package/dist/esm/memory/constants.mjs.map +1 -1
  99. package/dist/esm/memory/mmr.mjs +1 -1
  100. package/dist/esm/memory/mmr.mjs.map +1 -1
  101. package/dist/esm/memory/paths.mjs +1 -1
  102. package/dist/esm/memory/paths.mjs.map +1 -1
  103. package/dist/esm/memory/recallTracking.mjs +3 -3
  104. package/dist/esm/memory/recallTracking.mjs.map +1 -1
  105. package/dist/esm/memory/temporalDecay.mjs +2 -2
  106. package/dist/esm/memory/temporalDecay.mjs.map +1 -1
  107. package/dist/esm/messages/cache.mjs +0 -89
  108. package/dist/esm/messages/cache.mjs.map +1 -1
  109. package/dist/esm/messages/format.mjs +13 -71
  110. package/dist/esm/messages/format.mjs.map +1 -1
  111. package/dist/esm/tools/BashExecutor.mjs +12 -22
  112. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  113. package/dist/esm/tools/CodeExecutor.mjs +14 -41
  114. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  115. package/dist/esm/tools/ProgrammaticToolCalling.mjs +12 -17
  116. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  117. package/dist/esm/tools/ToolNode.mjs +78 -13
  118. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  119. package/dist/esm/tools/memory/memoryAppendTool.mjs +1 -1
  120. package/dist/esm/tools/memory/memoryAppendTool.mjs.map +1 -1
  121. package/dist/esm/tools/memory/memoryGetTool.mjs +2 -2
  122. package/dist/esm/tools/memory/memoryGetTool.mjs.map +1 -1
  123. package/dist/esm/tools/memory/memorySearchTool.mjs +3 -3
  124. package/dist/esm/tools/memory/memorySearchTool.mjs.map +1 -1
  125. package/dist/esm/tools/memory/shared.mjs +1 -1
  126. package/dist/esm/tools/memory/shared.mjs.map +1 -1
  127. package/dist/esm/tools/search/search.mjs +3 -11
  128. package/dist/esm/tools/search/search.mjs.map +1 -1
  129. package/dist/esm/tools/search/tool.mjs +4 -28
  130. package/dist/esm/tools/search/tool.mjs.map +1 -1
  131. package/dist/esm/tools/search/utils.mjs +3 -10
  132. package/dist/esm/tools/search/utils.mjs.map +1 -1
  133. package/dist/esm/tools/subagent/SubagentExecutor.mjs +48 -0
  134. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  135. package/dist/esm/types/graph.mjs.map +1 -1
  136. package/dist/types/agents/AgentContext.d.ts +25 -95
  137. package/dist/types/common/enum.d.ts +12 -12
  138. package/dist/types/graphs/Graph.d.ts +2 -2
  139. package/dist/types/graphs/phases/memoryFlushPhase.d.ts +2 -2
  140. package/dist/types/hooks/HookRegistry.d.ts +1 -1
  141. package/dist/types/hooks/matchers.d.ts +2 -2
  142. package/dist/types/hooks/types.d.ts +1 -1
  143. package/dist/types/index.d.ts +0 -1
  144. package/dist/types/llm/bedrock/index.d.ts +1 -54
  145. package/dist/types/llm/openai/index.d.ts +1 -1
  146. package/dist/types/memory/citations.d.ts +4 -4
  147. package/dist/types/memory/constants.d.ts +17 -17
  148. package/dist/types/memory/mmr.d.ts +3 -3
  149. package/dist/types/memory/paths.d.ts +1 -1
  150. package/dist/types/memory/temporalDecay.d.ts +2 -2
  151. package/dist/types/memory/types.d.ts +3 -3
  152. package/dist/types/messages/format.d.ts +2 -5
  153. package/dist/types/tools/CodeExecutor.d.ts +0 -6
  154. package/dist/types/tools/ToolNode.d.ts +3 -3
  155. package/dist/types/tools/memory/shared.d.ts +1 -1
  156. package/dist/types/tools/search/test.d.ts +1 -0
  157. package/dist/types/tools/search/types.d.ts +5 -99
  158. package/dist/types/tools/search/utils.d.ts +2 -2
  159. package/dist/types/tools/subagent/SubagentExecutor.d.ts +29 -0
  160. package/dist/types/types/graph.d.ts +30 -34
  161. package/dist/types/types/index.d.ts +0 -1
  162. package/dist/types/types/messages.d.ts +1 -1
  163. package/dist/types/types/run.d.ts +1 -3
  164. package/dist/types/types/tools.d.ts +5 -14
  165. package/package.json +1 -61
  166. package/src/agents/AgentContext.test.ts +176 -0
  167. package/src/agents/AgentContext.ts +179 -305
  168. package/src/agents/__tests__/AgentContext.test.ts +0 -632
  169. package/src/common/__tests__/enum.test.ts +1 -1
  170. package/src/common/enum.ts +12 -12
  171. package/src/graphs/Graph.ts +32 -13
  172. package/src/graphs/MultiAgentGraph.ts +1 -1
  173. package/src/graphs/gapFeatures.test.ts +1 -1
  174. package/src/graphs/phases/__tests__/memoryFlushPhase.test.ts +1 -1
  175. package/src/graphs/phases/memoryFlushPhase.ts +2 -2
  176. package/src/hooks/HookRegistry.ts +1 -1
  177. package/src/hooks/index.ts +1 -1
  178. package/src/hooks/matchers.ts +2 -2
  179. package/src/hooks/types.ts +1 -1
  180. package/src/index.ts +0 -6
  181. package/src/llm/anthropic/utils/message_inputs.ts +1 -10
  182. package/src/llm/bedrock/__tests__/bedrock-caching.test.ts +18 -166
  183. package/src/llm/bedrock/index.ts +41 -116
  184. package/src/llm/openai/index.ts +2 -2
  185. package/src/llm/openai/utils/index.ts +14 -31
  186. package/src/memory/citations.ts +4 -4
  187. package/src/memory/constants.ts +17 -17
  188. package/src/memory/mmr.ts +3 -3
  189. package/src/memory/paths.ts +1 -1
  190. package/src/memory/recallTracking.ts +3 -3
  191. package/src/memory/temporalDecay.ts +2 -2
  192. package/src/memory/types.ts +3 -3
  193. package/src/messages/cache.test.ts +24 -62
  194. package/src/messages/cache.ts +0 -112
  195. package/src/messages/ensureThinkingBlock.test.ts +1 -1
  196. package/src/messages/format.ts +13 -92
  197. package/src/messages/formatAgentMessages.test.ts +1 -1
  198. package/src/scripts/subagent-configurable-inheritance.ts +263 -0
  199. package/src/scripts/subagent-event-driven-debug.ts +2 -2
  200. package/src/specs/anthropic.simple.test.ts +0 -61
  201. package/src/specs/prune.orphans.test.ts +1 -1
  202. package/src/tools/BashExecutor.ts +13 -37
  203. package/src/tools/CodeExecutor.ts +14 -59
  204. package/src/tools/ProgrammaticToolCalling.ts +14 -29
  205. package/src/tools/ToolNode.ts +75 -14
  206. package/src/tools/__tests__/CodeExecutor.test.ts +3 -3
  207. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +0 -60
  208. package/src/tools/__tests__/SubagentExecutor.test.ts +157 -0
  209. package/src/tools/memory/memoryAppendTool.ts +1 -1
  210. package/src/tools/memory/memoryGetTool.ts +2 -2
  211. package/src/tools/memory/memorySearchTool.ts +3 -3
  212. package/src/tools/memory/shared.ts +1 -1
  213. package/src/tools/search/output.md +2775 -0
  214. package/src/tools/search/search.ts +2 -12
  215. package/src/tools/search/test.html +884 -0
  216. package/src/tools/search/test.md +643 -0
  217. package/src/tools/search/test.ts +159 -0
  218. package/src/tools/search/tool.ts +2 -36
  219. package/src/tools/search/types.ts +8 -133
  220. package/src/tools/search/utils.ts +5 -13
  221. package/src/tools/subagent/SubagentExecutor.ts +78 -0
  222. package/src/types/graph.ts +27 -34
  223. package/src/types/index.ts +0 -1
  224. package/src/types/messages.ts +1 -1
  225. package/src/types/run.ts +1 -3
  226. package/src/types/tools.ts +5 -14
  227. package/dist/cjs/langchain/google-common.cjs +0 -3
  228. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  229. package/dist/cjs/langchain/index.cjs +0 -86
  230. package/dist/cjs/langchain/index.cjs.map +0 -1
  231. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  232. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  233. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  234. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  235. package/dist/cjs/langchain/messages.cjs +0 -51
  236. package/dist/cjs/langchain/messages.cjs.map +0 -1
  237. package/dist/cjs/langchain/openai.cjs +0 -3
  238. package/dist/cjs/langchain/openai.cjs.map +0 -1
  239. package/dist/cjs/langchain/prompts.cjs +0 -11
  240. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  241. package/dist/cjs/langchain/runnables.cjs +0 -19
  242. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  243. package/dist/cjs/langchain/tools.cjs +0 -23
  244. package/dist/cjs/langchain/tools.cjs.map +0 -1
  245. package/dist/cjs/langchain/utils/env.cjs +0 -11
  246. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  247. package/dist/cjs/llm/bedrock/cacheSupport.cjs +0 -55
  248. package/dist/cjs/llm/bedrock/cacheSupport.cjs.map +0 -1
  249. package/dist/cjs/tools/search/tavily-scraper.cjs +0 -189
  250. package/dist/cjs/tools/search/tavily-scraper.cjs.map +0 -1
  251. package/dist/cjs/tools/search/tavily-search.cjs +0 -372
  252. package/dist/cjs/tools/search/tavily-search.cjs.map +0 -1
  253. package/dist/cjs/types/agent-cache.cjs +0 -54
  254. package/dist/cjs/types/agent-cache.cjs.map +0 -1
  255. package/dist/esm/langchain/google-common.mjs +0 -2
  256. package/dist/esm/langchain/google-common.mjs.map +0 -1
  257. package/dist/esm/langchain/index.mjs +0 -5
  258. package/dist/esm/langchain/index.mjs.map +0 -1
  259. package/dist/esm/langchain/language_models/chat_models.mjs +0 -2
  260. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  261. package/dist/esm/langchain/messages/tool.mjs +0 -2
  262. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  263. package/dist/esm/langchain/messages.mjs +0 -2
  264. package/dist/esm/langchain/messages.mjs.map +0 -1
  265. package/dist/esm/langchain/openai.mjs +0 -2
  266. package/dist/esm/langchain/openai.mjs.map +0 -1
  267. package/dist/esm/langchain/prompts.mjs +0 -2
  268. package/dist/esm/langchain/prompts.mjs.map +0 -1
  269. package/dist/esm/langchain/runnables.mjs +0 -2
  270. package/dist/esm/langchain/runnables.mjs.map +0 -1
  271. package/dist/esm/langchain/tools.mjs +0 -2
  272. package/dist/esm/langchain/tools.mjs.map +0 -1
  273. package/dist/esm/langchain/utils/env.mjs +0 -2
  274. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  275. package/dist/esm/llm/bedrock/cacheSupport.mjs +0 -52
  276. package/dist/esm/llm/bedrock/cacheSupport.mjs.map +0 -1
  277. package/dist/esm/tools/search/tavily-scraper.mjs +0 -186
  278. package/dist/esm/tools/search/tavily-scraper.mjs.map +0 -1
  279. package/dist/esm/tools/search/tavily-search.mjs +0 -370
  280. package/dist/esm/tools/search/tavily-search.mjs.map +0 -1
  281. package/dist/esm/types/agent-cache.mjs +0 -52
  282. package/dist/esm/types/agent-cache.mjs.map +0 -1
  283. package/dist/types/langchain/google-common.d.ts +0 -1
  284. package/dist/types/langchain/index.d.ts +0 -8
  285. package/dist/types/langchain/language_models/chat_models.d.ts +0 -1
  286. package/dist/types/langchain/messages/tool.d.ts +0 -1
  287. package/dist/types/langchain/messages.d.ts +0 -2
  288. package/dist/types/langchain/openai.d.ts +0 -1
  289. package/dist/types/langchain/prompts.d.ts +0 -1
  290. package/dist/types/langchain/runnables.d.ts +0 -2
  291. package/dist/types/langchain/tools.d.ts +0 -2
  292. package/dist/types/langchain/utils/env.d.ts +0 -1
  293. package/dist/types/llm/bedrock/cacheSupport.d.ts +0 -35
  294. package/dist/types/tools/search/tavily-scraper.d.ts +0 -19
  295. package/dist/types/tools/search/tavily-search.d.ts +0 -4
  296. package/dist/types/tools/subagent/types.d.ts +0 -84
  297. package/dist/types/types/agent-cache.d.ts +0 -71
  298. package/src/agents/__tests__/AgentContext.cacheTtl.live.test.ts +0 -259
  299. package/src/agents/__tests__/AgentContext.crossAgentTier1.live.test.ts +0 -266
  300. package/src/agents/__tests__/AgentContext.crossUserCache.live.test.ts +0 -342
  301. package/src/langchain/google-common.ts +0 -1
  302. package/src/langchain/index.ts +0 -8
  303. package/src/langchain/language_models/chat_models.ts +0 -1
  304. package/src/langchain/messages/tool.ts +0 -5
  305. package/src/langchain/messages.ts +0 -21
  306. package/src/langchain/openai.ts +0 -1
  307. package/src/langchain/prompts.ts +0 -1
  308. package/src/langchain/runnables.ts +0 -7
  309. package/src/langchain/tools.ts +0 -8
  310. package/src/langchain/utils/env.ts +0 -1
  311. package/src/llm/anthropic/utils/server-tool-inputs.test.ts +0 -436
  312. package/src/llm/bedrock/cacheSupport.test.ts +0 -99
  313. package/src/llm/bedrock/cacheSupport.ts +0 -53
  314. package/src/tools/search/tavily-scraper.ts +0 -235
  315. package/src/tools/search/tavily-search.ts +0 -424
  316. package/src/tools/search/tavily.test.ts +0 -965
  317. package/src/tools/subagent/types.test.ts +0 -70
  318. package/src/tools/subagent/types.ts +0 -115
  319. package/src/types/agent-cache.ts +0 -74
@@ -1,436 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { AIMessage, HumanMessage, ToolMessage } from '@langchain/core/messages';
3
- import type { BaseMessage } from '@langchain/core/messages';
4
- import { _convertMessagesToAnthropicPayload } from './message_inputs';
5
-
6
- describe('_convertMessagesToAnthropicPayload — server tool use (web search) multi-turn', () => {
7
- /* Skipped: this fork intentionally diverged from the reference implementation's
8
- * `_convertLangChainToolCallToAnthropic` — local always emits
9
- * `tool_use` regardless of `srvtoolu_` ID prefix (see message_inputs.ts
10
- * line ~144). These tests assert the standard server_tool_use emission
11
- * which this fork does not implement. The text→server_tool_use correction
12
- * test (next, "corrects text-typed server tool blocks") still passes
13
- * because that path lives in `_formatContent`. */
14
- it.skip('corrects tool_use blocks with srvtoolu_ IDs to server_tool_use', () => {
15
- const messageHistory: BaseMessage[] = [
16
- new HumanMessage('search for X and Y'),
17
- new AIMessage({
18
- content: [
19
- { type: 'text', text: 'I will search for that.' },
20
- {
21
- type: 'tool_use',
22
- id: 'srvtoolu_1',
23
- name: 'web_search',
24
- input: { query: 'X' },
25
- },
26
- {
27
- type: 'web_search_tool_result',
28
- tool_use_id: 'srvtoolu_1',
29
- content: [
30
- {
31
- type: 'web_search_result',
32
- url: 'https://example.com',
33
- title: 'Result',
34
- encrypted_content: 'abc',
35
- page_age: '1d',
36
- },
37
- ],
38
- },
39
- {
40
- type: 'tool_use',
41
- id: 'srvtoolu_2',
42
- name: 'web_search',
43
- input: { query: 'Y' },
44
- },
45
- {
46
- type: 'web_search_tool_result',
47
- tool_use_id: 'srvtoolu_2',
48
- content: [
49
- {
50
- type: 'web_search_result',
51
- url: 'https://example2.com',
52
- title: 'Result 2',
53
- encrypted_content: 'def',
54
- page_age: '2d',
55
- },
56
- ],
57
- },
58
- { type: 'text', text: 'Here are the results.' },
59
- ],
60
- tool_calls: [
61
- {
62
- id: 'srvtoolu_1',
63
- name: 'web_search',
64
- args: { query: 'X' },
65
- type: 'tool_call',
66
- },
67
- {
68
- id: 'srvtoolu_2',
69
- name: 'web_search',
70
- args: { query: 'Y' },
71
- type: 'tool_call',
72
- },
73
- ],
74
- }),
75
- new HumanMessage('follow up question'),
76
- ];
77
-
78
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
79
- expect(messages).toHaveLength(3);
80
-
81
- const assistantContent = messages[1].content as any[];
82
- const serverToolBlocks = assistantContent.filter(
83
- (b: any) => b.type === 'server_tool_use'
84
- );
85
- const searchResultBlocks = assistantContent.filter(
86
- (b: any) => b.type === 'web_search_tool_result'
87
- );
88
- const regularToolUseBlocks = assistantContent.filter(
89
- (b: any) => b.type === 'tool_use' && b.id?.startsWith('srvtoolu_')
90
- );
91
-
92
- expect(serverToolBlocks).toHaveLength(2);
93
- expect(searchResultBlocks).toHaveLength(2);
94
- expect(regularToolUseBlocks).toHaveLength(0);
95
-
96
- // Verify blocks are clean (no extra streaming properties)
97
- for (const b of serverToolBlocks) {
98
- expect(Object.keys(b).sort()).toEqual(
99
- ['id', 'input', 'name', 'type'].sort()
100
- );
101
- }
102
- for (const b of searchResultBlocks) {
103
- expect(Object.keys(b).sort()).toEqual(
104
- ['content', 'tool_use_id', 'type'].sort()
105
- );
106
- }
107
- });
108
-
109
- it('corrects text-typed server tool blocks back to correct types', () => {
110
- const messageHistory: BaseMessage[] = [
111
- new HumanMessage('search for X'),
112
- new AIMessage({
113
- content: [
114
- {
115
- type: 'text',
116
- id: 'srvtoolu_1',
117
- name: 'web_search',
118
- input: '{"query":"X"}',
119
- },
120
- {
121
- type: 'text',
122
- tool_use_id: 'srvtoolu_1',
123
- content: [
124
- {
125
- type: 'web_search_result',
126
- url: 'https://example.com',
127
- title: 'Result',
128
- encrypted_content: 'abc',
129
- page_age: '1d',
130
- },
131
- ],
132
- },
133
- { type: 'text', text: 'Found results.' },
134
- ],
135
- tool_calls: [
136
- {
137
- id: 'srvtoolu_1',
138
- name: 'web_search',
139
- args: { query: 'X' },
140
- type: 'tool_call',
141
- },
142
- ],
143
- }),
144
- new HumanMessage('follow up'),
145
- ];
146
-
147
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
148
- const assistantContent = messages[1].content as any[];
149
-
150
- expect(assistantContent[0]).toEqual({
151
- type: 'server_tool_use',
152
- id: 'srvtoolu_1',
153
- name: 'web_search',
154
- input: { query: 'X' },
155
- });
156
- expect(assistantContent[1].type).toBe('web_search_tool_result');
157
- expect(assistantContent[1].tool_use_id).toBe('srvtoolu_1');
158
- expect(assistantContent[2]).toEqual({
159
- type: 'text',
160
- text: 'Found results.',
161
- });
162
- });
163
-
164
- /* Skipped: depends on the standard server_tool_use emission, see header. */
165
- it.skip('filters server tool calls when content is a string', () => {
166
- const messageHistory: BaseMessage[] = [
167
- new HumanMessage('search for X'),
168
- new AIMessage({
169
- content: 'I searched and found results.',
170
- tool_calls: [
171
- {
172
- id: 'srvtoolu_1',
173
- name: 'web_search',
174
- args: { query: 'X' },
175
- type: 'tool_call',
176
- },
177
- {
178
- id: 'toolu_regular',
179
- name: 'calculator',
180
- args: { expr: '2+2' },
181
- type: 'tool_call',
182
- },
183
- ],
184
- }),
185
- new ToolMessage({
186
- content: '4',
187
- tool_call_id: 'toolu_regular',
188
- }),
189
- new HumanMessage('follow up'),
190
- ];
191
-
192
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
193
- const assistantContent = messages[1].content as any[];
194
-
195
- const toolUseBlocks = assistantContent.filter(
196
- (b: any) => b.type === 'tool_use'
197
- );
198
- expect(toolUseBlocks).toHaveLength(1);
199
- expect(toolUseBlocks[0].id).toBe('toolu_regular');
200
-
201
- const serverToolBlocks = assistantContent.filter((b: any) =>
202
- b.id?.startsWith('srvtoolu_')
203
- );
204
- expect(serverToolBlocks).toHaveLength(0);
205
- });
206
-
207
- /* Skipped: depends on the standard server_tool_use emission, see header. */
208
- it.skip('handles empty string content with only server tool calls', () => {
209
- const messageHistory: BaseMessage[] = [
210
- new HumanMessage('search for X'),
211
- new AIMessage({
212
- content: '',
213
- tool_calls: [
214
- {
215
- id: 'srvtoolu_1',
216
- name: 'web_search',
217
- args: { query: 'X' },
218
- type: 'tool_call',
219
- },
220
- ],
221
- }),
222
- new HumanMessage('follow up'),
223
- ];
224
-
225
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
226
- const assistantContent = messages[1].content as any[];
227
- expect(assistantContent).toHaveLength(1);
228
- expect(assistantContent[0].type).toBe('text');
229
- expect(assistantContent[0].text).toBe(' ');
230
- });
231
-
232
- /* Skipped: depends on the standard server_tool_use emission, see header. */
233
- it.skip('preserves regular tool_use blocks alongside corrected server tool blocks', () => {
234
- const messageHistory: BaseMessage[] = [
235
- new HumanMessage('search for X and calculate 2+2'),
236
- new AIMessage({
237
- content: [
238
- { type: 'text', text: 'Let me help.' },
239
- {
240
- type: 'tool_use',
241
- id: 'srvtoolu_1',
242
- name: 'web_search',
243
- input: { query: 'X' },
244
- },
245
- {
246
- type: 'web_search_tool_result',
247
- tool_use_id: 'srvtoolu_1',
248
- content: [
249
- {
250
- type: 'web_search_result',
251
- url: 'https://example.com',
252
- title: 'Result',
253
- encrypted_content: 'abc',
254
- page_age: '1d',
255
- },
256
- ],
257
- },
258
- {
259
- type: 'tool_use',
260
- id: 'toolu_calc',
261
- name: 'calculator',
262
- input: { expr: '2+2' },
263
- },
264
- ],
265
- tool_calls: [
266
- {
267
- id: 'srvtoolu_1',
268
- name: 'web_search',
269
- args: { query: 'X' },
270
- type: 'tool_call',
271
- },
272
- {
273
- id: 'toolu_calc',
274
- name: 'calculator',
275
- args: { expr: '2+2' },
276
- type: 'tool_call',
277
- },
278
- ],
279
- }),
280
- new ToolMessage({
281
- content: '4',
282
- tool_call_id: 'toolu_calc',
283
- }),
284
- new HumanMessage('follow up'),
285
- ];
286
-
287
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
288
- const assistantContent = messages[1].content as any[];
289
-
290
- const serverToolUse = assistantContent.filter(
291
- (b: any) => b.type === 'server_tool_use'
292
- );
293
- const webSearchResult = assistantContent.filter(
294
- (b: any) => b.type === 'web_search_tool_result'
295
- );
296
- const regularToolUse = assistantContent.filter(
297
- (b: any) => b.type === 'tool_use' && !b.id?.startsWith('srvtoolu_')
298
- );
299
-
300
- expect(serverToolUse).toHaveLength(1);
301
- expect(serverToolUse[0].id).toBe('srvtoolu_1');
302
- expect(webSearchResult).toHaveLength(1);
303
- expect(regularToolUse).toHaveLength(1);
304
- expect(regularToolUse[0].id).toBe('toolu_calc');
305
- });
306
-
307
- it('filters out empty text blocks from array content', () => {
308
- const messageHistory: BaseMessage[] = [
309
- new HumanMessage('search for X'),
310
- new AIMessage({
311
- content: [
312
- { type: 'text', text: '' },
313
- {
314
- type: 'server_tool_use',
315
- id: 'srvtoolu_1',
316
- name: 'web_search',
317
- input: { query: 'X' },
318
- },
319
- {
320
- type: 'web_search_tool_result',
321
- tool_use_id: 'srvtoolu_1',
322
- content: [
323
- {
324
- type: 'web_search_result',
325
- url: 'https://example.com',
326
- title: 'Result',
327
- encrypted_content: 'abc',
328
- page_age: '1d',
329
- },
330
- ],
331
- },
332
- { type: 'text', text: '' },
333
- { type: 'text', text: 'Here are the results.' },
334
- ],
335
- tool_calls: [
336
- {
337
- id: 'srvtoolu_1',
338
- name: 'web_search',
339
- args: { query: 'X' },
340
- type: 'tool_call',
341
- },
342
- ],
343
- }),
344
- new HumanMessage('follow up'),
345
- ];
346
-
347
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
348
- const assistantContent = messages[1].content as any[];
349
-
350
- const emptyTextBlocks = assistantContent.filter(
351
- (b: any) => b.type === 'text' && b.text === ''
352
- );
353
- expect(emptyTextBlocks).toHaveLength(0);
354
-
355
- const textBlocks = assistantContent.filter((b: any) => b.type === 'text');
356
- expect(textBlocks).toHaveLength(1);
357
- expect(textBlocks[0].text).toBe('Here are the results.');
358
- });
359
-
360
- /**
361
- * Regression for discussion #12806.
362
- *
363
- * Anthropic web_search responses can include text blocks whose text is
364
- * whitespace-only (e.g. ' ', '\n', '\t') alongside server_tool_use and
365
- * web_search_tool_result blocks. On follow-up turns the API rejects these
366
- * with: "messages: text content blocks must contain non-whitespace text".
367
- *
368
- * The empty-string check alone is insufficient — the filter must drop any
369
- * text block whose trimmed content is empty.
370
- */
371
- it.each([
372
- ['single space', ' '],
373
- ['newline', '\n'],
374
- ['tab', '\t'],
375
- ['multiple spaces', ' '],
376
- ['mixed whitespace', ' \n\t '],
377
- ])(
378
- 'filters whitespace-only text blocks from array content (%s)',
379
- (_label, whitespace) => {
380
- const messageHistory: BaseMessage[] = [
381
- new HumanMessage('search for X'),
382
- new AIMessage({
383
- content: [
384
- { type: 'text', text: whitespace },
385
- {
386
- type: 'server_tool_use',
387
- id: 'srvtoolu_1',
388
- name: 'web_search',
389
- input: { query: 'X' },
390
- },
391
- {
392
- type: 'web_search_tool_result',
393
- tool_use_id: 'srvtoolu_1',
394
- content: [
395
- {
396
- type: 'web_search_result',
397
- url: 'https://example.com',
398
- title: 'Result',
399
- encrypted_content: 'abc',
400
- page_age: '1d',
401
- },
402
- ],
403
- },
404
- { type: 'text', text: 'Here are the results.' },
405
- ],
406
- tool_calls: [
407
- {
408
- id: 'srvtoolu_1',
409
- name: 'web_search',
410
- args: { query: 'X' },
411
- type: 'tool_call',
412
- },
413
- ],
414
- }),
415
- new HumanMessage('follow up'),
416
- ];
417
-
418
- const { messages } = _convertMessagesToAnthropicPayload(messageHistory);
419
- const assistantContent = messages[1].content as any[];
420
-
421
- const whitespaceTextBlocks = assistantContent.filter(
422
- (b: any) =>
423
- b.type === 'text' &&
424
- typeof b.text === 'string' &&
425
- b.text.trim() === ''
426
- );
427
- expect(whitespaceTextBlocks).toHaveLength(0);
428
-
429
- const textBlocks = assistantContent.filter(
430
- (b: any) => b.type === 'text'
431
- );
432
- expect(textBlocks).toHaveLength(1);
433
- expect(textBlocks[0].text).toBe('Here are the results.');
434
- }
435
- );
436
- });
@@ -1,99 +0,0 @@
1
- import {
2
- DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS,
3
- isBedrockCacheSupported,
4
- } from './cacheSupport';
5
-
6
- describe('isBedrockCacheSupported', () => {
7
- describe('default allowlist — supported models', () => {
8
- const supported = [
9
- // Anthropic Claude direct
10
- 'anthropic.claude-3-5-sonnet-20241022-v2:0',
11
- 'anthropic.claude-3-haiku-20240307-v1:0',
12
- 'anthropic.claude-opus-4-5-20250514-v1:0',
13
- 'anthropic.claude-sonnet-4-5-20250929-v1:0',
14
- // Anthropic Claude via cross-region inference profile
15
- 'us.anthropic.claude-sonnet-4-5-20250929-v1:0',
16
- 'us.anthropic.claude-haiku-4-5-20251001-v1:0',
17
- 'eu.anthropic.claude-3-5-sonnet-20241022-v2:0',
18
- // Amazon Nova
19
- 'amazon.nova-pro-v1:0',
20
- 'amazon.nova-lite-v1:0',
21
- 'amazon.nova-canvas-v1:0',
22
- 'us.amazon.nova-pro-v1:0',
23
- ];
24
-
25
- for (const model of supported) {
26
- it(`accepts "${model}"`, () => {
27
- expect(isBedrockCacheSupported(model)).toBe(true);
28
- });
29
- }
30
- });
31
-
32
- describe('default allowlist — unsupported models', () => {
33
- const unsupported = [
34
- 'amazon.titan-text-premier-v1:0',
35
- 'amazon.titan-embed-text-v2:0',
36
- 'meta.llama3-1-405b-instruct-v1:0',
37
- 'meta.llama3-2-90b-instruct-v1:0',
38
- 'cohere.command-r-plus-v1:0',
39
- 'mistral.mistral-large-2402-v1:0',
40
- 'ai21.j2-ultra-v1',
41
- 'stability.sd3-5-large-v1:0',
42
- // Adversarial — substring match would falsely accept these
43
- 'meta.llama-claude-killer-v1', // contains "claude" but isn't an Anthropic model
44
- 'fake.anthropic-impersonator', // contains "anthropic" but wrong vendor
45
- ];
46
-
47
- for (const model of unsupported) {
48
- it(`rejects "${model}"`, () => {
49
- expect(isBedrockCacheSupported(model)).toBe(false);
50
- });
51
- }
52
- });
53
-
54
- describe('edge cases', () => {
55
- it('returns false for undefined', () => {
56
- expect(isBedrockCacheSupported(undefined)).toBe(false);
57
- });
58
-
59
- it('returns false for empty string', () => {
60
- expect(isBedrockCacheSupported('')).toBe(false);
61
- });
62
- });
63
-
64
- describe('consumer extension via additionalPatterns', () => {
65
- it('accepts model matching consumer-supplied pattern', () => {
66
- expect(
67
- isBedrockCacheSupported('mycorp.future-model-v1:0', [
68
- /^mycorp\.future-/i,
69
- ]),
70
- ).toBe(true);
71
- });
72
-
73
- it('still rejects models not in default OR consumer allowlist', () => {
74
- expect(
75
- isBedrockCacheSupported('cohere.command-r-plus-v1:0', [
76
- /^mycorp\./i,
77
- ]),
78
- ).toBe(false);
79
- });
80
-
81
- it('default allowlist still works alongside extensions', () => {
82
- // Both default + custom pattern work
83
- expect(
84
- isBedrockCacheSupported('anthropic.claude-3-haiku-20240307-v1:0', [
85
- /^mycorp\./i,
86
- ]),
87
- ).toBe(true);
88
- });
89
- });
90
-
91
- describe('DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS export', () => {
92
- it('is a non-empty readonly array of RegExp', () => {
93
- expect(DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS.length).toBeGreaterThan(0);
94
- for (const pattern of DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS) {
95
- expect(pattern).toBeInstanceOf(RegExp);
96
- }
97
- });
98
- });
99
- });
@@ -1,53 +0,0 @@
1
- /**
2
- * Bedrock prompt-cache model support detection.
3
- * ===============================================
4
- *
5
- * Bedrock prompt caching (via `cachePoint` blocks) is only supported on
6
- * specific model families. Other families silently reject or ignore the
7
- * markers. We maintain an allowlist instead of a substring heuristic so
8
- * a future model with an unfortunate name (e.g. `llama-claude-killer`)
9
- * doesn't accidentally match.
10
- *
11
- * Consumers can extend the allowlist with `bedrockCacheModelPatterns` in
12
- * `clientOptions` for proprietary or pre-release model IDs not yet in
13
- * the reference library.
14
- */
15
-
16
- /**
17
- * Default allowlist of Bedrock model ID patterns that support cachePoint.
18
- * Sourced from AWS Bedrock documentation (verified against us-east-1
19
- * 2026-05).
20
- *
21
- * Adding a new model: append a RegExp here AND add a regression test in
22
- * `cacheSupport.test.ts` covering at least one full model ID for that
23
- * family. Removing a model: do not remove without operator confirmation
24
- * — silent removal would suddenly stop emitting cachePoint markers and
25
- * regress cost savings.
26
- */
27
- export const DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS: readonly RegExp[] = [
28
- // Anthropic Claude family (anthropic.claude-* and us.anthropic.claude-*)
29
- /(?:^|[/.])anthropic\.claude-/i,
30
- /(?:^|\.)us\.anthropic\.claude-/i,
31
- // Amazon Nova family (nova-pro, nova-lite, nova-canvas, etc.)
32
- /(?:^|[/.])amazon\.nova-/i,
33
- /(?:^|\.)us\.amazon\.nova-/i,
34
- ];
35
-
36
- /**
37
- * Returns true when the given Bedrock model ID belongs to a family that
38
- * supports cachePoint blocks. `additionalPatterns` lets consumers extend
39
- * the allowlist for models the library doesn't know about yet.
40
- *
41
- * @param modelId Bedrock model ID (e.g. `us.anthropic.claude-sonnet-4-5-20250929-v1:0`)
42
- * @param additionalPatterns Extra patterns from consumer config
43
- */
44
- export function isBedrockCacheSupported(
45
- modelId: string | undefined,
46
- additionalPatterns?: readonly RegExp[],
47
- ): boolean {
48
- if (!modelId) return false;
49
- const allPatterns = additionalPatterns
50
- ? [...DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS, ...additionalPatterns]
51
- : DEFAULT_BEDROCK_CACHE_MODEL_PATTERNS;
52
- return allPatterns.some((p) => p.test(modelId));
53
- }