@librechat/agents 3.2.31 → 3.2.33

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 (582) hide show
  1. package/dist/cjs/_virtual/_rolldown/runtime.cjs +23 -0
  2. package/dist/cjs/agents/AgentContext.cjs +844 -1046
  3. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  4. package/dist/cjs/common/constants.cjs +13 -13
  5. package/dist/cjs/common/constants.cjs.map +1 -1
  6. package/dist/cjs/common/enum.cjs +233 -240
  7. package/dist/cjs/common/enum.cjs.map +1 -1
  8. package/dist/cjs/common/index.cjs +2 -0
  9. package/dist/cjs/events.cjs +121 -169
  10. package/dist/cjs/events.cjs.map +1 -1
  11. package/dist/cjs/graphs/Graph.cjs +1389 -1807
  12. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  13. package/dist/cjs/graphs/MultiAgentGraph.cjs +713 -945
  14. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  15. package/dist/cjs/graphs/index.cjs +2 -0
  16. package/dist/cjs/hitl/askUserQuestion.cjs +60 -62
  17. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -1
  18. package/dist/cjs/hitl/index.cjs +1 -0
  19. package/dist/cjs/hooks/HookRegistry.cjs +176 -202
  20. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  21. package/dist/cjs/hooks/createToolPolicyHook.cjs +71 -101
  22. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -1
  23. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +170 -273
  24. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  25. package/dist/cjs/hooks/executeHooks.cjs +227 -282
  26. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  27. package/dist/cjs/hooks/index.cjs +6 -0
  28. package/dist/cjs/hooks/matchers.cjs +196 -230
  29. package/dist/cjs/hooks/matchers.cjs.map +1 -1
  30. package/dist/cjs/hooks/types.cjs +24 -24
  31. package/dist/cjs/hooks/types.cjs.map +1 -1
  32. package/dist/cjs/instrumentation.cjs +110 -137
  33. package/dist/cjs/instrumentation.cjs.map +1 -1
  34. package/dist/cjs/langchain/google-common.cjs +0 -3
  35. package/dist/cjs/langchain/index.cjs +80 -43
  36. package/dist/cjs/langchain/language_models/chat_models.cjs +0 -3
  37. package/dist/cjs/langchain/messages/tool.cjs +0 -3
  38. package/dist/cjs/langchain/messages.cjs +35 -18
  39. package/dist/cjs/langchain/openai.cjs +0 -3
  40. package/dist/cjs/langchain/prompts.cjs +5 -8
  41. package/dist/cjs/langchain/runnables.cjs +11 -10
  42. package/dist/cjs/langchain/tools.cjs +14 -11
  43. package/dist/cjs/langchain/utils/env.cjs +5 -8
  44. package/dist/cjs/langfuse.cjs +60 -79
  45. package/dist/cjs/langfuse.cjs.map +1 -1
  46. package/dist/cjs/langfuseToolOutputTracing.cjs +267 -399
  47. package/dist/cjs/langfuseToolOutputTracing.cjs.map +1 -1
  48. package/dist/cjs/llm/anthropic/index.cjs +432 -562
  49. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  50. package/dist/cjs/llm/anthropic/types.cjs +23 -47
  51. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  52. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +441 -696
  53. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  54. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +171 -252
  55. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  56. package/dist/cjs/llm/anthropic/utils/output_parsers.cjs +2 -0
  57. package/dist/cjs/llm/anthropic/utils/tools.cjs +12 -26
  58. package/dist/cjs/llm/anthropic/utils/tools.cjs.map +1 -1
  59. package/dist/cjs/llm/bedrock/index.cjs +195 -240
  60. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  61. package/dist/cjs/llm/bedrock/toolCache.cjs +84 -106
  62. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  63. package/dist/cjs/llm/bedrock/utils/index.cjs +2 -0
  64. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +357 -620
  65. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  66. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +105 -149
  67. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  68. package/dist/cjs/llm/fake.cjs +86 -96
  69. package/dist/cjs/llm/fake.cjs.map +1 -1
  70. package/dist/cjs/llm/google/index.cjs +183 -237
  71. package/dist/cjs/llm/google/index.cjs.map +1 -1
  72. package/dist/cjs/llm/google/utils/common.cjs +398 -674
  73. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  74. package/dist/cjs/llm/google/utils/zod_to_genai_parameters.cjs +2 -0
  75. package/dist/cjs/llm/init.cjs +44 -53
  76. package/dist/cjs/llm/init.cjs.map +1 -1
  77. package/dist/cjs/llm/invoke.cjs +142 -182
  78. package/dist/cjs/llm/invoke.cjs.map +1 -1
  79. package/dist/cjs/llm/openai/index.cjs +991 -1276
  80. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  81. package/dist/cjs/llm/openai/utils/index.cjs +189 -316
  82. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  83. package/dist/cjs/llm/openrouter/index.cjs +102 -153
  84. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  85. package/dist/cjs/llm/openrouter/toolCache.cjs +35 -44
  86. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  87. package/dist/cjs/llm/providers.cjs +29 -37
  88. package/dist/cjs/llm/providers.cjs.map +1 -1
  89. package/dist/cjs/llm/request.cjs +20 -33
  90. package/dist/cjs/llm/request.cjs.map +1 -1
  91. package/dist/cjs/llm/vertexai/index.cjs +427 -453
  92. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  93. package/dist/cjs/main.cjs +547 -528
  94. package/dist/cjs/messages/anthropicToolCache.cjs +68 -119
  95. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  96. package/dist/cjs/messages/cache.cjs +308 -401
  97. package/dist/cjs/messages/cache.cjs.map +1 -1
  98. package/dist/cjs/messages/content.cjs +36 -49
  99. package/dist/cjs/messages/content.cjs.map +1 -1
  100. package/dist/cjs/messages/contextPruning.cjs +112 -145
  101. package/dist/cjs/messages/contextPruning.cjs.map +1 -1
  102. package/dist/cjs/messages/contextPruningSettings.cjs +36 -46
  103. package/dist/cjs/messages/contextPruningSettings.cjs.map +1 -1
  104. package/dist/cjs/messages/core.cjs +256 -397
  105. package/dist/cjs/messages/core.cjs.map +1 -1
  106. package/dist/cjs/messages/format.cjs +904 -1382
  107. package/dist/cjs/messages/format.cjs.map +1 -1
  108. package/dist/cjs/messages/ids.cjs +16 -20
  109. package/dist/cjs/messages/ids.cjs.map +1 -1
  110. package/dist/cjs/messages/index.cjs +12 -0
  111. package/dist/cjs/messages/langchain.cjs +18 -18
  112. package/dist/cjs/messages/langchain.cjs.map +1 -1
  113. package/dist/cjs/messages/prune.cjs +1054 -1517
  114. package/dist/cjs/messages/prune.cjs.map +1 -1
  115. package/dist/cjs/messages/recency.cjs +77 -95
  116. package/dist/cjs/messages/recency.cjs.map +1 -1
  117. package/dist/cjs/messages/reducer.cjs +63 -78
  118. package/dist/cjs/messages/reducer.cjs.map +1 -1
  119. package/dist/cjs/messages/tools.cjs +51 -79
  120. package/dist/cjs/messages/tools.cjs.map +1 -1
  121. package/dist/cjs/openai/index.cjs +171 -217
  122. package/dist/cjs/openai/index.cjs.map +1 -1
  123. package/dist/cjs/responses/index.cjs +302 -391
  124. package/dist/cjs/responses/index.cjs.map +1 -1
  125. package/dist/cjs/run.cjs +903 -1113
  126. package/dist/cjs/run.cjs.map +1 -1
  127. package/dist/cjs/session/AgentSession.cjs +805 -986
  128. package/dist/cjs/session/AgentSession.cjs.map +1 -1
  129. package/dist/cjs/session/JsonlSessionStore.cjs +327 -410
  130. package/dist/cjs/session/JsonlSessionStore.cjs.map +1 -1
  131. package/dist/cjs/session/handlers.cjs +192 -208
  132. package/dist/cjs/session/handlers.cjs.map +1 -1
  133. package/dist/cjs/session/ids.cjs +9 -10
  134. package/dist/cjs/session/ids.cjs.map +1 -1
  135. package/dist/cjs/session/index.cjs +4 -0
  136. package/dist/cjs/session/messageSerialization.cjs +94 -156
  137. package/dist/cjs/session/messageSerialization.cjs.map +1 -1
  138. package/dist/cjs/splitStream.cjs +147 -206
  139. package/dist/cjs/splitStream.cjs.map +1 -1
  140. package/dist/cjs/stream.cjs +856 -1344
  141. package/dist/cjs/stream.cjs.map +1 -1
  142. package/dist/cjs/summarization/index.cjs +57 -101
  143. package/dist/cjs/summarization/index.cjs.map +1 -1
  144. package/dist/cjs/summarization/node.cjs +643 -796
  145. package/dist/cjs/summarization/node.cjs.map +1 -1
  146. package/dist/cjs/tools/BashExecutor.cjs +110 -136
  147. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  148. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +165 -245
  149. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  150. package/dist/cjs/tools/Calculator.cjs +36 -57
  151. package/dist/cjs/tools/Calculator.cjs.map +1 -1
  152. package/dist/cjs/tools/CodeExecutor.cjs +126 -168
  153. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  154. package/dist/cjs/tools/CodeSessionFileSummary.cjs +36 -46
  155. package/dist/cjs/tools/CodeSessionFileSummary.cjs.map +1 -1
  156. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +459 -649
  157. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  158. package/dist/cjs/tools/ReadFile.cjs +17 -20
  159. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  160. package/dist/cjs/tools/SkillTool.cjs +26 -27
  161. package/dist/cjs/tools/SkillTool.cjs.map +1 -1
  162. package/dist/cjs/tools/SubagentTool.cjs +59 -61
  163. package/dist/cjs/tools/SubagentTool.cjs.map +1 -1
  164. package/dist/cjs/tools/ToolNode.cjs +2109 -2686
  165. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  166. package/dist/cjs/tools/ToolSearch.cjs +663 -825
  167. package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
  168. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +248 -340
  169. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -1
  170. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +170 -197
  171. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  172. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +425 -520
  173. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -1
  174. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +91 -124
  175. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -1
  176. package/dist/cjs/tools/cloudflare/index.cjs +4 -0
  177. package/dist/cjs/tools/eagerEventExecution.cjs +75 -99
  178. package/dist/cjs/tools/eagerEventExecution.cjs.map +1 -1
  179. package/dist/cjs/tools/handlers.cjs +200 -262
  180. package/dist/cjs/tools/handlers.cjs.map +1 -1
  181. package/dist/cjs/tools/local/CompileCheckTool.cjs +150 -212
  182. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -1
  183. package/dist/cjs/tools/local/FileCheckpointer.cjs +77 -85
  184. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -1
  185. package/dist/cjs/tools/local/LocalCodingTools.cjs +763 -1022
  186. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  187. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +666 -941
  188. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  189. package/dist/cjs/tools/local/LocalExecutionTools.cjs +49 -92
  190. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -1
  191. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +286 -354
  192. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
  193. package/dist/cjs/tools/local/attachments.cjs +108 -165
  194. package/dist/cjs/tools/local/attachments.cjs.map +1 -1
  195. package/dist/cjs/tools/local/bashAst.cjs +99 -113
  196. package/dist/cjs/tools/local/bashAst.cjs.map +1 -1
  197. package/dist/cjs/tools/local/editStrategies.cjs +126 -169
  198. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -1
  199. package/dist/cjs/tools/local/index.cjs +12 -0
  200. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +136 -218
  201. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  202. package/dist/cjs/tools/local/syntaxCheck.cjs +142 -161
  203. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -1
  204. package/dist/cjs/tools/local/textEncoding.cjs +25 -23
  205. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -1
  206. package/dist/cjs/tools/local/workspaceFS.cjs +38 -46
  207. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -1
  208. package/dist/cjs/tools/ptcTimeout.cjs +27 -47
  209. package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
  210. package/dist/cjs/tools/schema.cjs +24 -23
  211. package/dist/cjs/tools/schema.cjs.map +1 -1
  212. package/dist/cjs/tools/search/anthropic.cjs +24 -33
  213. package/dist/cjs/tools/search/anthropic.cjs.map +1 -1
  214. package/dist/cjs/tools/search/content.cjs +95 -137
  215. package/dist/cjs/tools/search/content.cjs.map +1 -1
  216. package/dist/cjs/tools/search/firecrawl.cjs +141 -172
  217. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  218. package/dist/cjs/tools/search/format.cjs +128 -196
  219. package/dist/cjs/tools/search/format.cjs.map +1 -1
  220. package/dist/cjs/tools/search/highlights.cjs +165 -232
  221. package/dist/cjs/tools/search/highlights.cjs.map +1 -1
  222. package/dist/cjs/tools/search/index.cjs +2 -0
  223. package/dist/cjs/tools/search/rerankers.cjs +151 -174
  224. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  225. package/dist/cjs/tools/search/schema.cjs +40 -39
  226. package/dist/cjs/tools/search/schema.cjs.map +1 -1
  227. package/dist/cjs/tools/search/search.cjs +428 -530
  228. package/dist/cjs/tools/search/search.cjs.map +1 -1
  229. package/dist/cjs/tools/search/serper-scraper.cjs +106 -127
  230. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -1
  231. package/dist/cjs/tools/search/tavily-scraper.cjs +129 -181
  232. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -1
  233. package/dist/cjs/tools/search/tavily-search.cjs +295 -359
  234. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -1
  235. package/dist/cjs/tools/search/tool.cjs +260 -299
  236. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  237. package/dist/cjs/tools/search/utils.cjs +74 -117
  238. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  239. package/dist/cjs/tools/skillCatalog.cjs +54 -72
  240. package/dist/cjs/tools/skillCatalog.cjs.map +1 -1
  241. package/dist/cjs/tools/streamedToolCallSeals.cjs +19 -36
  242. package/dist/cjs/tools/streamedToolCallSeals.cjs.map +1 -1
  243. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +612 -771
  244. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  245. package/dist/cjs/tools/subagent/index.cjs +1 -0
  246. package/dist/cjs/tools/toolOutputReferences.cjs +523 -630
  247. package/dist/cjs/tools/toolOutputReferences.cjs.map +1 -1
  248. package/dist/cjs/utils/callbacks.cjs +11 -21
  249. package/dist/cjs/utils/callbacks.cjs.map +1 -1
  250. package/dist/cjs/utils/errors.cjs +70 -95
  251. package/dist/cjs/utils/errors.cjs.map +1 -1
  252. package/dist/cjs/utils/events.cjs +32 -42
  253. package/dist/cjs/utils/events.cjs.map +1 -1
  254. package/dist/cjs/utils/graph.cjs +8 -12
  255. package/dist/cjs/utils/graph.cjs.map +1 -1
  256. package/dist/cjs/utils/handlers.cjs +60 -82
  257. package/dist/cjs/utils/handlers.cjs.map +1 -1
  258. package/dist/cjs/utils/index.cjs +9 -0
  259. package/dist/cjs/utils/llm.cjs +19 -27
  260. package/dist/cjs/utils/llm.cjs.map +1 -1
  261. package/dist/cjs/utils/misc.cjs +30 -46
  262. package/dist/cjs/utils/misc.cjs.map +1 -1
  263. package/dist/cjs/utils/run.cjs +50 -66
  264. package/dist/cjs/utils/run.cjs.map +1 -1
  265. package/dist/cjs/utils/schema.cjs +11 -19
  266. package/dist/cjs/utils/schema.cjs.map +1 -1
  267. package/dist/cjs/utils/title.cjs +71 -106
  268. package/dist/cjs/utils/title.cjs.map +1 -1
  269. package/dist/cjs/utils/tokens.cjs +186 -283
  270. package/dist/cjs/utils/tokens.cjs.map +1 -1
  271. package/dist/cjs/utils/truncation.cjs +95 -114
  272. package/dist/cjs/utils/truncation.cjs.map +1 -1
  273. package/dist/esm/agents/AgentContext.mjs +844 -1044
  274. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  275. package/dist/esm/common/constants.mjs +13 -11
  276. package/dist/esm/common/constants.mjs.map +1 -1
  277. package/dist/esm/common/enum.mjs +221 -238
  278. package/dist/esm/common/enum.mjs.map +1 -1
  279. package/dist/esm/common/index.mjs +3 -0
  280. package/dist/esm/events.mjs +121 -167
  281. package/dist/esm/events.mjs.map +1 -1
  282. package/dist/esm/graphs/Graph.mjs +1388 -1804
  283. package/dist/esm/graphs/Graph.mjs.map +1 -1
  284. package/dist/esm/graphs/MultiAgentGraph.mjs +713 -943
  285. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  286. package/dist/esm/graphs/index.mjs +3 -0
  287. package/dist/esm/hitl/askUserQuestion.mjs +60 -60
  288. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -1
  289. package/dist/esm/hitl/index.mjs +2 -0
  290. package/dist/esm/hooks/HookRegistry.mjs +176 -200
  291. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  292. package/dist/esm/hooks/createToolPolicyHook.mjs +71 -99
  293. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -1
  294. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +170 -271
  295. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  296. package/dist/esm/hooks/executeHooks.mjs +227 -280
  297. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  298. package/dist/esm/hooks/index.mjs +7 -0
  299. package/dist/esm/hooks/matchers.mjs +196 -228
  300. package/dist/esm/hooks/matchers.mjs.map +1 -1
  301. package/dist/esm/hooks/types.mjs +24 -22
  302. package/dist/esm/hooks/types.mjs.map +1 -1
  303. package/dist/esm/instrumentation.mjs +109 -132
  304. package/dist/esm/instrumentation.mjs.map +1 -1
  305. package/dist/esm/langchain/google-common.mjs +1 -2
  306. package/dist/esm/langchain/index.mjs +5 -5
  307. package/dist/esm/langchain/language_models/chat_models.mjs +1 -2
  308. package/dist/esm/langchain/messages/tool.mjs +1 -2
  309. package/dist/esm/langchain/messages.mjs +2 -2
  310. package/dist/esm/langchain/openai.mjs +1 -2
  311. package/dist/esm/langchain/prompts.mjs +2 -2
  312. package/dist/esm/langchain/runnables.mjs +2 -2
  313. package/dist/esm/langchain/tools.mjs +2 -2
  314. package/dist/esm/langchain/utils/env.mjs +2 -2
  315. package/dist/esm/langfuse.mjs +60 -76
  316. package/dist/esm/langfuse.mjs.map +1 -1
  317. package/dist/esm/langfuseToolOutputTracing.mjs +267 -395
  318. package/dist/esm/langfuseToolOutputTracing.mjs.map +1 -1
  319. package/dist/esm/llm/anthropic/index.mjs +432 -559
  320. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  321. package/dist/esm/llm/anthropic/types.mjs +23 -45
  322. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  323. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +439 -690
  324. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  325. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +171 -249
  326. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  327. package/dist/esm/llm/anthropic/utils/output_parsers.mjs +3 -0
  328. package/dist/esm/llm/anthropic/utils/tools.mjs +12 -24
  329. package/dist/esm/llm/anthropic/utils/tools.mjs.map +1 -1
  330. package/dist/esm/llm/bedrock/index.mjs +195 -238
  331. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  332. package/dist/esm/llm/bedrock/toolCache.mjs +84 -104
  333. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  334. package/dist/esm/llm/bedrock/utils/index.mjs +3 -0
  335. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +357 -618
  336. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  337. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +105 -147
  338. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  339. package/dist/esm/llm/fake.mjs +86 -94
  340. package/dist/esm/llm/fake.mjs.map +1 -1
  341. package/dist/esm/llm/google/index.mjs +183 -235
  342. package/dist/esm/llm/google/index.mjs.map +1 -1
  343. package/dist/esm/llm/google/utils/common.mjs +397 -666
  344. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  345. package/dist/esm/llm/google/utils/zod_to_genai_parameters.mjs +3 -0
  346. package/dist/esm/llm/init.mjs +44 -51
  347. package/dist/esm/llm/init.mjs.map +1 -1
  348. package/dist/esm/llm/invoke.mjs +142 -180
  349. package/dist/esm/llm/invoke.mjs.map +1 -1
  350. package/dist/esm/llm/openai/index.mjs +991 -1271
  351. package/dist/esm/llm/openai/index.mjs.map +1 -1
  352. package/dist/esm/llm/openai/utils/index.mjs +188 -312
  353. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  354. package/dist/esm/llm/openrouter/index.mjs +102 -151
  355. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  356. package/dist/esm/llm/openrouter/toolCache.mjs +35 -42
  357. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  358. package/dist/esm/llm/providers.mjs +29 -34
  359. package/dist/esm/llm/providers.mjs.map +1 -1
  360. package/dist/esm/llm/request.mjs +20 -31
  361. package/dist/esm/llm/request.mjs.map +1 -1
  362. package/dist/esm/llm/vertexai/index.mjs +427 -449
  363. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  364. package/dist/esm/main.mjs +99 -87
  365. package/dist/esm/messages/anthropicToolCache.mjs +68 -117
  366. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  367. package/dist/esm/messages/cache.mjs +308 -399
  368. package/dist/esm/messages/cache.mjs.map +1 -1
  369. package/dist/esm/messages/content.mjs +36 -47
  370. package/dist/esm/messages/content.mjs.map +1 -1
  371. package/dist/esm/messages/contextPruning.mjs +112 -143
  372. package/dist/esm/messages/contextPruning.mjs.map +1 -1
  373. package/dist/esm/messages/contextPruningSettings.mjs +36 -44
  374. package/dist/esm/messages/contextPruningSettings.mjs.map +1 -1
  375. package/dist/esm/messages/core.mjs +254 -393
  376. package/dist/esm/messages/core.mjs.map +1 -1
  377. package/dist/esm/messages/format.mjs +902 -1378
  378. package/dist/esm/messages/format.mjs.map +1 -1
  379. package/dist/esm/messages/ids.mjs +16 -18
  380. package/dist/esm/messages/ids.mjs.map +1 -1
  381. package/dist/esm/messages/index.mjs +13 -0
  382. package/dist/esm/messages/langchain.mjs +18 -16
  383. package/dist/esm/messages/langchain.mjs.map +1 -1
  384. package/dist/esm/messages/prune.mjs +1053 -1514
  385. package/dist/esm/messages/prune.mjs.map +1 -1
  386. package/dist/esm/messages/recency.mjs +77 -93
  387. package/dist/esm/messages/recency.mjs.map +1 -1
  388. package/dist/esm/messages/reducer.mjs +63 -76
  389. package/dist/esm/messages/reducer.mjs.map +1 -1
  390. package/dist/esm/messages/tools.mjs +49 -75
  391. package/dist/esm/messages/tools.mjs.map +1 -1
  392. package/dist/esm/openai/index.mjs +170 -215
  393. package/dist/esm/openai/index.mjs.map +1 -1
  394. package/dist/esm/responses/index.mjs +301 -389
  395. package/dist/esm/responses/index.mjs.map +1 -1
  396. package/dist/esm/run.mjs +903 -1111
  397. package/dist/esm/run.mjs.map +1 -1
  398. package/dist/esm/session/AgentSession.mjs +806 -985
  399. package/dist/esm/session/AgentSession.mjs.map +1 -1
  400. package/dist/esm/session/JsonlSessionStore.mjs +326 -407
  401. package/dist/esm/session/JsonlSessionStore.mjs.map +1 -1
  402. package/dist/esm/session/handlers.mjs +192 -206
  403. package/dist/esm/session/handlers.mjs.map +1 -1
  404. package/dist/esm/session/ids.mjs +9 -8
  405. package/dist/esm/session/ids.mjs.map +1 -1
  406. package/dist/esm/session/index.mjs +5 -0
  407. package/dist/esm/session/messageSerialization.mjs +94 -154
  408. package/dist/esm/session/messageSerialization.mjs.map +1 -1
  409. package/dist/esm/splitStream.mjs +147 -204
  410. package/dist/esm/splitStream.mjs.map +1 -1
  411. package/dist/esm/stream.mjs +854 -1341
  412. package/dist/esm/stream.mjs.map +1 -1
  413. package/dist/esm/summarization/index.mjs +57 -99
  414. package/dist/esm/summarization/index.mjs.map +1 -1
  415. package/dist/esm/summarization/node.mjs +640 -790
  416. package/dist/esm/summarization/node.mjs.map +1 -1
  417. package/dist/esm/tools/BashExecutor.mjs +103 -129
  418. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  419. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +162 -239
  420. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  421. package/dist/esm/tools/Calculator.mjs +34 -36
  422. package/dist/esm/tools/Calculator.mjs.map +1 -1
  423. package/dist/esm/tools/CodeExecutor.mjs +123 -164
  424. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  425. package/dist/esm/tools/CodeSessionFileSummary.mjs +36 -44
  426. package/dist/esm/tools/CodeSessionFileSummary.mjs.map +1 -1
  427. package/dist/esm/tools/ProgrammaticToolCalling.mjs +454 -644
  428. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  429. package/dist/esm/tools/ReadFile.mjs +17 -18
  430. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  431. package/dist/esm/tools/SkillTool.mjs +26 -25
  432. package/dist/esm/tools/SkillTool.mjs.map +1 -1
  433. package/dist/esm/tools/SubagentTool.mjs +59 -59
  434. package/dist/esm/tools/SubagentTool.mjs.map +1 -1
  435. package/dist/esm/tools/ToolNode.mjs +2107 -2684
  436. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  437. package/dist/esm/tools/ToolSearch.mjs +659 -804
  438. package/dist/esm/tools/ToolSearch.mjs.map +1 -1
  439. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +248 -338
  440. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -1
  441. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +170 -195
  442. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  443. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +424 -517
  444. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -1
  445. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +91 -122
  446. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -1
  447. package/dist/esm/tools/cloudflare/index.mjs +5 -0
  448. package/dist/esm/tools/eagerEventExecution.mjs +75 -96
  449. package/dist/esm/tools/eagerEventExecution.mjs.map +1 -1
  450. package/dist/esm/tools/handlers.mjs +200 -260
  451. package/dist/esm/tools/handlers.mjs.map +1 -1
  452. package/dist/esm/tools/local/CompileCheckTool.mjs +150 -210
  453. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -1
  454. package/dist/esm/tools/local/FileCheckpointer.mjs +77 -83
  455. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -1
  456. package/dist/esm/tools/local/LocalCodingTools.mjs +760 -1017
  457. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  458. package/dist/esm/tools/local/LocalExecutionEngine.mjs +663 -936
  459. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  460. package/dist/esm/tools/local/LocalExecutionTools.mjs +49 -90
  461. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -1
  462. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +283 -349
  463. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
  464. package/dist/esm/tools/local/attachments.mjs +108 -163
  465. package/dist/esm/tools/local/attachments.mjs.map +1 -1
  466. package/dist/esm/tools/local/bashAst.mjs +99 -111
  467. package/dist/esm/tools/local/bashAst.mjs.map +1 -1
  468. package/dist/esm/tools/local/editStrategies.mjs +126 -167
  469. package/dist/esm/tools/local/editStrategies.mjs.map +1 -1
  470. package/dist/esm/tools/local/index.mjs +13 -0
  471. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +136 -216
  472. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  473. package/dist/esm/tools/local/syntaxCheck.mjs +138 -155
  474. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -1
  475. package/dist/esm/tools/local/textEncoding.mjs +25 -21
  476. package/dist/esm/tools/local/textEncoding.mjs.map +1 -1
  477. package/dist/esm/tools/local/workspaceFS.mjs +38 -44
  478. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -1
  479. package/dist/esm/tools/ptcTimeout.mjs +27 -42
  480. package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
  481. package/dist/esm/tools/schema.mjs +24 -21
  482. package/dist/esm/tools/schema.mjs.map +1 -1
  483. package/dist/esm/tools/search/anthropic.mjs +24 -31
  484. package/dist/esm/tools/search/anthropic.mjs.map +1 -1
  485. package/dist/esm/tools/search/content.mjs +93 -116
  486. package/dist/esm/tools/search/content.mjs.map +1 -1
  487. package/dist/esm/tools/search/firecrawl.mjs +139 -169
  488. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  489. package/dist/esm/tools/search/format.mjs +128 -194
  490. package/dist/esm/tools/search/format.mjs.map +1 -1
  491. package/dist/esm/tools/search/highlights.mjs +165 -230
  492. package/dist/esm/tools/search/highlights.mjs.map +1 -1
  493. package/dist/esm/tools/search/index.mjs +3 -0
  494. package/dist/esm/tools/search/rerankers.mjs +149 -168
  495. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  496. package/dist/esm/tools/search/schema.mjs +39 -37
  497. package/dist/esm/tools/search/schema.mjs.map +1 -1
  498. package/dist/esm/tools/search/search.mjs +426 -528
  499. package/dist/esm/tools/search/search.mjs.map +1 -1
  500. package/dist/esm/tools/search/serper-scraper.mjs +104 -124
  501. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -1
  502. package/dist/esm/tools/search/tavily-scraper.mjs +127 -178
  503. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -1
  504. package/dist/esm/tools/search/tavily-search.mjs +293 -357
  505. package/dist/esm/tools/search/tavily-search.mjs.map +1 -1
  506. package/dist/esm/tools/search/tool.mjs +259 -297
  507. package/dist/esm/tools/search/tool.mjs.map +1 -1
  508. package/dist/esm/tools/search/utils.mjs +74 -115
  509. package/dist/esm/tools/search/utils.mjs.map +1 -1
  510. package/dist/esm/tools/skillCatalog.mjs +54 -70
  511. package/dist/esm/tools/skillCatalog.mjs.map +1 -1
  512. package/dist/esm/tools/streamedToolCallSeals.mjs +19 -31
  513. package/dist/esm/tools/streamedToolCallSeals.mjs.map +1 -1
  514. package/dist/esm/tools/subagent/SubagentExecutor.mjs +612 -768
  515. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  516. package/dist/esm/tools/subagent/index.mjs +2 -0
  517. package/dist/esm/tools/toolOutputReferences.mjs +523 -624
  518. package/dist/esm/tools/toolOutputReferences.mjs.map +1 -1
  519. package/dist/esm/utils/callbacks.mjs +11 -19
  520. package/dist/esm/utils/callbacks.mjs.map +1 -1
  521. package/dist/esm/utils/errors.mjs +70 -93
  522. package/dist/esm/utils/errors.mjs.map +1 -1
  523. package/dist/esm/utils/events.mjs +32 -40
  524. package/dist/esm/utils/events.mjs.map +1 -1
  525. package/dist/esm/utils/graph.mjs +8 -10
  526. package/dist/esm/utils/graph.mjs.map +1 -1
  527. package/dist/esm/utils/handlers.mjs +60 -80
  528. package/dist/esm/utils/handlers.mjs.map +1 -1
  529. package/dist/esm/utils/index.mjs +10 -0
  530. package/dist/esm/utils/llm.mjs +19 -25
  531. package/dist/esm/utils/llm.mjs.map +1 -1
  532. package/dist/esm/utils/misc.mjs +30 -44
  533. package/dist/esm/utils/misc.mjs.map +1 -1
  534. package/dist/esm/utils/run.mjs +50 -64
  535. package/dist/esm/utils/run.mjs.map +1 -1
  536. package/dist/esm/utils/schema.mjs +11 -17
  537. package/dist/esm/utils/schema.mjs.map +1 -1
  538. package/dist/esm/utils/title.mjs +71 -104
  539. package/dist/esm/utils/title.mjs.map +1 -1
  540. package/dist/esm/utils/tokens.mjs +186 -281
  541. package/dist/esm/utils/tokens.mjs.map +1 -1
  542. package/dist/esm/utils/truncation.mjs +95 -112
  543. package/dist/esm/utils/truncation.mjs.map +1 -1
  544. package/dist/types/messages/format.d.ts +5 -0
  545. package/dist/types/tools/search/tool.d.ts +17 -0
  546. package/dist/types/tools/search/types.d.ts +4 -0
  547. package/package.json +11 -17
  548. package/src/llm/anthropic/llm.spec.ts +36 -0
  549. package/src/llm/anthropic/utils/message_inputs.ts +45 -3
  550. package/src/llm/anthropic/utils/message_outputs.ts +6 -2
  551. package/src/llm/anthropic/utils/streaming-tool-input.test.ts +186 -0
  552. package/src/messages/cache.test.ts +122 -0
  553. package/src/messages/cache.ts +25 -1
  554. package/src/messages/format.ts +9 -0
  555. package/src/messages/formatAgentMessages.skills.test.ts +100 -0
  556. package/src/tools/search/highlights.ts +9 -1
  557. package/src/tools/search/search.ts +41 -3
  558. package/src/tools/search/source-processing.test.ts +373 -0
  559. package/src/tools/search/tool.ts +22 -2
  560. package/src/tools/search/types.ts +4 -0
  561. package/dist/cjs/langchain/google-common.cjs.map +0 -1
  562. package/dist/cjs/langchain/index.cjs.map +0 -1
  563. package/dist/cjs/langchain/language_models/chat_models.cjs.map +0 -1
  564. package/dist/cjs/langchain/messages/tool.cjs.map +0 -1
  565. package/dist/cjs/langchain/messages.cjs.map +0 -1
  566. package/dist/cjs/langchain/openai.cjs.map +0 -1
  567. package/dist/cjs/langchain/prompts.cjs.map +0 -1
  568. package/dist/cjs/langchain/runnables.cjs.map +0 -1
  569. package/dist/cjs/langchain/tools.cjs.map +0 -1
  570. package/dist/cjs/langchain/utils/env.cjs.map +0 -1
  571. package/dist/cjs/main.cjs.map +0 -1
  572. package/dist/esm/langchain/google-common.mjs.map +0 -1
  573. package/dist/esm/langchain/index.mjs.map +0 -1
  574. package/dist/esm/langchain/language_models/chat_models.mjs.map +0 -1
  575. package/dist/esm/langchain/messages/tool.mjs.map +0 -1
  576. package/dist/esm/langchain/messages.mjs.map +0 -1
  577. package/dist/esm/langchain/openai.mjs.map +0 -1
  578. package/dist/esm/langchain/prompts.mjs.map +0 -1
  579. package/dist/esm/langchain/runnables.mjs.map +0 -1
  580. package/dist/esm/langchain/tools.mjs.map +0 -1
  581. package/dist/esm/langchain/utils/env.mjs.map +0 -1
  582. package/dist/esm/main.mjs.map +0 -1
