@librechat/agents 3.1.75 → 3.1.77-dev.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 (272) hide show
  1. package/dist/cjs/graphs/Graph.cjs +22 -3
  2. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  3. package/dist/cjs/hitl/askUserQuestion.cjs +67 -0
  4. package/dist/cjs/hitl/askUserQuestion.cjs.map +1 -0
  5. package/dist/cjs/hooks/HookRegistry.cjs +54 -0
  6. package/dist/cjs/hooks/HookRegistry.cjs.map +1 -1
  7. package/dist/cjs/hooks/createToolPolicyHook.cjs +115 -0
  8. package/dist/cjs/hooks/createToolPolicyHook.cjs.map +1 -0
  9. package/dist/cjs/hooks/executeHooks.cjs +40 -1
  10. package/dist/cjs/hooks/executeHooks.cjs.map +1 -1
  11. package/dist/cjs/hooks/types.cjs +1 -0
  12. package/dist/cjs/hooks/types.cjs.map +1 -1
  13. package/dist/cjs/langchain/google-common.cjs +3 -0
  14. package/dist/cjs/langchain/google-common.cjs.map +1 -0
  15. package/dist/cjs/langchain/index.cjs +86 -0
  16. package/dist/cjs/langchain/index.cjs.map +1 -0
  17. package/dist/cjs/langchain/language_models/chat_models.cjs +3 -0
  18. package/dist/cjs/langchain/language_models/chat_models.cjs.map +1 -0
  19. package/dist/cjs/langchain/messages/tool.cjs +3 -0
  20. package/dist/cjs/langchain/messages/tool.cjs.map +1 -0
  21. package/dist/cjs/langchain/messages.cjs +51 -0
  22. package/dist/cjs/langchain/messages.cjs.map +1 -0
  23. package/dist/cjs/langchain/openai.cjs +3 -0
  24. package/dist/cjs/langchain/openai.cjs.map +1 -0
  25. package/dist/cjs/langchain/prompts.cjs +11 -0
  26. package/dist/cjs/langchain/prompts.cjs.map +1 -0
  27. package/dist/cjs/langchain/runnables.cjs +19 -0
  28. package/dist/cjs/langchain/runnables.cjs.map +1 -0
  29. package/dist/cjs/langchain/tools.cjs +23 -0
  30. package/dist/cjs/langchain/tools.cjs.map +1 -0
  31. package/dist/cjs/langchain/utils/env.cjs +11 -0
  32. package/dist/cjs/langchain/utils/env.cjs.map +1 -0
  33. package/dist/cjs/llm/anthropic/index.cjs +145 -52
  34. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  35. package/dist/cjs/llm/anthropic/types.cjs.map +1 -1
  36. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +21 -14
  37. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  38. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs +84 -70
  39. package/dist/cjs/llm/anthropic/utils/message_outputs.cjs.map +1 -1
  40. package/dist/cjs/llm/bedrock/index.cjs +1 -1
  41. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  42. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +213 -3
  43. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  44. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs +2 -1
  45. package/dist/cjs/llm/bedrock/utils/message_outputs.cjs.map +1 -1
  46. package/dist/cjs/llm/google/utils/common.cjs +5 -4
  47. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  48. package/dist/cjs/llm/openai/index.cjs +519 -655
  49. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  50. package/dist/cjs/llm/openai/utils/index.cjs +20 -458
  51. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  52. package/dist/cjs/llm/openrouter/index.cjs +57 -175
  53. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  54. package/dist/cjs/llm/vertexai/index.cjs +5 -3
  55. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  56. package/dist/cjs/main.cjs +112 -3
  57. package/dist/cjs/main.cjs.map +1 -1
  58. package/dist/cjs/messages/cache.cjs +2 -1
  59. package/dist/cjs/messages/cache.cjs.map +1 -1
  60. package/dist/cjs/messages/core.cjs +7 -6
  61. package/dist/cjs/messages/core.cjs.map +1 -1
  62. package/dist/cjs/messages/format.cjs +73 -15
  63. package/dist/cjs/messages/format.cjs.map +1 -1
  64. package/dist/cjs/messages/langchain.cjs +26 -0
  65. package/dist/cjs/messages/langchain.cjs.map +1 -0
  66. package/dist/cjs/messages/prune.cjs +7 -6
  67. package/dist/cjs/messages/prune.cjs.map +1 -1
  68. package/dist/cjs/run.cjs +400 -42
  69. package/dist/cjs/run.cjs.map +1 -1
  70. package/dist/cjs/tools/ToolNode.cjs +556 -56
  71. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  72. package/dist/cjs/tools/search/search.cjs +55 -66
  73. package/dist/cjs/tools/search/search.cjs.map +1 -1
  74. package/dist/cjs/tools/search/tavily-scraper.cjs +189 -0
  75. package/dist/cjs/tools/search/tavily-scraper.cjs.map +1 -0
  76. package/dist/cjs/tools/search/tavily-search.cjs +372 -0
  77. package/dist/cjs/tools/search/tavily-search.cjs.map +1 -0
  78. package/dist/cjs/tools/search/tool.cjs +26 -4
  79. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  80. package/dist/cjs/tools/search/utils.cjs +10 -3
  81. package/dist/cjs/tools/search/utils.cjs.map +1 -1
  82. package/dist/esm/graphs/Graph.mjs +22 -3
  83. package/dist/esm/graphs/Graph.mjs.map +1 -1
  84. package/dist/esm/hitl/askUserQuestion.mjs +65 -0
  85. package/dist/esm/hitl/askUserQuestion.mjs.map +1 -0
  86. package/dist/esm/hooks/HookRegistry.mjs +54 -0
  87. package/dist/esm/hooks/HookRegistry.mjs.map +1 -1
  88. package/dist/esm/hooks/createToolPolicyHook.mjs +113 -0
  89. package/dist/esm/hooks/createToolPolicyHook.mjs.map +1 -0
  90. package/dist/esm/hooks/executeHooks.mjs +40 -1
  91. package/dist/esm/hooks/executeHooks.mjs.map +1 -1
  92. package/dist/esm/hooks/types.mjs +1 -0
  93. package/dist/esm/hooks/types.mjs.map +1 -1
  94. package/dist/esm/langchain/google-common.mjs +2 -0
  95. package/dist/esm/langchain/google-common.mjs.map +1 -0
  96. package/dist/esm/langchain/index.mjs +5 -0
  97. package/dist/esm/langchain/index.mjs.map +1 -0
  98. package/dist/esm/langchain/language_models/chat_models.mjs +2 -0
  99. package/dist/esm/langchain/language_models/chat_models.mjs.map +1 -0
  100. package/dist/esm/langchain/messages/tool.mjs +2 -0
  101. package/dist/esm/langchain/messages/tool.mjs.map +1 -0
  102. package/dist/esm/langchain/messages.mjs +2 -0
  103. package/dist/esm/langchain/messages.mjs.map +1 -0
  104. package/dist/esm/langchain/openai.mjs +2 -0
  105. package/dist/esm/langchain/openai.mjs.map +1 -0
  106. package/dist/esm/langchain/prompts.mjs +2 -0
  107. package/dist/esm/langchain/prompts.mjs.map +1 -0
  108. package/dist/esm/langchain/runnables.mjs +2 -0
  109. package/dist/esm/langchain/runnables.mjs.map +1 -0
  110. package/dist/esm/langchain/tools.mjs +2 -0
  111. package/dist/esm/langchain/tools.mjs.map +1 -0
  112. package/dist/esm/langchain/utils/env.mjs +2 -0
  113. package/dist/esm/langchain/utils/env.mjs.map +1 -0
  114. package/dist/esm/llm/anthropic/index.mjs +146 -54
  115. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  116. package/dist/esm/llm/anthropic/types.mjs.map +1 -1
  117. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +21 -14
  118. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  119. package/dist/esm/llm/anthropic/utils/message_outputs.mjs +84 -71
  120. package/dist/esm/llm/anthropic/utils/message_outputs.mjs.map +1 -1
  121. package/dist/esm/llm/bedrock/index.mjs +1 -1
  122. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  123. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +214 -4
  124. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  125. package/dist/esm/llm/bedrock/utils/message_outputs.mjs +2 -1
  126. package/dist/esm/llm/bedrock/utils/message_outputs.mjs.map +1 -1
  127. package/dist/esm/llm/google/utils/common.mjs +5 -4
  128. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  129. package/dist/esm/llm/openai/index.mjs +520 -656
  130. package/dist/esm/llm/openai/index.mjs.map +1 -1
  131. package/dist/esm/llm/openai/utils/index.mjs +23 -459
  132. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  133. package/dist/esm/llm/openrouter/index.mjs +57 -175
  134. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  135. package/dist/esm/llm/vertexai/index.mjs +5 -3
  136. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  137. package/dist/esm/main.mjs +7 -0
  138. package/dist/esm/main.mjs.map +1 -1
  139. package/dist/esm/messages/cache.mjs +2 -1
  140. package/dist/esm/messages/cache.mjs.map +1 -1
  141. package/dist/esm/messages/core.mjs +7 -6
  142. package/dist/esm/messages/core.mjs.map +1 -1
  143. package/dist/esm/messages/format.mjs +73 -15
  144. package/dist/esm/messages/format.mjs.map +1 -1
  145. package/dist/esm/messages/langchain.mjs +23 -0
  146. package/dist/esm/messages/langchain.mjs.map +1 -0
  147. package/dist/esm/messages/prune.mjs +7 -6
  148. package/dist/esm/messages/prune.mjs.map +1 -1
  149. package/dist/esm/run.mjs +400 -42
  150. package/dist/esm/run.mjs.map +1 -1
  151. package/dist/esm/tools/ToolNode.mjs +557 -57
  152. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  153. package/dist/esm/tools/search/search.mjs +55 -66
  154. package/dist/esm/tools/search/search.mjs.map +1 -1
  155. package/dist/esm/tools/search/tavily-scraper.mjs +186 -0
  156. package/dist/esm/tools/search/tavily-scraper.mjs.map +1 -0
  157. package/dist/esm/tools/search/tavily-search.mjs +370 -0
  158. package/dist/esm/tools/search/tavily-search.mjs.map +1 -0
  159. package/dist/esm/tools/search/tool.mjs +26 -4
  160. package/dist/esm/tools/search/tool.mjs.map +1 -1
  161. package/dist/esm/tools/search/utils.mjs +10 -3
  162. package/dist/esm/tools/search/utils.mjs.map +1 -1
  163. package/dist/types/graphs/Graph.d.ts +7 -0
  164. package/dist/types/hitl/askUserQuestion.d.ts +55 -0
  165. package/dist/types/hitl/index.d.ts +6 -0
  166. package/dist/types/hooks/HookRegistry.d.ts +58 -0
  167. package/dist/types/hooks/createToolPolicyHook.d.ts +87 -0
  168. package/dist/types/hooks/index.d.ts +4 -1
  169. package/dist/types/hooks/types.d.ts +109 -3
  170. package/dist/types/index.d.ts +10 -0
  171. package/dist/types/langchain/google-common.d.ts +1 -0
  172. package/dist/types/langchain/index.d.ts +8 -0
  173. package/dist/types/langchain/language_models/chat_models.d.ts +1 -0
  174. package/dist/types/langchain/messages/tool.d.ts +1 -0
  175. package/dist/types/langchain/messages.d.ts +2 -0
  176. package/dist/types/langchain/openai.d.ts +1 -0
  177. package/dist/types/langchain/prompts.d.ts +1 -0
  178. package/dist/types/langchain/runnables.d.ts +2 -0
  179. package/dist/types/langchain/tools.d.ts +2 -0
  180. package/dist/types/langchain/utils/env.d.ts +1 -0
  181. package/dist/types/llm/anthropic/index.d.ts +22 -9
  182. package/dist/types/llm/anthropic/types.d.ts +5 -1
  183. package/dist/types/llm/anthropic/utils/message_outputs.d.ts +13 -6
  184. package/dist/types/llm/anthropic/utils/output_parsers.d.ts +1 -1
  185. package/dist/types/llm/openai/index.d.ts +21 -24
  186. package/dist/types/llm/openrouter/index.d.ts +11 -9
  187. package/dist/types/llm/vertexai/index.d.ts +1 -0
  188. package/dist/types/messages/cache.d.ts +4 -1
  189. package/dist/types/messages/format.d.ts +4 -1
  190. package/dist/types/messages/langchain.d.ts +27 -0
  191. package/dist/types/run.d.ts +117 -1
  192. package/dist/types/tools/ToolNode.d.ts +26 -1
  193. package/dist/types/tools/search/tavily-scraper.d.ts +19 -0
  194. package/dist/types/tools/search/tavily-search.d.ts +4 -0
  195. package/dist/types/tools/search/types.d.ts +99 -5
  196. package/dist/types/tools/search/utils.d.ts +2 -2
  197. package/dist/types/types/graph.d.ts +23 -37
  198. package/dist/types/types/hitl.d.ts +272 -0
  199. package/dist/types/types/index.d.ts +1 -0
  200. package/dist/types/types/llm.d.ts +3 -3
  201. package/dist/types/types/run.d.ts +33 -0
  202. package/dist/types/types/stream.d.ts +1 -1
  203. package/dist/types/types/tools.d.ts +19 -0
  204. package/package.json +80 -17
  205. package/src/graphs/Graph.ts +33 -4
  206. package/src/graphs/__tests__/composition.smoke.test.ts +188 -0
  207. package/src/hitl/askUserQuestion.ts +72 -0
  208. package/src/hitl/index.ts +7 -0
  209. package/src/hooks/HookRegistry.ts +71 -0
  210. package/src/hooks/__tests__/createToolPolicyHook.test.ts +259 -0
  211. package/src/hooks/createToolPolicyHook.ts +184 -0
  212. package/src/hooks/executeHooks.ts +50 -1
  213. package/src/hooks/index.ts +6 -0
  214. package/src/hooks/types.ts +112 -0
  215. package/src/index.ts +22 -0
  216. package/src/langchain/google-common.ts +1 -0
  217. package/src/langchain/index.ts +8 -0
  218. package/src/langchain/language_models/chat_models.ts +1 -0
  219. package/src/langchain/messages/tool.ts +5 -0
  220. package/src/langchain/messages.ts +21 -0
  221. package/src/langchain/openai.ts +1 -0
  222. package/src/langchain/prompts.ts +1 -0
  223. package/src/langchain/runnables.ts +7 -0
  224. package/src/langchain/tools.ts +8 -0
  225. package/src/langchain/utils/env.ts +1 -0
  226. package/src/llm/anthropic/index.ts +252 -84
  227. package/src/llm/anthropic/llm.spec.ts +751 -102
  228. package/src/llm/anthropic/types.ts +9 -1
  229. package/src/llm/anthropic/utils/message_inputs.ts +37 -19
  230. package/src/llm/anthropic/utils/message_outputs.ts +119 -101
  231. package/src/llm/bedrock/index.ts +2 -2
  232. package/src/llm/bedrock/llm.spec.ts +341 -0
  233. package/src/llm/bedrock/utils/message_inputs.ts +303 -4
  234. package/src/llm/bedrock/utils/message_outputs.ts +2 -1
  235. package/src/llm/custom-chat-models.smoke.test.ts +836 -0
  236. package/src/llm/google/llm.spec.ts +339 -57
  237. package/src/llm/google/utils/common.ts +53 -48
  238. package/src/llm/openai/contentBlocks.test.ts +346 -0
  239. package/src/llm/openai/index.ts +856 -833
  240. package/src/llm/openai/utils/index.ts +107 -78
  241. package/src/llm/openai/utils/messages.test.ts +159 -0
  242. package/src/llm/openrouter/index.ts +124 -247
  243. package/src/llm/openrouter/reasoning.test.ts +8 -1
  244. package/src/llm/vertexai/index.ts +11 -5
  245. package/src/llm/vertexai/llm.spec.ts +28 -1
  246. package/src/messages/cache.test.ts +4 -3
  247. package/src/messages/cache.ts +3 -2
  248. package/src/messages/core.ts +16 -9
  249. package/src/messages/format.ts +96 -16
  250. package/src/messages/formatAgentMessages.test.ts +166 -1
  251. package/src/messages/langchain.ts +39 -0
  252. package/src/messages/prune.ts +12 -8
  253. package/src/run.ts +456 -47
  254. package/src/scripts/caching.ts +2 -3
  255. package/src/specs/summarization.test.ts +51 -58
  256. package/src/tools/ToolNode.ts +706 -63
  257. package/src/tools/__tests__/hitl.test.ts +3593 -0
  258. package/src/tools/search/search.ts +83 -73
  259. package/src/tools/search/tavily-scraper.ts +235 -0
  260. package/src/tools/search/tavily-search.ts +424 -0
  261. package/src/tools/search/tavily.test.ts +965 -0
  262. package/src/tools/search/tool.ts +36 -26
  263. package/src/tools/search/types.ts +133 -8
  264. package/src/tools/search/utils.ts +13 -5
  265. package/src/types/graph.ts +32 -87
  266. package/src/types/hitl.ts +303 -0
  267. package/src/types/index.ts +1 -0
  268. package/src/types/llm.ts +3 -3
  269. package/src/types/run.ts +33 -0
  270. package/src/types/stream.ts +1 -1
  271. package/src/types/tools.ts +19 -0
  272. package/src/utils/llmConfig.ts +1 -6