@@ -1,551 +1,449 @@
1
- 'use strict';
2
-
3
- var axios = require('axios');
4
- var textsplitters = require('@langchain/textsplitters');
5
- var utils = require('./utils.cjs');
6
- var tavilySearch = require('./tavily-search.cjs');
7
-
1
+ const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
2
+ const require_utils = require("./utils.cjs");
3
+ const require_tavily_search = require("./tavily-search.cjs");
4
+ let axios = require("axios");
5
+ axios = require_runtime.__toESM(axios, 1);
6
+ let _langchain_textsplitters = require("@langchain/textsplitters");
7
+ //#region src/tools/search/search.ts
8
8
  const chunker = {
9
- cleanText: (text) => {
10
- if (!text)
11
- return '';
12
- /** Normalized all line endings to '\n' */
13
- const normalizedText = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
14
- /** Handle multiple backslashes followed by newlines
15
- * This replaces patterns like '\\\\\\n' with a single newline */
16
- const fixedBackslashes = normalizedText.replace(/\\+\n/g, '\n');
17
- /** Cleaned up consecutive newlines, tabs, and spaces around newlines */
18
- const cleanedNewlines = fixedBackslashes.replace(/[\t ]*\n[\t \n]*/g, '\n');
19
- /** Cleaned up excessive spaces and tabs */
20
- const cleanedSpaces = cleanedNewlines.replace(/[ \t]+/g, ' ');
21
- return cleanedSpaces.trim();
22
- },
23
- splitText: async (text, options) => {
24
- const chunkSize = options?.chunkSize ?? 150;
25
- const chunkOverlap = options?.chunkOverlap ?? 50;
26
- const separators = options?.separators || ['\n\n', '\n'];
27
- const splitter = new textsplitters.RecursiveCharacterTextSplitter({
28
- separators,
29
- chunkSize,
30
- chunkOverlap,
31
- });
32
- return await splitter.splitText(text);
33
- },
34
- splitTexts: async (texts, options, logger) => {
35
- // Split multiple texts
36
- const logger_ = logger || utils.createDefaultLogger();
37
- const promises = texts.map((text) => chunker.splitText(text, options).catch((error) => {
38
- logger_.error('Error splitting text:', error);
39
- return [text];
40
- }));
41
- return Promise.all(promises);
42
- },
9
+ cleanText: (text) => {
10
+ if (!text) return "";
11
+ return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\\+\n/g, "\n").replace(/[\t ]*\n[\t \n]*/g, "\n").replace(/[ \t]+/g, " ").trim();
12
+ },
13
+ splitText: async (text, options) => {
14
+ const chunkSize = options?.chunkSize ?? 150;
15
+ const chunkOverlap = options?.chunkOverlap ?? 50;
16
+ return await new _langchain_textsplitters.RecursiveCharacterTextSplitter({
17
+ separators: options?.separators || ["\n\n", "\n"],
18
+ chunkSize,
19
+ chunkOverlap
20
+ }).splitText(text);
21
+ },
22
+ splitTexts: async (texts, options, logger) => {
23
+ const logger_ = logger || require_utils.createDefaultLogger();
24
+ const promises = texts.map((text) => chunker.splitText(text, options).catch((error) => {
25
+ logger_.error("Error splitting text:", error);
26
+ return [text];
27
+ }));
28
+ return Promise.all(promises);
29
+ }
43
30
  };
31
+ const DEFAULT_MAX_CONTENT_LENGTH = 5e4;
32
+ /** Resolves the per-source scraped content cap from config, the
33
+ * `SEARCH_MAX_CONTENT_LENGTH` env var, or the default (50,000 chars) */
34
+ function resolveMaxContentLength(maxContentLength) {
35
+ if (maxContentLength != null && maxContentLength > 0) return maxContentLength;
36
+ const envValue = Number(process.env.SEARCH_MAX_CONTENT_LENGTH);
37
+ if (Number.isFinite(envValue) && envValue > 0) return envValue;
38
+ return DEFAULT_MAX_CONTENT_LENGTH;
39
+ }
40
+ function truncateContent(content, maxLength) {
41
+ return content.length > maxLength ? content.slice(0, maxLength) : content;
42
+ }
44
43
  function createSourceUpdateCallback(sourceMap) {
45
- return (link, update) => {
46
- const source = sourceMap.get(link);
47
- if (source) {
48
- sourceMap.set(link, {
49
- ...source,
50
- ...update,
51
- });
52
- }
53
- };
44
+ return (link, update) => {
45
+ const source = sourceMap.get(link);
46
+ if (source) sourceMap.set(link, {
47
+ ...source,
48
+ ...update
49
+ });
50
+ };
54
51
  }