@@ -0,0 +1,424 @@
1
+ import axios from 'axios';
2
+ import type * as t from './types';
3
+
4
+ const DEFAULT_TAVILY_TIMEOUT = 15000;
5
+
6
+ const TAVILY_COUNTRY_ALIASES: Record<string, string> = {
7
+ ba: 'bosnia and herzegovina',
8
+ cg: 'congo',
9
+ cz: 'czech republic',
10
+ gb: 'united kingdom',
11
+ mm: 'myanmar',
12
+ tr: 'turkey',
13
+ tt: 'trinidad and tobago',
14
+ uk: 'united kingdom',
15
+ };
16
+
17
+ const TAVILY_SUPPORTED_COUNTRIES = new Set([
18
+ 'afghanistan',
19
+ 'albania',
20
+ 'algeria',
21
+ 'andorra',
22
+ 'angola',
23
+ 'argentina',
24
+ 'armenia',
25
+ 'australia',
26
+ 'austria',
27
+ 'azerbaijan',
28
+ 'bahamas',
29
+ 'bahrain',
30
+ 'bangladesh',
31
+ 'barbados',
32
+ 'belarus',
33
+ 'belgium',
34
+ 'belize',
35
+ 'benin',
36
+ 'bhutan',
37
+ 'bolivia',
38
+ 'bosnia and herzegovina',
39
+ 'botswana',
40
+ 'brazil',
41
+ 'brunei',
42
+ 'bulgaria',
43
+ 'burkina faso',
44
+ 'burundi',
45
+ 'cambodia',
46
+ 'cameroon',
47
+ 'canada',
48
+ 'cape verde',
49
+ 'central african republic',
50
+ 'chad',
51
+ 'chile',
52
+ 'china',
53
+ 'colombia',
54
+ 'comoros',
55
+ 'congo',
56
+ 'costa rica',
57
+ 'croatia',
58
+ 'cuba',
59
+ 'cyprus',
60
+ 'czech republic',
61
+ 'denmark',
62
+ 'djibouti',
63
+ 'dominican republic',
64
+ 'ecuador',
65
+ 'egypt',
66
+ 'el salvador',
67
+ 'equatorial guinea',
68
+ 'eritrea',
69
+ 'estonia',
70
+ 'ethiopia',
71
+ 'fiji',
72
+ 'finland',
73
+ 'france',
74
+ 'gabon',
75
+ 'gambia',
76
+ 'georgia',
77
+ 'germany',
78
+ 'ghana',
79
+ 'greece',
80
+ 'guatemala',
81
+ 'guinea',
82
+ 'haiti',
83
+ 'honduras',
84
+ 'hungary',
85
+ 'iceland',
86
+ 'india',
87
+ 'indonesia',
88
+ 'iran',
89
+ 'iraq',
90
+ 'ireland',
91
+ 'israel',
92
+ 'italy',
93
+ 'jamaica',
94
+ 'japan',
95
+ 'jordan',
96
+ 'kazakhstan',
97
+ 'kenya',
98
+ 'kuwait',
99
+ 'kyrgyzstan',
100
+ 'latvia',
101
+ 'lebanon',
102
+ 'lesotho',
103
+ 'liberia',
104
+ 'libya',
105
+ 'liechtenstein',
106
+ 'lithuania',
107
+ 'luxembourg',
108
+ 'madagascar',
109
+ 'malawi',
110
+ 'malaysia',
111
+ 'maldives',
112
+ 'mali',
113
+ 'malta',
114
+ 'mauritania',
115
+ 'mauritius',
116
+ 'mexico',
117
+ 'moldova',
118
+ 'monaco',
119
+ 'mongolia',
120
+ 'montenegro',
121
+ 'morocco',
122
+ 'mozambique',
123
+ 'myanmar',
124
+ 'namibia',
125
+ 'nepal',
126
+ 'netherlands',
127
+ 'new zealand',
128
+ 'nicaragua',
129
+ 'niger',
130
+ 'nigeria',
131
+ 'north korea',
132
+ 'north macedonia',
133
+ 'norway',
134
+ 'oman',
135
+ 'pakistan',
136
+ 'panama',
137
+ 'papua new guinea',
138
+ 'paraguay',
139
+ 'peru',
140
+ 'philippines',
141
+ 'poland',
142
+ 'portugal',
143
+ 'qatar',
144
+ 'romania',
145
+ 'russia',
146
+ 'rwanda',
147
+ 'saudi arabia',
148
+ 'senegal',
149
+ 'serbia',
150
+ 'singapore',
151
+ 'slovakia',
152
+ 'slovenia',
153
+ 'somalia',
154
+ 'south africa',
155
+ 'south korea',
156
+ 'south sudan',
157
+ 'spain',
158
+ 'sri lanka',
159
+ 'sudan',
160
+ 'sweden',
161
+ 'switzerland',
162
+ 'syria',
163
+ 'taiwan',
164
+ 'tajikistan',
165
+ 'tanzania',
166
+ 'thailand',
167
+ 'togo',
168
+ 'trinidad and tobago',
169
+ 'tunisia',
170
+ 'turkey',
171
+ 'turkmenistan',
172
+ 'uganda',
173
+ 'ukraine',
174
+ 'united arab emirates',
175
+ 'united kingdom',
176
+ 'united states',
177
+ 'uruguay',
178
+ 'uzbekistan',
179
+ 'venezuela',
180
+ 'vietnam',
181
+ 'yemen',
182
+ 'zambia',
183
+ 'zimbabwe',
184
+ ]);
185
+
186
+ const TAVILY_REGION_NAMES = new Intl.DisplayNames(['en'], {
187
+ type: 'region',
188
+ });
189
+
190
+ const normalizeTavilyCountryName = (country: string): string =>
191
+ country
192
+ .toLowerCase()
193
+ .replace(/\s*\([^)]*\)/g, '')
194
+ .replace(/\s*&\s*/g, ' and ')
195
+ .normalize('NFD')
196
+ .replace(/\p{Diacritic}/gu, '');
197
+
198
+ const normalizeTavilyCountry = (country?: string): string | undefined => {
199
+ const normalizedCountry = country?.trim().toLowerCase();
200
+ if (normalizedCountry == null || normalizedCountry === '') {
201
+ return undefined;
202
+ }
203
+
204
+ const countryAlias = TAVILY_COUNTRY_ALIASES[normalizedCountry];
205
+ if (countryAlias != null) {
206
+ return TAVILY_SUPPORTED_COUNTRIES.has(countryAlias)
207
+ ? countryAlias
208
+ : undefined;
209
+ }
210
+
211
+ if (/^[a-z]{2}$/.test(normalizedCountry)) {
212
+ const regionName = TAVILY_REGION_NAMES.of(normalizedCountry.toUpperCase());
213
+ if (regionName == null) {
214
+ return undefined;
215
+ }
216
+ const countryName = normalizeTavilyCountryName(regionName);
217
+ return TAVILY_SUPPORTED_COUNTRIES.has(countryName)
218
+ ? countryName
219
+ : undefined;
220
+ }
221
+
222
+ const countryName = normalizeTavilyCountryName(normalizedCountry);
223
+ return TAVILY_SUPPORTED_COUNTRIES.has(countryName) ? countryName : undefined;
224
+ };
225
+
226
+ const normalizeTavilyTimeRange = (
227
+ timeRange?: t.TavilyTimeRangeInput
228
+ ): t.TavilyTimeRange | undefined => {
229
+ switch (timeRange) {
230
+ case 'h':
231
+ case 'd':
232
+ return 'day';
233
+ case 'w':
234
+ return 'week';
235
+ case 'm':
236
+ return 'month';
237
+ case 'y':
238
+ return 'year';
239
+ case 'day':
240
+ case 'week':
241
+ case 'month':
242
+ case 'year':
243
+ return timeRange;
244
+ default:
245
+ return undefined;
246
+ }
247
+ };
248
+
249
+ const getHostname = (link: string): string => {
250
+ try {
251
+ return new URL(link).hostname;
252
+ } catch {
253
+ return link;
254
+ }
255
+ };
256
+
257
+ export const createTavilyAPI = (
258
+ apiKey?: string,
259
+ apiUrl?: string,
260
+ options?: t.TavilySearchOptions
261
+ ): {
262
+ getSources: (params: t.GetSourcesParams) => Promise<t.SearchResult>;
263
+ } => {
264
+ const config = {
265
+ apiKey: apiKey ?? process.env.TAVILY_API_KEY,
266
+ apiUrl:
267
+ apiUrl ??
268
+ process.env.TAVILY_SEARCH_URL ??
269
+ 'https://api.tavily.com/search',
270
+ timeout: options?.timeout ?? DEFAULT_TAVILY_TIMEOUT,
271
+ };
272
+
273
+ if (config.apiKey == null || config.apiKey === '') {
274
+ throw new Error('TAVILY_API_KEY is required for Tavily API');
275
+ }
276
+
277
+ const getSources = async ({
278
+ query,
279
+ date,
280
+ country,
281
+ numResults = 8,
282
+ type,
283
+ news,
284
+ }: t.GetSourcesParams): Promise<t.SearchResult> => {
285
+ if (!query.trim()) {
286
+ return { success: false, error: 'Query cannot be empty' };
287
+ }
288
+
289
+ try {
290
+ const timeRange =
291
+ normalizeTavilyTimeRange(options?.timeRange) ??
292
+ (date != null ? (normalizeTavilyTimeRange(date) ?? 'day') : undefined);
293
+ const topic =
294
+ news === true || type === 'news'
295
+ ? 'news'
296
+ : (options?.topic ?? 'general');
297
+ const maxResults = options?.maxResults ?? numResults;
298
+ const searchDepth = options?.searchDepth ?? 'basic';
299
+
300
+ const payload: t.TavilySearchPayload = {
301
+ query,
302
+ search_depth: searchDepth,
303
+ topic,
304
+ max_results: Math.min(Math.max(1, maxResults), 20),
305
+ };
306
+
307
+ if (
308
+ options?.safeSearch != null &&
309
+ searchDepth !== 'fast' &&
310
+ searchDepth !== 'ultra-fast'
311
+ ) {
312
+ payload.safe_search = options.safeSearch;
313
+ }
314
+ if (timeRange != null) {
315
+ payload.time_range = timeRange;
316
+ }
317
+ const tavilyCountry =
318
+ topic === 'general' ? normalizeTavilyCountry(country) : undefined;
319
+ if (tavilyCountry != null) {
320
+ payload.country = tavilyCountry;
321
+ }
322
+ if (type === 'images' || options?.includeImages) {
323
+ payload.include_images = true;
324
+ }
325
+ if (options?.includeAnswer != null) {
326
+ payload.include_answer = options.includeAnswer;
327
+ }
328
+ if (options?.includeRawContent != null) {
329
+ payload.include_raw_content = options.includeRawContent;
330
+ }
331
+ if (
332
+ options?.includeDomains != null &&
333
+ options.includeDomains.length > 0
334
+ ) {
335
+ payload.include_domains = options.includeDomains;
336
+ }
337
+ if (
338
+ options?.excludeDomains != null &&
339
+ options.excludeDomains.length > 0
340
+ ) {
341
+ payload.exclude_domains = options.excludeDomains;
342
+ }
343
+ if (options?.includeImageDescriptions != null) {
344
+ payload.include_image_descriptions = options.includeImageDescriptions;
345
+ }
346
+ if (options?.includeFavicon != null) {
347
+ payload.include_favicon = options.includeFavicon;
348
+ }
349
+ if (options?.chunksPerSource != null && searchDepth === 'advanced') {
350
+ payload.chunks_per_source = options.chunksPerSource;
351
+ }
352
+
353
+ const response = await axios.post<t.TavilySearchResponse>(
354
+ config.apiUrl,
355
+ payload,
356
+ {
357
+ headers: {
358
+ Authorization: `Bearer ${config.apiKey}`,
359
+ 'Content-Type': 'application/json',
360
+ },
361
+ timeout: config.timeout,
362
+ }
363
+ );
364
+
365
+ const data = response.data;
366
+
367
+ const organicResults: t.OrganicResult[] = (data.results ?? []).map(
368
+ (result: t.TavilySearchResult) => ({
369
+ title: result.title ?? '',
370
+ link: result.url ?? '',
371
+ snippet: result.content ?? '',
372
+ date: result.published_date,
373
+ })
374
+ );
375
+
376
+ const imageResults: t.ImageResult[] = Array.isArray(data.images)
377
+ ? data.images.slice(0, 6).reduce<t.ImageResult[]>((acc, image) => {
378
+ const imageUrl = typeof image === 'string' ? image : image.url;
379
+ if (imageUrl == null || imageUrl === '') {
380
+ return acc;
381
+ }
382
+ acc.push({
383
+ imageUrl,
384
+ title: typeof image === 'string' ? undefined : image.description,
385
+ position: acc.length + 1,
386
+ });
387
+ return acc;
388
+ }, [])
389
+ : [];
390
+
391
+ const newsResults: t.NewsResult[] =
392
+ topic === 'news'
393
+ ? organicResults.map((r) => ({
394
+ title: r.title,
395
+ link: r.link,
396
+ snippet: r.snippet,
397
+ date: r.date,
398
+ source: getHostname(r.link),
399
+ }))
400
+ : [];
401
+
402
+ const results: t.SearchResultData = {
403
+ organic: organicResults,
404
+ images: imageResults,
405
+ topStories: [],
406
+ videos: [],
407
+ news: newsResults,
408
+ answerBox: data.answer != null ? { snippet: data.answer } : undefined,
409
+ relatedSearches: [],
410
+ };
411
+
412
+ return { success: true, data: results };
413
+ } catch (error) {
414
+ const errorMessage =
415
+ error instanceof Error ? error.message : String(error);
416
+ return {
417
+ success: false,
418
+ error: `Tavily API request failed: ${errorMessage}`,
419
+ };
420
+ }
421
+ };
422
+
423
+ return { getSources };
424
+ };