55
- const getHighlights = async ({ query, content, reranker, topResults = 5, logger, }) => {
56
- const logger_ = logger || utils.createDefaultLogger();
57
- if (!content) {
58
- logger_.warn('No content provided for highlights');
59
- return;
60
- }
61
- if (!reranker) {
62
- logger_.warn('No reranker provided for highlights');
63
- return;
64
- }
65
- try {
66
- const documents = await chunker.splitText(content);
67
- if (Array.isArray(documents)) {
68
- return await reranker.rerank(query, documents, topResults);
69
- }
70
- else {
71
- logger_.error('Expected documents to be an array, got:', typeof documents);
72
- return;
73
- }
74
- }
75
- catch (error) {
76
- logger_.error('Error in content processing:', error);
77
- return;
78
- }
52
+ const getHighlights = async ({ query, content, reranker, topResults = 5, maxContentLength = DEFAULT_MAX_CONTENT_LENGTH, logger }) => {
53
+ const logger_ = logger || require_utils.createDefaultLogger();
54
+ if (!content) {
55
+ logger_.warn("No content provided for highlights");
56
+ return;
57
+ }
58
+ if (!reranker) {
59
+ logger_.warn("No reranker provided for highlights");
60
+ return;
61
+ }
62
+ try {
63
+ const documents = await chunker.splitText(truncateContent(content, maxContentLength));
64
+ if (Array.isArray(documents)) return await reranker.rerank(query, documents, topResults);
65
+ else {
66
+ logger_.error("Expected documents to be an array, got:", typeof documents);
67
+ return;
68
+ }
69
+ } catch (error) {
70
+ logger_.error("Error in content processing:", error);
71
+ return;
72
+ }
79
73
  };
80
74
  const createSerperAPI = (apiKey) => {
81
- const config = {
82
- apiKey: apiKey ?? process.env.SERPER_API_KEY,
83
- apiUrl: 'https://google.serper.dev/search',
84
- timeout: 10000,
85
- };
86
- if (config.apiKey == null || config.apiKey === '') {
87
- throw new Error('SERPER_API_KEY is required for SerperAPI');
88
- }
89
- const getSources = async ({ query, date, country, safeSearch, numResults = 8, type, }) => {
90
- if (!query.trim()) {
91
- return { success: false, error: 'Query cannot be empty' };
92
- }
93
- try {
94
- const safe = ['off', 'moderate', 'active'];
95
- const payload = {
96
- q: query,
97
- safe: safe[safeSearch ?? 1],
98
- num: Math.min(Math.max(1, numResults), 10),
99
- };
100
- // Set the search type if provided
101
- if (type) {
102
- payload.type = type;
103
- }
104
- if (date != null) {
105
- payload.tbs = `qdr:${date}`;
106
- }
107
- if (country != null && country !== '') {
108
- payload['gl'] = country.toLowerCase();
109
- }
110
- // Determine the API endpoint based on the search type
111
- let apiEndpoint = config.apiUrl;
112
- if (type === 'images') {
113
- apiEndpoint = 'https://google.serper.dev/images';
114
- }
115
- else if (type === 'videos') {
116
- apiEndpoint = 'https://google.serper.dev/videos';
117
- }
118
- else if (type === 'news') {
119
- apiEndpoint = 'https://google.serper.dev/news';
120
- }
121
- const response = await axios.post(apiEndpoint, payload, {
122
- headers: {
123
- 'X-API-KEY': config.apiKey,
124
- 'Content-Type': 'application/json',
125
- },
126
- timeout: config.timeout,
127
- });
128
- const data = response.data;
129
- const results = {
130
- organic: data.organic,
131
- images: data.images ?? [],
132
- answerBox: data.answerBox,
133
- topStories: data.topStories ?? [],
134
- peopleAlsoAsk: data.peopleAlsoAsk,
135
- knowledgeGraph: data.knowledgeGraph,
136
- relatedSearches: data.relatedSearches,
137
- videos: data.videos ?? [],
138
- news: data.news ?? [],
139
- };
140
- return { success: true, data: results };
141
- }
142
- catch (error) {
143
- const errorMessage = error instanceof Error ? error.message : String(error);
144
- return { success: false, error: `API request failed: ${errorMessage}` };
145
- }
146
- };
147
- return { getSources };
75
+ const config = {
76
+ apiKey: apiKey ?? process.env.SERPER_API_KEY,
77
+ apiUrl: "https://google.serper.dev/search",
78
+ timeout: 1e4
79
+ };
80
+ if (config.apiKey == null || config.apiKey === "") throw new Error("SERPER_API_KEY is required for SerperAPI");
81
+ const getSources = async ({ query, date, country, safeSearch, numResults = 8, type }) => {
82
+ if (!query.trim()) return {
83
+ success: false,
84
+ error: "Query cannot be empty"
85
+ };
86
+ try {
87
+ const payload = {
88
+ q: query,
89
+ safe: [
90
+ "off",
91
+ "moderate",
92
+ "active"
93
+ ][safeSearch ?? 1],
94
+ num: Math.min(Math.max(1, numResults), 10)
95
+ };
96
+ if (type) payload.type = type;
97
+ if (date != null) payload.tbs = `qdr:${date}`;
98
+ if (country != null && country !== "") payload["gl"] = country.toLowerCase();
99
+ let apiEndpoint = config.apiUrl;
100
+ if (type === "images") apiEndpoint = "https://google.serper.dev/images";
101
+ else if (type === "videos") apiEndpoint = "https://google.serper.dev/videos";
102
+ else if (type === "news") apiEndpoint = "https://google.serper.dev/news";
103
+ const data = (await axios.default.post(apiEndpoint, payload, {
104
+ headers: {
105
+ "X-API-KEY": config.apiKey,
106
+ "Content-Type": "application/json"
107
+ },
108
+ timeout: config.timeout
109
+ })).data;
110
+ return {
111
+ success: true,
112
+ data: {
113
+ organic: data.organic,
114
+ images: data.images ?? [],
115
+ answerBox: data.answerBox,
116
+ topStories: data.topStories ?? [],
117
+ peopleAlsoAsk: data.peopleAlsoAsk,
118
+ knowledgeGraph: data.knowledgeGraph,
119
+ relatedSearches: data.relatedSearches,
120
+ videos: data.videos ?? [],
121
+ news: data.news ?? []
122
+ }
123
+ };
124
+ } catch (error) {
125
+ return {
126
+ success: false,
127
+ error: `API request failed: ${error instanceof Error ? error.message : String(error)}`
128
+ };
129
+ }
130
+ };
131
+ return { getSources };
148
132
  };
149
133
  const createSearXNGAPI = (instanceUrl, apiKey) => {
150
- const config = {
151
- instanceUrl: instanceUrl ?? process.env.SEARXNG_INSTANCE_URL,
152
- apiKey: apiKey ?? process.env.SEARXNG_API_KEY,
153
- defaultLocation: 'all',
154
- timeout: 10000,
155
- };
156
- if (config.instanceUrl == null || config.instanceUrl === '') {
157
- throw new Error('SEARXNG_INSTANCE_URL is required for SearXNG API');
158
- }
159
- const getSources = async ({ query, numResults = 8, safeSearch, type, }) => {
160
- if (!query.trim()) {
161
- return { success: false, error: 'Query cannot be empty' };
162
- }
163
- try {
164
- // Ensure the instance URL ends with /search
165
- if (config.instanceUrl == null || config.instanceUrl === '') {
166
- return { success: false, error: 'Instance URL is not defined' };
167
- }
168
- let searchUrl = config.instanceUrl;
169
- if (!searchUrl.endsWith('/search')) {
170
- searchUrl = searchUrl.replace(/\/$/, '') + '/search';
171
- }
172
- // Determine the search category based on the type
173
- let category = 'general';
174
- if (type === 'images') {
175
- category = 'images';
176
- }
177
- else if (type === 'videos') {
178
- category = 'videos';
179
- }
180
- else if (type === 'news') {
181
- category = 'news';
182
- }
183
- // Prepare parameters for SearXNG
184
- const params = {
185
- q: query,
186
- format: 'json',
187
- pageno: 1,
188
- categories: category,
189
- language: 'all',
190
- safesearch: safeSearch,
191
- engines: 'google,bing,duckduckgo',
192
- };
193
- const headers = {
194
- 'Content-Type': 'application/json',
195
- };
196
- if (config.apiKey != null && config.apiKey !== '') {
197
- headers['X-API-Key'] = config.apiKey;
198
- }
199
- const response = await axios.get(searchUrl, {
200
- headers,
201
- params,
202
- timeout: config.timeout,
203
- });
204
- const data = response.data;
205
- // Helper function to identify news results since SearXNG doesn't provide that classification by default
206
- const isNewsResult = (result) => {
207
- const url = result.url?.toLowerCase() ?? '';
208
- const title = result.title?.toLowerCase() ?? '';
209
- // News-related keywords in title/content
210
- const newsKeywords = [
211
- 'breaking news',
212
- 'latest news',
213
- 'top stories',
214
- 'news today',
215
- 'developing story',
216
- 'trending news',
217
- 'news',
218
- ];
219
- // Check if title/content contains news keywords
220
- const hasNewsKeywords = newsKeywords.some((keyword) => title.toLowerCase().includes(keyword) // just title probably fine, content parsing is overkill for what we need: || content.includes(keyword)
221
- );
222
- // Check if URL contains news-related paths
223
- const hasNewsPath = url.includes('/news/') ||
224
- url.includes('/world/') ||
225
- url.includes('/politics/') ||
226
- url.includes('/breaking/');
227
- return hasNewsKeywords || hasNewsPath;
228
- };
229
- // Transform SearXNG results to match SerperAPI format
230
- const organicResults = (data.results ?? [])
231
- .slice(0, numResults)
232
- .map((result, index) => {
233
- let attribution = '';
234
- try {
235
- attribution = new URL(result.url ?? '').hostname;
236
- }
237
- catch {
238
- attribution = '';
239
- }
240
- return {
241
- position: index + 1,
242
- title: result.title ?? '',
243
- link: result.url ?? '',
244
- snippet: result.content ?? '',
245
- date: result.publishedDate ?? '',
246
- attribution,
247
- };
248
- });
249
- const imageResults = (data.results ?? [])
250
- .filter((result) => result.img_src)
251
- .slice(0, 6)
252
- .map((result, index) => ({
253
- title: result.title ?? '',
254
- imageUrl: result.img_src ?? '',
255
- position: index + 1,
256
- source: new URL(result.url ?? '').hostname,
257
- domain: new URL(result.url ?? '').hostname,
258
- link: result.url ?? '',
259
- }));
260
- // Extract news results from organic results
261
- const newsResults = (data.results ?? [])
262
- .filter(isNewsResult)
263
- .map((result, index) => {
264
- let attribution = '';
265
- try {
266
- attribution = new URL(result.url ?? '').hostname;
267
- }
268
- catch {
269
- attribution = '';
270
- }
271
- return {
272
- title: result.title ?? '',
273
- link: result.url ?? '',
274
- snippet: result.content ?? '',
275
- date: result.publishedDate ?? '',
276
- source: attribution,
277
- imageUrl: result.img_src ?? '',
278
- position: index + 1,
279
- };
280
- });
281
- const topStories = newsResults.slice(0, 5);
282
- const relatedSearches = Array.isArray(data.suggestions)
283
- ? data.suggestions.map((suggestion) => ({ query: suggestion }))
284
- : [];
285
- const results = {
286
- organic: organicResults,
287
- images: imageResults,
288
- topStories: topStories, // Use first 5 extracted news as top stories
289
- relatedSearches,
290
- videos: [],
291
- news: newsResults,
292
- // Add empty arrays for other Serper fields to maintain parity
293
- places: [],
294
- shopping: [],
295
- peopleAlsoAsk: [],
296
- knowledgeGraph: undefined,
297
- answerBox: undefined,
298
- };
299
- return { success: true, data: results };
300
- }
301
- catch (error) {
302
- const errorMessage = error instanceof Error ? error.message : String(error);
303
- return {
304
- success: false,
305
- error: `SearXNG API request failed: ${errorMessage}`,
306
- };
307
- }
308
- };
309
- return { getSources };
134
+ const config = {
135
+ instanceUrl: instanceUrl ?? process.env.SEARXNG_INSTANCE_URL,
136
+ apiKey: apiKey ?? process.env.SEARXNG_API_KEY,
137
+ defaultLocation: "all",
138
+ timeout: 1e4
139
+ };
140
+ if (config.instanceUrl == null || config.instanceUrl === "") throw new Error("SEARXNG_INSTANCE_URL is required for SearXNG API");
141
+ const getSources = async ({ query, numResults = 8, safeSearch, type }) => {
142
+ if (!query.trim()) return {
143
+ success: false,
144
+ error: "Query cannot be empty"
145
+ };
146
+ try {
147
+ if (config.instanceUrl == null || config.instanceUrl === "") return {
148
+ success: false,
149
+ error: "Instance URL is not defined"
150
+ };
151
+ let searchUrl = config.instanceUrl;
152
+ if (!searchUrl.endsWith("/search")) searchUrl = searchUrl.replace(/\/$/, "") + "/search";
153
+ let category = "general";
154
+ if (type === "images") category = "images";
155
+ else if (type === "videos") category = "videos";
156
+ else if (type === "news") category = "news";
157
+ const params = {
158
+ q: query,
159
+ format: "json",
160
+ pageno: 1,
161
+ categories: category,
162
+ language: "all",
163
+ safesearch: safeSearch,
164
+ engines: "google,bing,duckduckgo"
165
+ };
166
+ const headers = { "Content-Type": "application/json" };
167
+ if (config.apiKey != null && config.apiKey !== "") headers["X-API-Key"] = config.apiKey;
168
+ const data = (await axios.default.get(searchUrl, {
169
+ headers,
170
+ params,
171
+ timeout: config.timeout
172
+ })).data;
173
+ const isNewsResult = (result) => {
174
+ const url = result.url?.toLowerCase() ?? "";
175
+ const title = result.title?.toLowerCase() ?? "";
176
+ const hasNewsKeywords = [
177
+ "breaking news",
178
+ "latest news",
179
+ "top stories",
180
+ "news today",
181
+ "developing story",
182
+ "trending news",
183
+ "news"
184
+ ].some((keyword) => title.toLowerCase().includes(keyword));
185
+ const hasNewsPath = url.includes("/news/") || url.includes("/world/") || url.includes("/politics/") || url.includes("/breaking/");
186
+ return hasNewsKeywords || hasNewsPath;
187
+ };
188
+ const organicResults = (data.results ?? []).slice(0, numResults).map((result, index) => {
189
+ let attribution = "";
190
+ try {
191
+ attribution = new URL(result.url ?? "").hostname;
192
+ } catch {
193
+ attribution = "";
194
+ }
195
+ return {
196
+ position: index + 1,
197
+ title: result.title ?? "",
198
+ link: result.url ?? "",
199
+ snippet: result.content ?? "",
200
+ date: result.publishedDate ?? "",
201
+ attribution
202
+ };
203
+ });
204
+ const imageResults = (data.results ?? []).filter((result) => result.img_src).slice(0, 6).map((result, index) => ({
205
+ title: result.title ?? "",
206
+ imageUrl: result.img_src ?? "",
207
+ position: index + 1,
208
+ source: new URL(result.url ?? "").hostname,
209
+ domain: new URL(result.url ?? "").hostname,
210
+ link: result.url ?? ""
211
+ }));
212
+ const newsResults = (data.results ?? []).filter(isNewsResult).map((result, index) => {
213
+ let attribution = "";
214
+ try {
215
+ attribution = new URL(result.url ?? "").hostname;
216
+ } catch {
217
+ attribution = "";
218
+ }
219
+ return {
220
+ title: result.title ?? "",
221
+ link: result.url ?? "",
222
+ snippet: result.content ?? "",
223
+ date: result.publishedDate ?? "",
224
+ source: attribution,
225
+ imageUrl: result.img_src ?? "",
226
+ position: index + 1
227
+ };
228
+ });
229
+ return {
230
+ success: true,
231
+ data: {
232
+ organic: organicResults,
233
+ images: imageResults,
234
+ topStories: newsResults.slice(0, 5),
235
+ relatedSearches: Array.isArray(data.suggestions) ? data.suggestions.map((suggestion) => ({ query: suggestion })) : [],
236
+ videos: [],
237
+ news: newsResults,
238
+ places: [],
239
+ shopping: [],
240
+ peopleAlsoAsk: [],
241
+ knowledgeGraph: void 0,
242
+ answerBox: void 0
243
+ }
244
+ };
245
+ } catch (error) {
246
+ return {
247
+ success: false,
248
+ error: `SearXNG API request failed: ${error instanceof Error ? error.message : String(error)}`
249
+ };
250
+ }
251
+ };
252
+ return { getSources };
310
253
  };
311
254
  const createSearchAPI = (config) => {
312
- const { searchProvider = 'serper', serperApiKey, searxngInstanceUrl, searxngApiKey, tavilyApiKey, tavilySearchUrl, tavilySearchOptions, } = config;
313
- if (searchProvider.toLowerCase() === 'serper') {
314
- return createSerperAPI(serperApiKey);
315
- }
316
- else if (searchProvider.toLowerCase() === 'searxng') {
317
- return createSearXNGAPI(searxngInstanceUrl, searxngApiKey);
318
- }
319
- else if (searchProvider.toLowerCase() === 'tavily') {
320
- return tavilySearch.createTavilyAPI(tavilyApiKey, tavilySearchUrl, tavilySearchOptions);
321
- }
322
- else {
323
- throw new Error(`Invalid search provider: ${searchProvider}. Must be 'serper', 'searxng', or 'tavily'`);
324
- }
255
+ const { searchProvider = "serper", serperApiKey, searxngInstanceUrl, searxngApiKey, tavilyApiKey, tavilySearchUrl, tavilySearchOptions } = config;
256
+ if (searchProvider.toLowerCase() === "serper") return createSerperAPI(serperApiKey);
257
+ else if (searchProvider.toLowerCase() === "searxng") return createSearXNGAPI(searxngInstanceUrl, searxngApiKey);
258
+ else if (searchProvider.toLowerCase() === "tavily") return require_tavily_search.createTavilyAPI(tavilyApiKey, tavilySearchUrl, tavilySearchOptions);
259
+ else throw new Error(`Invalid search provider: ${searchProvider}. Must be 'serper', 'searxng', or 'tavily'`);
325
260
  };
326
261
  const createSourceProcessor = (config = {}, scraperInstance) => {
327
- if (!scraperInstance) {
328
- throw new Error('Scraper instance is required');
329
- }
330
- const { topResults = 5,
331
- // strategies = ['no_extraction'],
332
- // filterContent = true,
333
- reranker, logger, } = config;
334
- const logger_ = logger || utils.createDefaultLogger();
335
- const scraper = scraperInstance;
336
- const processResponse = (url, response) => {
337
- const rawMetadata = scraper.extractMetadata(response);
338
- const metadata = Object.keys(rawMetadata).length > 0 ? rawMetadata : undefined;
339
- const attribution = utils.getAttribution(url, metadata, logger_);
340
- if (response.success && response.data) {
341
- const [content, references] = scraper.extractContent(response);
342
- return {
343
- url,
344
- references,
345
- attribution,
346
- content: chunker.cleanText(content),
347
- };
348
- }
349
- logger_.error(`Error scraping ${url}: ${response.error ?? 'Unknown error'}`);
350
- return { url, attribution, error: true, content: '' };
351
- };
352
- const addHighlights = async (result, query, onGetHighlights) => {
353
- if (result.error != null) {
354
- return result;
355
- }
356
- try {
357
- const highlights = await getHighlights({
358
- query,
359
- reranker,
360
- content: result.content,
361
- logger: logger_,
362
- });
363
- if (onGetHighlights) {
364
- onGetHighlights(result.url);
365
- }
366
- return { ...result, highlights };
367
- }
368
- catch (error) {
369
- logger_.error('Error processing scraped content:', error);
370
- return result;
371
- }
372
- };
373
- const webScraper = {
374
- scrapeMany: async ({ query, links, onGetHighlights, }) => {
375
- logger_.debug(`Scraping ${links.length} links`);
376
- try {
377
- let responses;
378
- if (scraper.scrapeUrls) {
379
- responses = await scraper.scrapeUrls(links);
380
- }
381
- else {
382
- responses = await Promise.all(links.map((link) => scraper
383
- .scrapeUrl(link, {})
384
- .catch((error) => {
385
- logger_.error(`Error scraping ${link}:`, error);
386
- return [link, { success: false, error: String(error) }];
387
- })));
388
- }
389
- const withHighlights = await Promise.all(responses.map(([url, response]) => addHighlights(processResponse(url, response), query, onGetHighlights)));
390
- return withHighlights;
391
- }
392
- catch (error) {
393
- logger_.error('Error in scrapeMany:', error);
394
- return [];
395
- }
396
- },
397
- };
398
- const fetchContents = async ({ links, query, target, onGetHighlights, onContentScraped, }) => {
399
- const initialLinks = links.slice(0, target);
400
- // const remainingLinks = links.slice(target).reverse();
401
- const results = await webScraper.scrapeMany({
402
- query,
403
- links: initialLinks,
404
- onGetHighlights,
405
- });
406
- for (const result of results) {
407
- if (result.error === true) {
408
- continue;
409
- }
410
- const { url, content, attribution, references, highlights } = result;
411
- onContentScraped?.(url, {
412
- content,
413
- attribution,
414
- references,
415
- highlights,
416
- });
417
- }
418
- };
419
- const processSources = async ({ result, numElements, query, news, proMode = true, onGetHighlights, }) => {
420
- try {
421
- if (!result.data) {
422
- return {
423
- organic: [],
424
- topStories: [],
425
- images: [],
426
- relatedSearches: [],
427
- };
428
- }
429
- else if (!result.data.organic) {
430
- return result.data;
431
- }
432
- if (!proMode) {
433
- const wikiSources = result.data.organic.filter((source) => source.link.includes('wikipedia.org'));
434
- if (!wikiSources.length) {
435
- return result.data;
436
- }
437
- const wikiSourceMap = new Map();
438
- wikiSourceMap.set(wikiSources[0].link, wikiSources[0]);
439
- const onContentScraped = createSourceUpdateCallback(wikiSourceMap);
440
- await fetchContents({
441
- query,
442
- target: 1,
443
- onGetHighlights,
444
- onContentScraped,
445
- links: [wikiSources[0].link],
446
- });
447
- for (let i = 0; i < result.data.organic.length; i++) {
448
- const source = result.data.organic[i];
449
- const updatedSource = wikiSourceMap.get(source.link);
450
- if (updatedSource) {
451
- result.data.organic[i] = {
452
- ...source,
453
- ...updatedSource,
454
- };
455
- }
456
- }
457
- return result.data;
458
- }
459
- const sourceMap = new Map();
460
- const organicLinksSet = new Set();
461
- // Collect organic links
462
- const organicLinks = collectLinks(result.data.organic, sourceMap, organicLinksSet);
463
- // Collect top story links, excluding any that are already in organic links
464
- const topStories = result.data.topStories ?? [];
465
- const topStoryLinks = collectLinks(topStories, sourceMap, organicLinksSet);
466
- if (organicLinks.length === 0 && (topStoryLinks.length === 0 || !news)) {
467
- return result.data;
468
- }
469
- const onContentScraped = createSourceUpdateCallback(sourceMap);
470
- const promises = [];
471
- // Process organic links
472
- if (organicLinks.length > 0) {
473
- promises.push(fetchContents({
474
- query,
475
- onGetHighlights,
476
- onContentScraped,
477
- links: organicLinks,
478
- target: numElements,
479
- }));
480
- }
481
- // Process top story links
482
- if (news && topStoryLinks.length > 0) {
483
- promises.push(fetchContents({
484
- query,
485
- onGetHighlights,
486
- onContentScraped,
487
- links: topStoryLinks,
488
- target: numElements,
489
- }));
490
- }
491
- await Promise.all(promises);
492
- if (result.data.organic.length > 0) {
493
- updateSourcesWithContent(result.data.organic, sourceMap);
494
- }
495
- if (news && topStories.length > 0) {
496
- updateSourcesWithContent(topStories, sourceMap);
497
- }
498
- return result.data;
499
- }
500
- catch (error) {
501
- logger_.error('Error in processSources:', error);
502
- return {
503
- organic: [],
504
- topStories: [],
505
- images: [],
506
- relatedSearches: [],
507
- ...result.data,
508
- error: error instanceof Error ? error.message : String(error),
509
- };
510
- }
511
- };
512
- return {
513
- processSources,
514
- topResults,
515
- };
262
+ if (!scraperInstance) throw new Error("Scraper instance is required");
263
+ const { topResults = 5, reranker, logger } = config;
264
+ const maxContentLength = resolveMaxContentLength(config.maxContentLength);
265
+ const logger_ = logger || require_utils.createDefaultLogger();
266
+ const scraper = scraperInstance;
267
+ const processResponse = (url, response) => {
268
+ const rawMetadata = scraper.extractMetadata(response);
269
+ const attribution = require_utils.getAttribution(url, Object.keys(rawMetadata).length > 0 ? rawMetadata : void 0, logger_);
270
+ if (response.success && response.data) {
271
+ const [content, references] = scraper.extractContent(response);
272
+ return {
273
+ url,
274
+ references,
275
+ attribution,
276
+ content: truncateContent(chunker.cleanText(content), maxContentLength)
277
+ };
278
+ }
279
+ logger_.error(`Error scraping ${url}: ${response.error ?? "Unknown error"}`);
280
+ return {
281
+ url,
282
+ attribution,
283
+ error: true,
284
+ content: ""
285
+ };
286
+ };
287
+ const addHighlights = async (result, query, onGetHighlights) => {
288
+ if (result.error != null) return result;
289
+ try {
290
+ const highlights = await getHighlights({
291
+ query,
292
+ reranker,
293
+ content: result.content,
294
+ maxContentLength,
295
+ logger: logger_
296
+ });
297
+ if (onGetHighlights) onGetHighlights(result.url);
298
+ return {
299
+ ...result,
300
+ highlights
301
+ };
302
+ } catch (error) {
303
+ logger_.error("Error processing scraped content:", error);
304
+ return result;
305
+ }
306
+ };
307
+ const webScraper = { scrapeMany: async ({ query, links, onGetHighlights }) => {
308
+ logger_.debug(`Scraping ${links.length} links`);
309
+ try {
310
+ let responses;
311
+ if (scraper.scrapeUrls) responses = await scraper.scrapeUrls(links);
312
+ else responses = await Promise.all(links.map((link) => scraper.scrapeUrl(link, {}).catch((error) => {
313
+ logger_.error(`Error scraping ${link}:`, error);
314
+ return [link, {
315
+ success: false,
316
+ error: String(error)
317
+ }];
318
+ })));
319
+ return await Promise.all(responses.map(([url, response]) => addHighlights(processResponse(url, response), query, onGetHighlights)));
320
+ } catch (error) {
321
+ logger_.error("Error in scrapeMany:", error);
322
+ return [];
323
+ }
324
+ } };
325
+ const fetchContents = async ({ links, query, target, onGetHighlights, onContentScraped }) => {
326
+ const initialLinks = links.slice(0, target);
327
+ const results = await webScraper.scrapeMany({
328
+ query,
329
+ links: initialLinks,
330
+ onGetHighlights
331
+ });
332
+ for (const result of results) {
333
+ if (result.error === true) continue;
334
+ const { url, content, attribution, references, highlights } = result;
335
+ onContentScraped?.(url, {
336
+ content,
337
+ attribution,
338
+ references,
339
+ highlights
340
+ });
341
+ }
342
+ };
343
+ const processSources = async ({ result, numElements, query, news, proMode = true, onGetHighlights }) => {
344
+ try {
345
+ if (!result.data) return {
346
+ organic: [],
347
+ topStories: [],
348
+ images: [],
349
+ relatedSearches: []
350
+ };
351
+ if (result.data.topStories != null && result.data.topStories.length > numElements)
352
+ /** Merged news results can far exceed the requested source count;
353
+ * every entry is formatted into the LLM output, so cap them up
354
+ * front before any early return below and before scraping
355
+ * entries the cap would discard */
356
+ result.data.topStories = result.data.topStories.slice(0, numElements);
357
+ if (!result.data.organic) return result.data;
358
+ if (!proMode) {
359
+ const wikiSources = result.data.organic.filter((source) => source.link.includes("wikipedia.org"));
360
+ if (!wikiSources.length) return result.data;
361
+ const wikiSourceMap = /* @__PURE__ */ new Map();
362
+ wikiSourceMap.set(wikiSources[0].link, wikiSources[0]);
363
+ await fetchContents({
364
+ query,
365
+ target: 1,
366
+ onGetHighlights,
367
+ onContentScraped: createSourceUpdateCallback(wikiSourceMap),
368
+ links: [wikiSources[0].link]
369
+ });
370
+ for (let i = 0; i < result.data.organic.length; i++) {
371
+ const source = result.data.organic[i];
372
+ const updatedSource = wikiSourceMap.get(source.link);
373
+ if (updatedSource) result.data.organic[i] = {
374
+ ...source,
375
+ ...updatedSource
376
+ };
377
+ }
378
+ return result.data;
379
+ }
380
+ const sourceMap = /* @__PURE__ */ new Map();
381
+ const organicLinksSet = /* @__PURE__ */ new Set();
382
+ const organicLinks = collectLinks(result.data.organic, sourceMap, organicLinksSet);
383
+ const topStories = result.data.topStories ?? [];
384
+ const topStoryLinks = collectLinks(topStories, sourceMap, organicLinksSet);
385
+ if (organicLinks.length === 0 && (topStoryLinks.length === 0 || !news)) return result.data;
386
+ const onContentScraped = createSourceUpdateCallback(sourceMap);
387
+ const promises = [];
388
+ if (organicLinks.length > 0) promises.push(fetchContents({
389
+ query,
390
+ onGetHighlights,
391
+ onContentScraped,
392
+ links: organicLinks,
393
+ target: numElements
394
+ }));
395
+ if (news && topStoryLinks.length > 0) promises.push(fetchContents({
396
+ query,
397
+ onGetHighlights,
398
+ onContentScraped,
399
+ links: topStoryLinks,
400
+ target: numElements
401
+ }));
402
+ await Promise.all(promises);
403
+ if (result.data.organic.length > 0) updateSourcesWithContent(result.data.organic, sourceMap);
404
+ if (news && topStories.length > 0) updateSourcesWithContent(topStories, sourceMap);
405
+ return result.data;
406
+ } catch (error) {
407
+ logger_.error("Error in processSources:", error);
408
+ return {
409
+ organic: [],
410
+ topStories: [],
411
+ images: [],
412
+ relatedSearches: [],
413
+ ...result.data,
414
+ error: error instanceof Error ? error.message : String(error)
415
+ };
416
+ }
417
+ };
418
+ return {
419
+ processSources,
420
+ topResults
421
+ };
516
422
  };
517
423
  /** Helper function to collect links and update sourceMap */
518
424
  function collectLinks(sources, sourceMap, existingLinksSet) {
519
- const links = [];
520
- for (const source of sources) {
521
- if (source.link) {
522
- // For topStories, only add if not already in organic links
523
- if (existingLinksSet && existingLinksSet.has(source.link)) {
524
- continue;
525
- }
526
- links.push(source.link);
527
- if (existingLinksSet) {
528
- existingLinksSet.add(source.link);
529
- }
530
- sourceMap.set(source.link, source);
531
- }
532
- }
533
- return links;
425
+ const links = [];
426
+ for (const source of sources) if (source.link) {
427
+ if (existingLinksSet && existingLinksSet.has(source.link)) continue;
428
+ links.push(source.link);
429
+ if (existingLinksSet) existingLinksSet.add(source.link);
430
+ sourceMap.set(source.link, source);
431
+ }
432
+ return links;
534
433
  }
535
434
  /** Helper function to update sources with scraped content */
536
435
  function updateSourcesWithContent(sources, sourceMap) {
537
- for (let i = 0; i < sources.length; i++) {
538
- const source = sources[i];
539
- const updatedSource = sourceMap.get(source.link);
540
- if (updatedSource) {
541
- sources[i] = {
542
- ...source,
543
- ...updatedSource,
544
- };
545
- }
546
- }
436
+ for (let i = 0; i < sources.length; i++) {
437
+ const source = sources[i];
438
+ const updatedSource = sourceMap.get(source.link);
439
+ if (updatedSource) sources[i] = {
440
+ ...source,
441
+ ...updatedSource
442
+ };
443
+ }
547
444
  }
548
-
445
+ //#endregion
549
446
  exports.createSearchAPI = createSearchAPI;
550
447
  exports.createSourceProcessor = createSourceProcessor;
551
- //# sourceMappingURL=search.cjs.map
448
+
449
+ //# sourceMappingURL=search.cjs.map