@librechat/agents 3.0.0-rc1 → 3.0.0-rc11

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 (187) hide show
  1. package/dist/cjs/common/enum.cjs +1 -0
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +7 -2
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/graphs/MultiAgentGraph.cjs +229 -44
  6. package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/index.cjs +21 -2
  8. package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
  9. package/dist/cjs/llm/google/index.cjs +3 -0
  10. package/dist/cjs/llm/google/index.cjs.map +1 -1
  11. package/dist/cjs/llm/google/utils/common.cjs +13 -0
  12. package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
  13. package/dist/cjs/llm/ollama/index.cjs +3 -0
  14. package/dist/cjs/llm/ollama/index.cjs.map +1 -1
  15. package/dist/cjs/llm/openai/index.cjs +53 -1
  16. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openai/utils/index.cjs +6 -1
  18. package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
  19. package/dist/cjs/llm/openrouter/index.cjs +5 -1
  20. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  21. package/dist/cjs/llm/vertexai/index.cjs +1 -1
  22. package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
  23. package/dist/cjs/main.cjs +3 -1
  24. package/dist/cjs/main.cjs.map +1 -1
  25. package/dist/cjs/messages/core.cjs +5 -1
  26. package/dist/cjs/messages/core.cjs.map +1 -1
  27. package/dist/cjs/messages/format.cjs +52 -34
  28. package/dist/cjs/messages/format.cjs.map +1 -1
  29. package/dist/cjs/messages/prune.cjs +28 -0
  30. package/dist/cjs/messages/prune.cjs.map +1 -1
  31. package/dist/cjs/run.cjs +28 -15
  32. package/dist/cjs/run.cjs.map +1 -1
  33. package/dist/cjs/stream.cjs +1 -1
  34. package/dist/cjs/stream.cjs.map +1 -1
  35. package/dist/cjs/tools/ToolNode.cjs +2 -0
  36. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  37. package/dist/cjs/tools/search/firecrawl.cjs +3 -1
  38. package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
  39. package/dist/cjs/tools/search/rerankers.cjs +8 -6
  40. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  41. package/dist/cjs/tools/search/search.cjs +5 -5
  42. package/dist/cjs/tools/search/search.cjs.map +1 -1
  43. package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
  44. package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
  45. package/dist/cjs/tools/search/tool.cjs +46 -9
  46. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  47. package/dist/cjs/utils/handlers.cjs +70 -0
  48. package/dist/cjs/utils/handlers.cjs.map +1 -0
  49. package/dist/esm/common/enum.mjs +1 -0
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +7 -2
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/graphs/MultiAgentGraph.mjs +230 -45
  54. package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
  55. package/dist/esm/llm/anthropic/index.mjs +21 -2
  56. package/dist/esm/llm/anthropic/index.mjs.map +1 -1
  57. package/dist/esm/llm/google/index.mjs +3 -0
  58. package/dist/esm/llm/google/index.mjs.map +1 -1
  59. package/dist/esm/llm/google/utils/common.mjs +13 -0
  60. package/dist/esm/llm/google/utils/common.mjs.map +1 -1
  61. package/dist/esm/llm/ollama/index.mjs +3 -0
  62. package/dist/esm/llm/ollama/index.mjs.map +1 -1
  63. package/dist/esm/llm/openai/index.mjs +53 -1
  64. package/dist/esm/llm/openai/index.mjs.map +1 -1
  65. package/dist/esm/llm/openai/utils/index.mjs +6 -1
  66. package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
  67. package/dist/esm/llm/openrouter/index.mjs +5 -1
  68. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  69. package/dist/esm/llm/vertexai/index.mjs +1 -1
  70. package/dist/esm/llm/vertexai/index.mjs.map +1 -1
  71. package/dist/esm/main.mjs +2 -1
  72. package/dist/esm/main.mjs.map +1 -1
  73. package/dist/esm/messages/core.mjs +5 -1
  74. package/dist/esm/messages/core.mjs.map +1 -1
  75. package/dist/esm/messages/format.mjs +52 -34
  76. package/dist/esm/messages/format.mjs.map +1 -1
  77. package/dist/esm/messages/prune.mjs +28 -0
  78. package/dist/esm/messages/prune.mjs.map +1 -1
  79. package/dist/esm/run.mjs +28 -15
  80. package/dist/esm/run.mjs.map +1 -1
  81. package/dist/esm/stream.mjs +1 -1
  82. package/dist/esm/stream.mjs.map +1 -1
  83. package/dist/esm/tools/ToolNode.mjs +2 -0
  84. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  85. package/dist/esm/tools/search/firecrawl.mjs +3 -1
  86. package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
  87. package/dist/esm/tools/search/rerankers.mjs +8 -6
  88. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  89. package/dist/esm/tools/search/search.mjs +5 -5
  90. package/dist/esm/tools/search/search.mjs.map +1 -1
  91. package/dist/esm/tools/search/serper-scraper.mjs +129 -0
  92. package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
  93. package/dist/esm/tools/search/tool.mjs +46 -9
  94. package/dist/esm/tools/search/tool.mjs.map +1 -1
  95. package/dist/esm/utils/handlers.mjs +68 -0
  96. package/dist/esm/utils/handlers.mjs.map +1 -0
  97. package/dist/types/common/enum.d.ts +2 -1
  98. package/dist/types/graphs/MultiAgentGraph.d.ts +12 -2
  99. package/dist/types/llm/anthropic/index.d.ts +3 -0
  100. package/dist/types/llm/google/index.d.ts +1 -0
  101. package/dist/types/llm/ollama/index.d.ts +1 -0
  102. package/dist/types/llm/openai/index.d.ts +14 -0
  103. package/dist/types/llm/openrouter/index.d.ts +4 -2
  104. package/dist/types/llm/vertexai/index.d.ts +1 -1
  105. package/dist/types/messages/format.d.ts +23 -20
  106. package/dist/types/run.d.ts +1 -1
  107. package/dist/types/tools/search/firecrawl.d.ts +2 -1
  108. package/dist/types/tools/search/rerankers.d.ts +4 -1
  109. package/dist/types/tools/search/search.d.ts +1 -2
  110. package/dist/types/tools/search/serper-scraper.d.ts +59 -0
  111. package/dist/types/tools/search/tool.d.ts +25 -4
  112. package/dist/types/tools/search/types.d.ts +31 -1
  113. package/dist/types/types/graph.d.ts +38 -4
  114. package/dist/types/types/llm.d.ts +1 -0
  115. package/dist/types/types/run.d.ts +5 -1
  116. package/dist/types/utils/handlers.d.ts +34 -0
  117. package/dist/types/utils/index.d.ts +1 -0
  118. package/package.json +11 -3
  119. package/src/common/enum.ts +1 -0
  120. package/src/graphs/Graph.ts +8 -2
  121. package/src/graphs/MultiAgentGraph.ts +267 -50
  122. package/src/llm/anthropic/index.ts +23 -2
  123. package/src/llm/google/index.ts +4 -0
  124. package/src/llm/google/utils/common.ts +14 -0
  125. package/src/llm/ollama/index.ts +3 -0
  126. package/src/llm/openai/index.ts +60 -1
  127. package/src/llm/openai/utils/index.ts +7 -1
  128. package/src/llm/openrouter/index.ts +15 -6
  129. package/src/llm/vertexai/index.ts +2 -2
  130. package/src/messages/core.ts +5 -2
  131. package/src/messages/format.ts +67 -39
  132. package/src/messages/formatMessage.test.ts +418 -2
  133. package/src/messages/prune.ts +51 -0
  134. package/src/run.ts +38 -27
  135. package/src/scripts/multi-agent-chain.ts +278 -0
  136. package/src/scripts/multi-agent-document-review-chain.ts +197 -0
  137. package/src/scripts/multi-agent-hybrid-flow.ts +310 -0
  138. package/src/scripts/multi-agent-parallel.ts +27 -23
  139. package/src/scripts/multi-agent-supervisor.ts +362 -0
  140. package/src/scripts/search.ts +5 -1
  141. package/src/scripts/test-custom-prompt-key.ts +145 -0
  142. package/src/scripts/test-handoff-input.ts +170 -0
  143. package/src/scripts/test-multi-agent-list-handoff.ts +261 -0
  144. package/src/scripts/test-tools-before-handoff.ts +233 -0
  145. package/src/scripts/tools.ts +4 -1
  146. package/src/stream.ts +4 -1
  147. package/src/tools/search/firecrawl.ts +5 -2
  148. package/src/tools/search/jina-reranker.test.ts +126 -0
  149. package/src/tools/search/rerankers.ts +11 -5
  150. package/src/tools/search/search.ts +6 -8
  151. package/src/tools/search/serper-scraper.ts +155 -0
  152. package/src/tools/search/tool.ts +49 -8
  153. package/src/tools/search/types.ts +46 -0
  154. package/src/types/graph.ts +51 -5
  155. package/src/types/llm.ts +1 -0
  156. package/src/types/run.ts +6 -1
  157. package/src/utils/handlers.ts +107 -0
  158. package/src/utils/index.ts +2 -1
  159. package/src/utils/llmConfig.ts +35 -1
  160. package/dist/types/scripts/abort.d.ts +0 -1
  161. package/dist/types/scripts/ant_web_search.d.ts +0 -1
  162. package/dist/types/scripts/args.d.ts +0 -7
  163. package/dist/types/scripts/caching.d.ts +0 -1
  164. package/dist/types/scripts/cli.d.ts +0 -1
  165. package/dist/types/scripts/cli2.d.ts +0 -1
  166. package/dist/types/scripts/cli3.d.ts +0 -1
  167. package/dist/types/scripts/cli4.d.ts +0 -1
  168. package/dist/types/scripts/cli5.d.ts +0 -1
  169. package/dist/types/scripts/code_exec.d.ts +0 -1
  170. package/dist/types/scripts/code_exec_files.d.ts +0 -1
  171. package/dist/types/scripts/code_exec_simple.d.ts +0 -1
  172. package/dist/types/scripts/content.d.ts +0 -1
  173. package/dist/types/scripts/empty_input.d.ts +0 -1
  174. package/dist/types/scripts/handoff-test.d.ts +0 -1
  175. package/dist/types/scripts/image.d.ts +0 -1
  176. package/dist/types/scripts/memory.d.ts +0 -1
  177. package/dist/types/scripts/multi-agent-conditional.d.ts +0 -1
  178. package/dist/types/scripts/multi-agent-parallel.d.ts +0 -1
  179. package/dist/types/scripts/multi-agent-sequence.d.ts +0 -1
  180. package/dist/types/scripts/multi-agent-test.d.ts +0 -1
  181. package/dist/types/scripts/search.d.ts +0 -1
  182. package/dist/types/scripts/simple.d.ts +0 -1
  183. package/dist/types/scripts/stream.d.ts +0 -1
  184. package/dist/types/scripts/thinking.d.ts +0 -1
  185. package/dist/types/scripts/tools.d.ts +0 -1
  186. package/dist/types/specs/spec.utils.d.ts +0 -1
  187. package/src/scripts/multi-agent-example-output.md +0 -110
@@ -1 +1 @@
1
- {"version":3,"file":"tool.mjs","sources":["../../../../src/tools/search/tool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from './types';\nimport {\n DATE_RANGE,\n querySchema,\n dateSchema,\n countrySchema,\n imagesSchema,\n videosSchema,\n newsSchema,\n} from './schema';\nimport { createSearchAPI, createSourceProcessor } from './search';\nimport { createFirecrawlScraper } from './firecrawl';\nimport { expandHighlights } from './highlights';\nimport { formatResultsForLLM } from './format';\nimport { createDefaultLogger } from './utils';\nimport { createReranker } from './rerankers';\nimport { Constants } from '@/common';\n\n/**\n * Executes parallel searches and merges the results\n */\nasync function executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n}: {\n searchAPI: ReturnType<typeof createSearchAPI>;\n query: string;\n date?: DATE_RANGE;\n country?: string;\n safeSearch: t.SearchToolConfig['safeSearch'];\n images: boolean;\n videos: boolean;\n news: boolean;\n logger: t.Logger;\n}): Promise<t.SearchResult> {\n // Prepare all search tasks to run in parallel\n const searchTasks: Promise<t.SearchResult>[] = [\n // Main search\n searchAPI.getSources({\n query,\n date,\n country,\n safeSearch,\n }),\n ];\n\n if (images) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'images',\n })\n .catch((error) => {\n logger.error('Error fetching images:', error);\n return {\n success: false,\n error: `Images search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (videos) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'videos',\n })\n .catch((error) => {\n logger.error('Error fetching videos:', error);\n return {\n success: false,\n error: `Videos search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (news) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'news',\n })\n .catch((error) => {\n logger.error('Error fetching news:', error);\n return {\n success: false,\n error: `News search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n\n // Run all searches in parallel\n const results = await Promise.all(searchTasks);\n\n // Get the main search result (first result)\n const mainResult = results[0];\n if (!mainResult.success) {\n throw new Error(mainResult.error ?? 'Search failed');\n }\n\n // Merge additional results with the main results\n const mergedResults = { ...mainResult.data };\n\n // Convert existing news to topStories if present\n if (mergedResults.news !== undefined && mergedResults.news.length > 0) {\n const existingNewsAsTopStories = mergedResults.news\n .filter((newsItem) => newsItem.link !== undefined && newsItem.link !== '')\n .map((newsItem) => ({\n title: newsItem.title ?? '',\n link: newsItem.link ?? '',\n source: newsItem.source ?? '',\n date: newsItem.date ?? '',\n imageUrl: newsItem.imageUrl ?? '',\n processed: false,\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...existingNewsAsTopStories,\n ];\n delete mergedResults.news;\n }\n\n results.slice(1).forEach((result) => {\n if (result.success && result.data !== undefined) {\n if (result.data.images !== undefined && result.data.images.length > 0) {\n mergedResults.images = [\n ...(mergedResults.images ?? []),\n ...result.data.images,\n ];\n }\n if (result.data.videos !== undefined && result.data.videos.length > 0) {\n mergedResults.videos = [\n ...(mergedResults.videos ?? []),\n ...result.data.videos,\n ];\n }\n if (result.data.news !== undefined && result.data.news.length > 0) {\n const newsAsTopStories = result.data.news.map((newsItem) => ({\n ...newsItem,\n link: newsItem.link ?? '',\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...newsAsTopStories,\n ];\n }\n }\n });\n\n return { success: true, data: mergedResults };\n}\n\nfunction createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n}: {\n safeSearch: t.SearchToolConfig['safeSearch'];\n searchAPI: ReturnType<typeof createSearchAPI>;\n sourceProcessor: ReturnType<typeof createSourceProcessor>;\n onGetHighlights: t.SearchToolConfig['onGetHighlights'];\n logger: t.Logger;\n}) {\n return async function ({\n query,\n date,\n country,\n proMode = true,\n maxSources = 5,\n onSearchResults,\n images = false,\n videos = false,\n news = false,\n }: {\n query: string;\n country?: string;\n date?: DATE_RANGE;\n proMode?: boolean;\n maxSources?: number;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n }): Promise<t.SearchResultData> {\n try {\n // Execute parallel searches and merge results\n const searchResult = await executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n });\n\n onSearchResults?.(searchResult);\n\n const processedSources = await sourceProcessor.processSources({\n query,\n news,\n result: searchResult,\n proMode,\n onGetHighlights,\n numElements: maxSources,\n });\n\n return expandHighlights(processedSources);\n } catch (error) {\n logger.error('Error in search:', error);\n return {\n organic: [],\n topStories: [],\n images: [],\n videos: [],\n news: [],\n relatedSearches: [],\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n}\n\nfunction createOnSearchResults({\n runnableConfig,\n onSearchResults,\n}: {\n runnableConfig: RunnableConfig;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}) {\n return function (results: t.SearchResult): void {\n if (!onSearchResults) {\n return;\n }\n onSearchResults(results, runnableConfig);\n };\n}\n\nfunction createTool({\n schema,\n search,\n onSearchResults: _onSearchResults,\n}: {\n schema: t.SearchToolSchema;\n search: ReturnType<typeof createSearchProcessor>;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}): DynamicStructuredTool<typeof schema> {\n return tool<typeof schema>(\n async (params, runnableConfig) => {\n const { query, date, country: _c, images, videos, news } = params;\n const country = typeof _c === 'string' && _c ? _c : undefined;\n const searchResult = await search({\n query,\n date,\n country,\n images,\n videos,\n news,\n onSearchResults: createOnSearchResults({\n runnableConfig,\n onSearchResults: _onSearchResults,\n }),\n });\n const turn = runnableConfig.toolCall?.turn ?? 0;\n const { output, references } = formatResultsForLLM(turn, searchResult);\n const data: t.SearchResultData = { turn, ...searchResult, references };\n return [output, { [Constants.WEB_SEARCH]: data }];\n },\n {\n name: Constants.WEB_SEARCH,\n description: `Real-time search. Results have required citation anchors.\n\nNote: Use ONCE per reply unless instructed otherwise.\n\nAnchors:\n- \\\\ue202turnXtypeY\n- X = turn idx, type = 'search' | 'news' | 'image' | 'ref', Y = item idx\n\nSpecial Markers:\n- \\\\ue203...\\\\ue204 — highlight start/end of cited text (for Standalone or Group citations)\n- \\\\ue200...\\\\ue201 — group block (e.g. \\\\ue200\\\\ue202turn0search1\\\\ue202turn0news2\\\\ue201)\n\n**CITE EVERY NON-OBVIOUS FACT/QUOTE:**\nUse anchor marker(s) immediately after the statement:\n- Standalone: \"Pure functions produce same output. \\\\ue202turn0search0\"\n- Standalone (multiple): \"Today's News \\\\ue202turn0search0\\\\ue202turn0news0\"\n- Highlight: \"\\\\ue203Highlight text.\\\\ue204\\\\ue202turn0news1\"\n- Group: \"Sources. \\\\ue200\\\\ue202turn0search0\\\\ue202turn0news1\\\\ue201\"\n- Group Highlight: \"\\\\ue203Highlight for group.\\\\ue204 \\\\ue200\\\\ue202turn0search0\\\\ue202turn0news1\\\\ue201\"\n- Image: \"See photo \\\\ue202turn0image0.\"\n\n**NEVER use markdown links, [1], or footnotes. CITE ONLY with anchors provided.**\n`.trim(),\n schema: schema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\n/**\n * Creates a search tool with a schema that dynamically includes the country field\n * only when the searchProvider is 'serper'.\n *\n * @param config - The search tool configuration\n * @returns A DynamicStructuredTool with a schema that depends on the searchProvider\n */\nexport const createSearchTool = (\n config: t.SearchToolConfig = {}\n): DynamicStructuredTool<typeof toolSchema> => {\n const {\n searchProvider = 'serper',\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n rerankerType = 'cohere',\n topResults = 5,\n strategies = ['no_extraction'],\n filterContent = true,\n safeSearch = 1,\n firecrawlApiKey,\n firecrawlApiUrl,\n firecrawlOptions,\n scraperTimeout,\n jinaApiKey,\n cohereApiKey,\n onSearchResults: _onSearchResults,\n onGetHighlights,\n } = config;\n\n const logger = config.logger || createDefaultLogger();\n\n const schemaObject: {\n query: z.ZodString;\n date: z.ZodOptional<z.ZodNativeEnum<typeof DATE_RANGE>>;\n country?: z.ZodOptional<z.ZodString>;\n images: z.ZodOptional<z.ZodBoolean>;\n videos: z.ZodOptional<z.ZodBoolean>;\n news: z.ZodOptional<z.ZodBoolean>;\n } = {\n query: querySchema,\n date: dateSchema,\n images: imagesSchema,\n videos: videosSchema,\n news: newsSchema,\n };\n\n if (searchProvider === 'serper') {\n schemaObject.country = countrySchema;\n }\n\n const toolSchema = z.object(schemaObject);\n\n const searchAPI = createSearchAPI({\n searchProvider,\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n });\n\n const firecrawlScraper = createFirecrawlScraper({\n ...firecrawlOptions,\n apiKey: firecrawlApiKey ?? process.env.FIRECRAWL_API_KEY,\n apiUrl: firecrawlApiUrl,\n timeout: scraperTimeout ?? firecrawlOptions?.timeout,\n formats: firecrawlOptions?.formats ?? ['markdown', 'rawHtml'],\n });\n\n const selectedReranker = createReranker({\n rerankerType,\n jinaApiKey,\n cohereApiKey,\n logger,\n });\n\n if (!selectedReranker) {\n logger.warn('No reranker selected. Using default ranking.');\n }\n\n const sourceProcessor = createSourceProcessor(\n {\n reranker: selectedReranker,\n topResults,\n strategies,\n filterContent,\n logger,\n },\n firecrawlScraper\n );\n\n const search = createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n });\n\n return createTool({\n search,\n schema: toolSchema,\n onSearchResults: _onSearchResults,\n });\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool.mjs","sources":["../../../../src/tools/search/tool.ts"],"sourcesContent":["import { z } from 'zod';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from './types';\nimport {\n DATE_RANGE,\n querySchema,\n dateSchema,\n countrySchema,\n imagesSchema,\n videosSchema,\n newsSchema,\n} from './schema';\nimport { createSearchAPI, createSourceProcessor } from './search';\nimport { createSerperScraper } from './serper-scraper';\nimport { createFirecrawlScraper } from './firecrawl';\nimport { expandHighlights } from './highlights';\nimport { formatResultsForLLM } from './format';\nimport { createDefaultLogger } from './utils';\nimport { createReranker } from './rerankers';\nimport { Constants } from '@/common';\n\n/**\n * Executes parallel searches and merges the results\n */\nasync function executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n}: {\n searchAPI: ReturnType<typeof createSearchAPI>;\n query: string;\n date?: DATE_RANGE;\n country?: string;\n safeSearch: t.SearchToolConfig['safeSearch'];\n images: boolean;\n videos: boolean;\n news: boolean;\n logger: t.Logger;\n}): Promise<t.SearchResult> {\n // Prepare all search tasks to run in parallel\n const searchTasks: Promise<t.SearchResult>[] = [\n // Main search\n searchAPI.getSources({\n query,\n date,\n country,\n safeSearch,\n }),\n ];\n\n if (images) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'images',\n })\n .catch((error) => {\n logger.error('Error fetching images:', error);\n return {\n success: false,\n error: `Images search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (videos) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'videos',\n })\n .catch((error) => {\n logger.error('Error fetching videos:', error);\n return {\n success: false,\n error: `Videos search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n if (news) {\n searchTasks.push(\n searchAPI\n .getSources({\n query,\n date,\n country,\n safeSearch,\n type: 'news',\n })\n .catch((error) => {\n logger.error('Error fetching news:', error);\n return {\n success: false,\n error: `News search failed: ${error instanceof Error ? error.message : String(error)}`,\n };\n })\n );\n }\n\n // Run all searches in parallel\n const results = await Promise.all(searchTasks);\n\n // Get the main search result (first result)\n const mainResult = results[0];\n if (!mainResult.success) {\n throw new Error(mainResult.error ?? 'Search failed');\n }\n\n // Merge additional results with the main results\n const mergedResults = { ...mainResult.data };\n\n // Convert existing news to topStories if present\n if (mergedResults.news !== undefined && mergedResults.news.length > 0) {\n const existingNewsAsTopStories = mergedResults.news\n .filter((newsItem) => newsItem.link !== undefined && newsItem.link !== '')\n .map((newsItem) => ({\n title: newsItem.title ?? '',\n link: newsItem.link ?? '',\n source: newsItem.source ?? '',\n date: newsItem.date ?? '',\n imageUrl: newsItem.imageUrl ?? '',\n processed: false,\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...existingNewsAsTopStories,\n ];\n delete mergedResults.news;\n }\n\n results.slice(1).forEach((result) => {\n if (result.success && result.data !== undefined) {\n if (result.data.images !== undefined && result.data.images.length > 0) {\n mergedResults.images = [\n ...(mergedResults.images ?? []),\n ...result.data.images,\n ];\n }\n if (result.data.videos !== undefined && result.data.videos.length > 0) {\n mergedResults.videos = [\n ...(mergedResults.videos ?? []),\n ...result.data.videos,\n ];\n }\n if (result.data.news !== undefined && result.data.news.length > 0) {\n const newsAsTopStories = result.data.news.map((newsItem) => ({\n ...newsItem,\n link: newsItem.link ?? '',\n }));\n mergedResults.topStories = [\n ...(mergedResults.topStories ?? []),\n ...newsAsTopStories,\n ];\n }\n }\n });\n\n return { success: true, data: mergedResults };\n}\n\nfunction createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n}: {\n safeSearch: t.SearchToolConfig['safeSearch'];\n searchAPI: ReturnType<typeof createSearchAPI>;\n sourceProcessor: ReturnType<typeof createSourceProcessor>;\n onGetHighlights: t.SearchToolConfig['onGetHighlights'];\n logger: t.Logger;\n}) {\n return async function ({\n query,\n date,\n country,\n proMode = true,\n maxSources = 5,\n onSearchResults,\n images = false,\n videos = false,\n news = false,\n }: {\n query: string;\n country?: string;\n date?: DATE_RANGE;\n proMode?: boolean;\n maxSources?: number;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n images?: boolean;\n videos?: boolean;\n news?: boolean;\n }): Promise<t.SearchResultData> {\n try {\n // Execute parallel searches and merge results\n const searchResult = await executeParallelSearches({\n searchAPI,\n query,\n date,\n country,\n safeSearch,\n images,\n videos,\n news,\n logger,\n });\n\n onSearchResults?.(searchResult);\n\n const processedSources = await sourceProcessor.processSources({\n query,\n news,\n result: searchResult,\n proMode,\n onGetHighlights,\n numElements: maxSources,\n });\n\n return expandHighlights(processedSources);\n } catch (error) {\n logger.error('Error in search:', error);\n return {\n organic: [],\n topStories: [],\n images: [],\n videos: [],\n news: [],\n relatedSearches: [],\n error: error instanceof Error ? error.message : String(error),\n };\n }\n };\n}\n\nfunction createOnSearchResults({\n runnableConfig,\n onSearchResults,\n}: {\n runnableConfig: RunnableConfig;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}) {\n return function (results: t.SearchResult): void {\n if (!onSearchResults) {\n return;\n }\n onSearchResults(results, runnableConfig);\n };\n}\n\nfunction createTool({\n schema,\n search,\n onSearchResults: _onSearchResults,\n}: {\n schema: t.SearchToolSchema;\n search: ReturnType<typeof createSearchProcessor>;\n onSearchResults: t.SearchToolConfig['onSearchResults'];\n}): DynamicStructuredTool<typeof schema> {\n return tool<typeof schema>(\n async (params, runnableConfig) => {\n const { query, date, country: _c, images, videos, news } = params;\n const country = typeof _c === 'string' && _c ? _c : undefined;\n const searchResult = await search({\n query,\n date,\n country,\n images,\n videos,\n news,\n onSearchResults: createOnSearchResults({\n runnableConfig,\n onSearchResults: _onSearchResults,\n }),\n });\n const turn = runnableConfig.toolCall?.turn ?? 0;\n const { output, references } = formatResultsForLLM(turn, searchResult);\n const data: t.SearchResultData = { turn, ...searchResult, references };\n return [output, { [Constants.WEB_SEARCH]: data }];\n },\n {\n name: Constants.WEB_SEARCH,\n description: `Real-time search. Results have required citation anchors.\n\nNote: Use ONCE per reply unless instructed otherwise.\n\nAnchors:\n- \\\\ue202turnXtypeY\n- X = turn idx, type = 'search' | 'news' | 'image' | 'ref', Y = item idx\n\nSpecial Markers:\n- \\\\ue203...\\\\ue204 — highlight start/end of cited text (for Standalone or Group citations)\n- \\\\ue200...\\\\ue201 — group block (e.g. \\\\ue200\\\\ue202turn0search1\\\\ue202turn0news2\\\\ue201)\n\n**CITE EVERY NON-OBVIOUS FACT/QUOTE:**\nUse anchor marker(s) immediately after the statement:\n- Standalone: \"Pure functions produce same output. \\\\ue202turn0search0\"\n- Standalone (multiple): \"Today's News \\\\ue202turn0search0\\\\ue202turn0news0\"\n- Highlight: \"\\\\ue203Highlight text.\\\\ue204\\\\ue202turn0news1\"\n- Group: \"Sources. \\\\ue200\\\\ue202turn0search0\\\\ue202turn0news1\\\\ue201\"\n- Group Highlight: \"\\\\ue203Highlight for group.\\\\ue204 \\\\ue200\\\\ue202turn0search0\\\\ue202turn0news1\\\\ue201\"\n- Image: \"See photo \\\\ue202turn0image0.\"\n\n**NEVER use markdown links, [1], or footnotes. CITE ONLY with anchors provided.**\n`.trim(),\n schema: schema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\n/**\n * Creates a search tool with a schema that dynamically includes the country field\n * only when the searchProvider is 'serper'.\n *\n * Supports multiple scraper providers:\n * - Firecrawl (default): Full-featured web scraping with multiple formats\n * - Serper: Lightweight scraping using Serper's scrape API\n *\n * @example\n * ```typescript\n * // Using Firecrawl scraper (default)\n * const searchTool = createSearchTool({\n * searchProvider: 'serper',\n * scraperProvider: 'firecrawl',\n * firecrawlApiKey: 'your-firecrawl-key'\n * });\n *\n * // Using Serper scraper\n * const searchTool = createSearchTool({\n * searchProvider: 'serper',\n * scraperProvider: 'serper',\n * serperApiKey: 'your-serper-key'\n * });\n * ```\n *\n * @param config - The search tool configuration\n * @returns A DynamicStructuredTool with a schema that depends on the searchProvider\n */\nexport const createSearchTool = (\n config: t.SearchToolConfig = {}\n): DynamicStructuredTool<typeof toolSchema> => {\n const {\n searchProvider = 'serper',\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n rerankerType = 'cohere',\n topResults = 5,\n strategies = ['no_extraction'],\n filterContent = true,\n safeSearch = 1,\n scraperProvider = 'firecrawl',\n firecrawlApiKey,\n firecrawlApiUrl,\n firecrawlVersion,\n firecrawlOptions,\n serperScraperOptions,\n scraperTimeout,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n onSearchResults: _onSearchResults,\n onGetHighlights,\n } = config;\n\n const logger = config.logger || createDefaultLogger();\n\n const schemaObject: {\n query: z.ZodString;\n date: z.ZodOptional<z.ZodNativeEnum<typeof DATE_RANGE>>;\n country?: z.ZodOptional<z.ZodString>;\n images: z.ZodOptional<z.ZodBoolean>;\n videos: z.ZodOptional<z.ZodBoolean>;\n news: z.ZodOptional<z.ZodBoolean>;\n } = {\n query: querySchema,\n date: dateSchema,\n images: imagesSchema,\n videos: videosSchema,\n news: newsSchema,\n };\n\n if (searchProvider === 'serper') {\n schemaObject.country = countrySchema;\n }\n\n const toolSchema = z.object(schemaObject);\n\n const searchAPI = createSearchAPI({\n searchProvider,\n serperApiKey,\n searxngInstanceUrl,\n searxngApiKey,\n });\n\n /** Create scraper based on scraperProvider */\n let scraperInstance: t.BaseScraper;\n\n if (scraperProvider === 'serper') {\n scraperInstance = createSerperScraper({\n ...serperScraperOptions,\n apiKey: serperApiKey,\n timeout: scraperTimeout ?? serperScraperOptions?.timeout,\n logger,\n });\n } else {\n scraperInstance = createFirecrawlScraper({\n ...firecrawlOptions,\n apiKey: firecrawlApiKey ?? process.env.FIRECRAWL_API_KEY,\n apiUrl: firecrawlApiUrl,\n version: firecrawlVersion,\n timeout: scraperTimeout ?? firecrawlOptions?.timeout,\n formats: firecrawlOptions?.formats ?? ['markdown', 'rawHtml'],\n logger,\n });\n }\n\n const selectedReranker = createReranker({\n rerankerType,\n jinaApiKey,\n jinaApiUrl,\n cohereApiKey,\n logger,\n });\n\n if (!selectedReranker) {\n logger.warn('No reranker selected. Using default ranking.');\n }\n\n const sourceProcessor = createSourceProcessor(\n {\n reranker: selectedReranker,\n topResults,\n strategies,\n filterContent,\n logger,\n },\n scraperInstance\n );\n\n const search = createSearchProcessor({\n searchAPI,\n safeSearch,\n sourceProcessor,\n onGetHighlights,\n logger,\n });\n\n return createTool({\n search,\n schema: toolSchema,\n onSearchResults: _onSearchResults,\n });\n};\n"],"names":[],"mappings":";;;;;;;;;;;;AAsBA;;AAEG;AACH,eAAe,uBAAuB,CAAC,EACrC,SAAS,EACT,KAAK,EACL,IAAI,EACJ,OAAO,EACP,UAAU,EACV,MAAM,EACN,MAAM,EACN,IAAI,EACJ,MAAM,GAWP,EAAA;;AAEC,IAAA,MAAM,WAAW,GAA8B;;QAE7C,SAAS,CAAC,UAAU,CAAC;YACnB,KAAK;YACL,IAAI;YACJ,OAAO;YACP,UAAU;SACX,CAAC;KACH;IAED,IAAI,MAAM,EAAE;QACV,WAAW,CAAC,IAAI,CACd;AACG,aAAA,UAAU,CAAC;YACV,KAAK;YACL,IAAI;YACJ,OAAO;YACP,UAAU;AACV,YAAA,IAAI,EAAE,QAAQ;SACf;AACA,aAAA,KAAK,CAAC,CAAC,KAAK,KAAI;AACf,YAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC;YAC7C,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,KAAK,EAAE,CAAyB,sBAAA,EAAA,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAE,CAAA;aACzF;SACF,CAAC,CACL;;IAEH,IAAI,MAAM,EAAE;QACV,WAAW,CAAC,IAAI,CACd;AACG,aAAA,UAAU,CAAC;YACV,KAAK;YACL,IAAI;YACJ,OAAO;YACP,UAAU;AACV,YAAA,IAAI,EAAE,QAAQ;SACf;AACA,aAAA,KAAK,CAAC,CAAC,KAAK,KAAI;AACf,YAAA,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,KAAK,CAAC;YAC7C,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,KAAK,EAAE,CAAyB,sBAAA,EAAA,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAE,CAAA;aACzF;SACF,CAAC,CACL;;IAEH,IAAI,IAAI,EAAE;QACR,WAAW,CAAC,IAAI,CACd;AACG,aAAA,UAAU,CAAC;YACV,KAAK;YACL,IAAI;YACJ,OAAO;YACP,UAAU;AACV,YAAA,IAAI,EAAE,MAAM;SACb;AACA,aAAA,KAAK,CAAC,CAAC,KAAK,KAAI;AACf,YAAA,MAAM,CAAC,KAAK,CAAC,sBAAsB,EAAE,KAAK,CAAC;YAC3C,OAAO;AACL,gBAAA,OAAO,EAAE,KAAK;AACd,gBAAA,KAAK,EAAE,CAAuB,oBAAA,EAAA,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAE,CAAA;aACvF;SACF,CAAC,CACL;;;IAIH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;;AAG9C,IAAA,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;AAC7B,IAAA,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE;QACvB,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,IAAI,eAAe,CAAC;;;IAItD,MAAM,aAAa,GAAG,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE;;AAG5C,IAAA,IAAI,aAAa,CAAC,IAAI,KAAK,SAAS,IAAI,aAAa,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACrE,QAAA,MAAM,wBAAwB,GAAG,aAAa,CAAC;AAC5C,aAAA,MAAM,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,IAAI,KAAK,EAAE;AACxE,aAAA,GAAG,CAAC,CAAC,QAAQ,MAAM;AAClB,YAAA,KAAK,EAAE,QAAQ,CAAC,KAAK,IAAI,EAAE;AAC3B,YAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;AACzB,YAAA,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE;AAC7B,YAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;AACzB,YAAA,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE;AACjC,YAAA,SAAS,EAAE,KAAK;AACjB,SAAA,CAAC,CAAC;QACL,aAAa,CAAC,UAAU,GAAG;AACzB,YAAA,IAAI,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC;AACnC,YAAA,GAAG,wBAAwB;SAC5B;QACD,OAAO,aAAa,CAAC,IAAI;;IAG3B,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;QAClC,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE;AAC/C,YAAA,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;gBACrE,aAAa,CAAC,MAAM,GAAG;AACrB,oBAAA,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC;AAC/B,oBAAA,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM;iBACtB;;AAEH,YAAA,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;gBACrE,aAAa,CAAC,MAAM,GAAG;AACrB,oBAAA,IAAI,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC;AAC/B,oBAAA,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM;iBACtB;;AAEH,YAAA,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;AACjE,gBAAA,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,MAAM;AAC3D,oBAAA,GAAG,QAAQ;AACX,oBAAA,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;AAC1B,iBAAA,CAAC,CAAC;gBACH,aAAa,CAAC,UAAU,GAAG;AACzB,oBAAA,IAAI,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC;AACnC,oBAAA,GAAG,gBAAgB;iBACpB;;;AAGP,KAAC,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE;AAC/C;AAEA,SAAS,qBAAqB,CAAC,EAC7B,SAAS,EACT,UAAU,EACV,eAAe,EACf,eAAe,EACf,MAAM,GAOP,EAAA;AACC,IAAA,OAAO,gBAAgB,EACrB,KAAK,EACL,IAAI,EACJ,OAAO,EACP,OAAO,GAAG,IAAI,EACd,UAAU,GAAG,CAAC,EACd,eAAe,EACf,MAAM,GAAG,KAAK,EACd,MAAM,GAAG,KAAK,EACd,IAAI,GAAG,KAAK,GAWb,EAAA;AACC,QAAA,IAAI;;AAEF,YAAA,MAAM,YAAY,GAAG,MAAM,uBAAuB,CAAC;gBACjD,SAAS;gBACT,KAAK;gBACL,IAAI;gBACJ,OAAO;gBACP,UAAU;gBACV,MAAM;gBACN,MAAM;gBACN,IAAI;gBACJ,MAAM;AACP,aAAA,CAAC;AAEF,YAAA,eAAe,GAAG,YAAY,CAAC;AAE/B,YAAA,MAAM,gBAAgB,GAAG,MAAM,eAAe,CAAC,cAAc,CAAC;gBAC5D,KAAK;gBACL,IAAI;AACJ,gBAAA,MAAM,EAAE,YAAY;gBACpB,OAAO;gBACP,eAAe;AACf,gBAAA,WAAW,EAAE,UAAU;AACxB,aAAA,CAAC;AAEF,YAAA,OAAO,gBAAgB,CAAC,gBAAgB,CAAC;;QACzC,OAAO,KAAK,EAAE;AACd,YAAA,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC;YACvC,OAAO;AACL,gBAAA,OAAO,EAAE,EAAE;AACX,gBAAA,UAAU,EAAE,EAAE;AACd,gBAAA,MAAM,EAAE,EAAE;AACV,gBAAA,MAAM,EAAE,EAAE;AACV,gBAAA,IAAI,EAAE,EAAE;AACR,gBAAA,eAAe,EAAE,EAAE;AACnB,gBAAA,KAAK,EAAE,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC;aAC9D;;AAEL,KAAC;AACH;AAEA,SAAS,qBAAqB,CAAC,EAC7B,cAAc,EACd,eAAe,GAIhB,EAAA;AACC,IAAA,OAAO,UAAU,OAAuB,EAAA;QACtC,IAAI,CAAC,eAAe,EAAE;YACpB;;AAEF,QAAA,eAAe,CAAC,OAAO,EAAE,cAAc,CAAC;AAC1C,KAAC;AACH;AAEA,SAAS,UAAU,CAAC,EAClB,MAAM,EACN,MAAM,EACN,eAAe,EAAE,gBAAgB,GAKlC,EAAA;IACC,OAAO,IAAI,CACT,OAAO,MAAM,EAAE,cAAc,KAAI;AAC/B,QAAA,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM;AACjE,QAAA,MAAM,OAAO,GAAG,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS;AAC7D,QAAA,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC;YAChC,KAAK;YACL,IAAI;YACJ,OAAO;YACP,MAAM;YACN,MAAM;YACN,IAAI;YACJ,eAAe,EAAE,qBAAqB,CAAC;gBACrC,cAAc;AACd,gBAAA,eAAe,EAAE,gBAAgB;aAClC,CAAC;AACH,SAAA,CAAC;QACF,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC;AAC/C,QAAA,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,mBAAmB,CAAC,IAAI,EAAE,YAAY,CAAC;QACtE,MAAM,IAAI,GAAuB,EAAE,IAAI,EAAE,GAAG,YAAY,EAAE,UAAU,EAAE;AACtE,QAAA,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC;AACnD,KAAC,EACD;QACE,IAAI,EAAE,SAAS,CAAC,UAAU;AAC1B,QAAA,WAAW,EAAE,CAAA;;;;;;;;;;;;;;;;;;;;;;AAsBlB,CAAA,CAAC,IAAI,EAAE;AACF,QAAA,MAAM,EAAE,MAAM;QACd,cAAc,EAAE,SAAS,CAAC,oBAAoB;AAC/C,KAAA,CACF;AACH;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BG;MACU,gBAAgB,GAAG,CAC9B,MAA6B,GAAA,EAAE,KACa;AAC5C,IAAA,MAAM,EACJ,cAAc,GAAG,QAAQ,EACzB,YAAY,EACZ,kBAAkB,EAClB,aAAa,EACb,YAAY,GAAG,QAAQ,EACvB,UAAU,GAAG,CAAC,EACd,UAAU,GAAG,CAAC,eAAe,CAAC,EAC9B,aAAa,GAAG,IAAI,EACpB,UAAU,GAAG,CAAC,EACd,eAAe,GAAG,WAAW,EAC7B,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,UAAU,EACV,YAAY,EACZ,eAAe,EAAE,gBAAgB,EACjC,eAAe,GAChB,GAAG,MAAM;IAEV,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,mBAAmB,EAAE;AAErD,IAAA,MAAM,YAAY,GAOd;AACF,QAAA,KAAK,EAAE,WAAW;AAClB,QAAA,IAAI,EAAE,UAAU;AAChB,QAAA,MAAM,EAAE,YAAY;AACpB,QAAA,MAAM,EAAE,YAAY;AACpB,QAAA,IAAI,EAAE,UAAU;KACjB;AAED,IAAA,IAAI,cAAc,KAAK,QAAQ,EAAE;AAC/B,QAAA,YAAY,CAAC,OAAO,GAAG,aAAa;;IAGtC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;IAEzC,MAAM,SAAS,GAAG,eAAe,CAAC;QAChC,cAAc;QACd,YAAY;QACZ,kBAAkB;QAClB,aAAa;AACd,KAAA,CAAC;;AAGF,IAAA,IAAI,eAA8B;AAElC,IAAA,IAAI,eAAe,KAAK,QAAQ,EAAE;QAChC,eAAe,GAAG,mBAAmB,CAAC;AACpC,YAAA,GAAG,oBAAoB;AACvB,YAAA,MAAM,EAAE,YAAY;AACpB,YAAA,OAAO,EAAE,cAAc,IAAI,oBAAoB,EAAE,OAAO;YACxD,MAAM;AACP,SAAA,CAAC;;SACG;QACL,eAAe,GAAG,sBAAsB,CAAC;AACvC,YAAA,GAAG,gBAAgB;AACnB,YAAA,MAAM,EAAE,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;AACxD,YAAA,MAAM,EAAE,eAAe;AACvB,YAAA,OAAO,EAAE,gBAAgB;AACzB,YAAA,OAAO,EAAE,cAAc,IAAI,gBAAgB,EAAE,OAAO;YACpD,OAAO,EAAE,gBAAgB,EAAE,OAAO,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC;YAC7D,MAAM;AACP,SAAA,CAAC;;IAGJ,MAAM,gBAAgB,GAAG,cAAc,CAAC;QACtC,YAAY;QACZ,UAAU;QACV,UAAU;QACV,YAAY;QACZ,MAAM;AACP,KAAA,CAAC;IAEF,IAAI,CAAC,gBAAgB,EAAE;AACrB,QAAA,MAAM,CAAC,IAAI,CAAC,8CAA8C,CAAC;;IAG7D,MAAM,eAAe,GAAG,qBAAqB,CAC3C;AACE,QAAA,QAAQ,EAAE,gBAAgB;QAC1B,UAAU;QAGV,MAAM;KACP,EACD,eAAe,CAChB;IAED,MAAM,MAAM,GAAG,qBAAqB,CAAC;QACnC,SAAS;QACT,UAAU;QACV,eAAe;QACf,eAAe;QACf,MAAM;AACP,KAAA,CAAC;AAEF,IAAA,OAAO,UAAU,CAAC;QAChB,MAAM;AACN,QAAA,MAAM,EAAE,UAAU;AAClB,QAAA,eAAe,EAAE,gBAAgB;AAClC,KAAA,CAAC;AACJ;;;;"}
@@ -0,0 +1,68 @@
1
+ import { GraphEvents } from '../common/enum.mjs';
2
+ import { createContentAggregator, ChatModelStreamHandler } from '../stream.mjs';
3
+ import { ModelEndHandler, ToolEndHandler } from '../events.mjs';
4
+
5
+ /**
6
+ * Multi-Agent Handler Utilities
7
+ *
8
+ * Provides a simple helper to create handlers with content aggregation for multi-agent scripts.
9
+ *
10
+ * Usage:
11
+ * ```typescript
12
+ * const { contentParts, aggregateContent, handlers } = createHandlers();
13
+ *
14
+ * // With callbacks
15
+ * const { contentParts, aggregateContent, handlers } = createHandlers({
16
+ * onRunStep: (event, data) => console.log('Step:', data),
17
+ * onRunStepCompleted: (event, data) => console.log('Completed:', data)
18
+ * });
19
+ * ```
20
+ */
21
+ /**
22
+ * Creates handlers with content aggregation for multi-agent scripts
23
+ */
24
+ function createHandlers(callbacks) {
25
+ // Set up content aggregator
26
+ const { contentParts, aggregateContent } = createContentAggregator();
27
+ // Create the handlers object
28
+ const handlers = {
29
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
30
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
31
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
32
+ [GraphEvents.ON_RUN_STEP]: {
33
+ handle: (event, data) => {
34
+ aggregateContent({ event, data: data });
35
+ callbacks?.onRunStep?.(event, data);
36
+ },
37
+ },
38
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
39
+ handle: (event, data) => {
40
+ aggregateContent({
41
+ event,
42
+ data: data,
43
+ });
44
+ callbacks?.onRunStepCompleted?.(event, data);
45
+ },
46
+ },
47
+ [GraphEvents.ON_RUN_STEP_DELTA]: {
48
+ handle: (event, data) => {
49
+ aggregateContent({ event, data: data });
50
+ callbacks?.onRunStepDelta?.(event, data);
51
+ },
52
+ },
53
+ [GraphEvents.ON_MESSAGE_DELTA]: {
54
+ handle: (event, data) => {
55
+ aggregateContent({ event, data: data });
56
+ callbacks?.onMessageDelta?.(event, data);
57
+ },
58
+ },
59
+ };
60
+ return {
61
+ contentParts,
62
+ aggregateContent,
63
+ handlers,
64
+ };
65
+ }
66
+
67
+ export { createHandlers };
68
+ //# sourceMappingURL=handlers.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.mjs","sources":["../../../src/utils/handlers.ts"],"sourcesContent":["/**\n * Multi-Agent Handler Utilities\n *\n * Provides a simple helper to create handlers with content aggregation for multi-agent scripts.\n *\n * Usage:\n * ```typescript\n * const { contentParts, aggregateContent, handlers } = createHandlers();\n *\n * // With callbacks\n * const { contentParts, aggregateContent, handlers } = createHandlers({\n * onRunStep: (event, data) => console.log('Step:', data),\n * onRunStepCompleted: (event, data) => console.log('Completed:', data)\n * });\n * ```\n */\n\nimport { GraphEvents } from '@/common';\nimport { ChatModelStreamHandler, createContentAggregator } from '@/stream';\nimport { ToolEndHandler, ModelEndHandler } from '@/events';\nimport type * as t from '@/types';\n\ninterface HandlerCallbacks {\n onRunStep?: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData) => void;\n onRunStepCompleted?: (\n event: GraphEvents.ON_RUN_STEP_COMPLETED,\n data: t.StreamEventData\n ) => void;\n onRunStepDelta?: (\n event: GraphEvents.ON_RUN_STEP_DELTA,\n data: t.StreamEventData\n ) => void;\n onMessageDelta?: (\n event: GraphEvents.ON_MESSAGE_DELTA,\n data: t.StreamEventData\n ) => void;\n}\n\n/**\n * Creates handlers with content aggregation for multi-agent scripts\n */\nexport function createHandlers(callbacks?: HandlerCallbacks): {\n contentParts: Array<t.MessageContentComplex | undefined>;\n aggregateContent: ReturnType<\n typeof createContentAggregator\n >['aggregateContent'];\n handlers: Record<string, t.EventHandler>;\n} {\n // Set up content aggregator\n const { contentParts, aggregateContent } = createContentAggregator();\n\n // Create the handlers object\n const handlers = {\n [GraphEvents.TOOL_END]: new ToolEndHandler(),\n [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),\n [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),\n\n [GraphEvents.ON_RUN_STEP]: {\n handle: (\n event: GraphEvents.ON_RUN_STEP,\n data: t.StreamEventData\n ): void => {\n aggregateContent({ event, data: data as t.RunStep });\n callbacks?.onRunStep?.(event, data);\n },\n },\n\n [GraphEvents.ON_RUN_STEP_COMPLETED]: {\n handle: (\n event: GraphEvents.ON_RUN_STEP_COMPLETED,\n data: t.StreamEventData\n ): void => {\n aggregateContent({\n event,\n data: data as unknown as { result: t.ToolEndEvent },\n });\n callbacks?.onRunStepCompleted?.(event, data);\n },\n },\n\n [GraphEvents.ON_RUN_STEP_DELTA]: {\n handle: (\n event: GraphEvents.ON_RUN_STEP_DELTA,\n data: t.StreamEventData\n ): void => {\n aggregateContent({ event, data: data as t.RunStepDeltaEvent });\n callbacks?.onRunStepDelta?.(event, data);\n },\n },\n\n [GraphEvents.ON_MESSAGE_DELTA]: {\n handle: (\n event: GraphEvents.ON_MESSAGE_DELTA,\n data: t.StreamEventData\n ): void => {\n aggregateContent({ event, data: data as t.MessageDeltaEvent });\n callbacks?.onMessageDelta?.(event, data);\n },\n },\n };\n\n return {\n contentParts,\n aggregateContent,\n handlers,\n };\n}\n"],"names":[],"mappings":";;;;AAAA;;;;;;;;;;;;;;;AAeG;AAuBH;;AAEG;AACG,SAAU,cAAc,CAAC,SAA4B,EAAA;;IAQzD,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,GAAG,uBAAuB,EAAE;;AAGpE,IAAA,MAAM,QAAQ,GAAG;AACf,QAAA,CAAC,WAAW,CAAC,QAAQ,GAAG,IAAI,cAAc,EAAE;AAC5C,QAAA,CAAC,WAAW,CAAC,cAAc,GAAG,IAAI,eAAe,EAAE;AACnD,QAAA,CAAC,WAAW,CAAC,iBAAiB,GAAG,IAAI,sBAAsB,EAAE;AAE7D,QAAA,CAAC,WAAW,CAAC,WAAW,GAAG;AACzB,YAAA,MAAM,EAAE,CACN,KAA8B,EAC9B,IAAuB,KACf;gBACR,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAiB,EAAE,CAAC;gBACpD,SAAS,EAAE,SAAS,GAAG,KAAK,EAAE,IAAI,CAAC;aACpC;AACF,SAAA;AAED,QAAA,CAAC,WAAW,CAAC,qBAAqB,GAAG;AACnC,YAAA,MAAM,EAAE,CACN,KAAwC,EACxC,IAAuB,KACf;AACR,gBAAA,gBAAgB,CAAC;oBACf,KAAK;AACL,oBAAA,IAAI,EAAE,IAA6C;AACpD,iBAAA,CAAC;gBACF,SAAS,EAAE,kBAAkB,GAAG,KAAK,EAAE,IAAI,CAAC;aAC7C;AACF,SAAA;AAED,QAAA,CAAC,WAAW,CAAC,iBAAiB,GAAG;AAC/B,YAAA,MAAM,EAAE,CACN,KAAoC,EACpC,IAAuB,KACf;gBACR,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAA2B,EAAE,CAAC;gBAC9D,SAAS,EAAE,cAAc,GAAG,KAAK,EAAE,IAAI,CAAC;aACzC;AACF,SAAA;AAED,QAAA,CAAC,WAAW,CAAC,gBAAgB,GAAG;AAC9B,YAAA,MAAM,EAAE,CACN,KAAmC,EACnC,IAAuB,KACf;gBACR,gBAAgB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAA2B,EAAE,CAAC;gBAC9D,SAAS,EAAE,cAAc,GAAG,KAAK,EAAE,IAAI,CAAC;aACzC;AACF,SAAA;KACF;IAED,OAAO;QACL,YAAY;QACZ,gBAAgB;QAChB,QAAQ;KACT;AACH;;;;"}
@@ -117,7 +117,8 @@ export declare enum Constants {
117
117
  OFFICIAL_CODE_BASEURL = "https://api.librechat.ai/v1",
118
118
  EXECUTE_CODE = "execute_code",
119
119
  WEB_SEARCH = "web_search",
120
- CONTENT_AND_ARTIFACT = "content_and_artifact"
120
+ CONTENT_AND_ARTIFACT = "content_and_artifact",
121
+ LC_TRANSFER_TO_ = "lc_transfer_to_"
121
122
  }
122
123
  export declare enum TitleMethod {
123
124
  STRUCTURED = "structured",
@@ -2,7 +2,17 @@ import type * as t from '@/types';
2
2
  import { StandardGraph } from './Graph';
3
3
  /**
4
4
  * MultiAgentGraph extends StandardGraph to support dynamic multi-agent workflows
5
- * with handoffs, fan-in/fan-out, and other composable patterns
5
+ * with handoffs, fan-in/fan-out, and other composable patterns.
6
+ *
7
+ * Key behavior:
8
+ * - Agents with ONLY handoff edges: Can dynamically route to any handoff destination
9
+ * - Agents with ONLY direct edges: Always follow their direct edges
10
+ * - Agents with BOTH: Use Command for exclusive routing (handoff OR direct, not both)
11
+ * - If handoff occurs: Only the handoff destination executes
12
+ * - If no handoff: Direct edges execute (potentially in parallel)
13
+ *
14
+ * This enables the common pattern where an agent either delegates (handoff)
15
+ * OR continues its workflow (direct edges), but not both simultaneously.
6
16
  */
7
17
  export declare class MultiAgentGraph extends StandardGraph {
8
18
  private edges;
@@ -33,5 +43,5 @@ export declare class MultiAgentGraph extends StandardGraph {
33
43
  /**
34
44
  * Create the multi-agent workflow with dynamic handoffs
35
45
  */
36
- createWorkflow(): t.CompiledStateWorkflow;
46
+ createWorkflow(): t.CompiledMultiAgentWorkflow;
37
47
  }
@@ -19,7 +19,9 @@ export declare class CustomAnthropic extends ChatAnthropicMessages {
19
19
  private message_delta;
20
20
  private tools_in_params?;
21
21
  private emitted_usage?;
22
+ top_k: number | undefined;
22
23
  constructor(fields?: CustomAnthropicInput);
24
+ static lc_name(): 'LibreChatAnthropic';
23
25
  /**
24
26
  * Get the parameters used to invoke the model
25
27
  */
@@ -30,6 +32,7 @@ export declare class CustomAnthropic extends ChatAnthropicMessages {
30
32
  */
31
33
  getStreamUsage(): UsageMetadata | undefined;
32
34
  resetTokenEvents(): void;
35
+ setDirectFields(fields?: CustomAnthropicInput): void;
33
36
  private createGenerationChunk;
34
37
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
35
38
  }
@@ -8,6 +8,7 @@ import type { GoogleClientOptions } from '@/types';
8
8
  export declare class CustomChatGoogleGenerativeAI extends ChatGoogleGenerativeAI {
9
9
  thinkingConfig?: GeminiGenerationConfig['thinkingConfig'];
10
10
  constructor(fields: GoogleClientOptions);
11
+ static lc_name(): 'LibreChatGoogleGenerativeAI';
11
12
  invocationParams(options?: this['ParsedCallOptions']): Omit<GenerateContentRequest, 'contents'>;
12
13
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
13
14
  }
@@ -3,5 +3,6 @@ import { ChatOllama as BaseChatOllama } from '@langchain/ollama';
3
3
  import { CallbackManagerForLLMRun } from '@langchain/core/callbacks/manager';
4
4
  import type { BaseMessage } from '@langchain/core/messages';
5
5
  export declare class ChatOllama extends BaseChatOllama {
6
+ static lc_name(): 'LibreChatOllama';
6
7
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
7
8
  }
@@ -40,7 +40,12 @@ export declare class CustomAzureOpenAIClient extends AzureOpenAIClient {
40
40
  }
41
41
  /** @ts-expect-error We are intentionally overriding `getReasoningParams` */
42
42
  export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptions> {
43
+ _lc_stream_delay?: number;
44
+ constructor(fields?: t.ChatOpenAICallOptions & {
45
+ _lc_stream_delay?: number;
46
+ } & t.OpenAIChatInput['modelKwargs']);
43
47
  get exposedClient(): CustomOpenAIClient;
48
+ static lc_name(): string;
44
49
  protected _getClientOptions(options?: OpenAICoreRequestOptions): OpenAICoreRequestOptions;
45
50
  /**
46
51
  * Returns backwards compatible reasoning parameters from constructor params and call options
@@ -53,7 +58,12 @@ export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptio
53
58
  }
54
59
  /** @ts-expect-error We are intentionally overriding `getReasoningParams` */
55
60
  export declare class AzureChatOpenAI extends OriginalAzureChatOpenAI {
61
+ _lc_stream_delay?: number;
62
+ constructor(fields?: t.AzureOpenAIInput & {
63
+ _lc_stream_delay?: number;
64
+ });
56
65
  get exposedClient(): CustomOpenAIClient;
66
+ static lc_name(): 'LibreChatAzureOpenAI';
57
67
  /**
58
68
  * Returns backwards compatible reasoning parameters from constructor params and call options
59
69
  * @internal
@@ -65,6 +75,7 @@ export declare class AzureChatOpenAI extends OriginalAzureChatOpenAI {
65
75
  }
66
76
  export declare class ChatDeepSeek extends OriginalChatDeepSeek {
67
77
  get exposedClient(): CustomOpenAIClient;
78
+ static lc_name(): 'LibreChatDeepSeek';
68
79
  protected _getClientOptions(options?: OpenAICoreRequestOptions): OpenAICoreRequestOptions;
69
80
  }
70
81
  /** xAI-specific usage metadata type */
@@ -84,6 +95,7 @@ export interface XAIUsageMetadata extends OpenAIClient.Completions.CompletionUsa
84
95
  num_sources_used?: number;
85
96
  }
86
97
  export declare class ChatXAI extends OriginalChatXAI {
98
+ _lc_stream_delay?: number;
87
99
  constructor(fields?: Partial<ChatXAIInput> & {
88
100
  configuration?: {
89
101
  baseURL?: string;
@@ -91,7 +103,9 @@ export declare class ChatXAI extends OriginalChatXAI {
91
103
  clientConfig?: {
92
104
  baseURL?: string;
93
105
  };
106
+ _lc_stream_delay?: number;
94
107
  });
108
+ static lc_name(): 'LibreChatXAI';
95
109
  get exposedClient(): CustomOpenAIClient;
96
110
  protected _getClientOptions(options?: OpenAICoreRequestOptions): OpenAICoreRequestOptions;
97
111
  _streamResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
@@ -1,10 +1,12 @@
1
- import type { ChatOpenAICallOptions, OpenAIClient } from '@langchain/openai';
2
- import type { AIMessageChunk, HumanMessageChunk, SystemMessageChunk, FunctionMessageChunk, ToolMessageChunk, ChatMessageChunk } from '@langchain/core/messages';
3
1
  import { ChatOpenAI } from '@/llm/openai';
2
+ import type { FunctionMessageChunk, SystemMessageChunk, HumanMessageChunk, ToolMessageChunk, ChatMessageChunk, AIMessageChunk } from '@langchain/core/messages';
3
+ import type { ChatOpenAICallOptions, OpenAIChatInput, OpenAIClient } from '@langchain/openai';
4
4
  export interface ChatOpenRouterCallOptions extends ChatOpenAICallOptions {
5
5
  include_reasoning?: boolean;
6
+ modelKwargs?: OpenAIChatInput['modelKwargs'];
6
7
  }
7
8
  export declare class ChatOpenRouter extends ChatOpenAI {
8
9
  constructor(_fields: Partial<ChatOpenRouterCallOptions>);
10
+ static lc_name(): 'LibreChatOpenRouter';
9
11
  protected _convertOpenAIDeltaToBaseMessageChunk(delta: Record<string, any>, rawResponse: OpenAIClient.ChatCompletionChunk, defaultRole?: 'function' | 'user' | 'system' | 'developer' | 'assistant' | 'tool'): AIMessageChunk | HumanMessageChunk | SystemMessageChunk | FunctionMessageChunk | ToolMessageChunk | ChatMessageChunk;
10
12
  }
@@ -286,7 +286,7 @@ import type { VertexAIClientOptions } from '@/types';
286
286
  export declare class ChatVertexAI extends ChatGoogle {
287
287
  lc_namespace: string[];
288
288
  dynamicThinkingBudget: boolean;
289
- static lc_name(): 'ChatVertexAI';
289
+ static lc_name(): 'LibreChatVertexAI';
290
290
  constructor(fields?: VertexAIClientOptions);
291
291
  invocationParams(options?: this['ParsedCallOptions'] | undefined): GoogleAIModelRequestParams;
292
292
  buildConnection(fields: VertexAIClientOptions, client: GoogleAbstractedClient): void;
@@ -2,23 +2,23 @@ import { AIMessage, ToolMessage, BaseMessage, HumanMessage, SystemMessage } from
2
2
  import type { MessageContentImageUrl } from '@langchain/core/messages';
3
3
  import type { MessageContentComplex, TPayload } from '@/types';
4
4
  import { Providers } from '@/common';
5
- interface VisionMessageParams {
5
+ interface MediaMessageParams {
6
6
  message: {
7
7
  role: string;
8
8
  content: string;
9
9
  name?: string;
10
10
  [key: string]: any;
11
11
  };
12
- image_urls: MessageContentImageUrl[];
12
+ mediaParts: MessageContentComplex[];
13
13
  endpoint?: Providers;
14
14
  }
15
15
  /**
16
- * Formats a message to OpenAI Vision API payload format.
16
+ * Formats a message with media content (images, documents, videos, audios) to API payload format.
17
17
  *
18
- * @param {VisionMessageParams} params - The parameters for formatting.
19
- * @returns {Object} - The formatted message.
18
+ * @param params - The parameters for formatting.
19
+ * @returns - The formatted message.
20
20
  */
21
- export declare const formatVisionMessage: ({ message, image_urls, endpoint, }: VisionMessageParams) => {
21
+ export declare const formatMediaMessage: ({ message, endpoint, mediaParts, }: MediaMessageParams) => {
22
22
  role: string;
23
23
  content: MessageContentComplex[];
24
24
  name?: string;
@@ -31,6 +31,9 @@ interface MessageInput {
31
31
  text?: string;
32
32
  content?: string | MessageContentComplex[];
33
33
  image_urls?: MessageContentImageUrl[];
34
+ documents?: MessageContentComplex[];
35
+ videos?: MessageContentComplex[];
36
+ audios?: MessageContentComplex[];
34
37
  lc_id?: string[];
35
38
  [key: string]: any;
36
39
  }
@@ -50,16 +53,16 @@ interface FormattedMessage {
50
53
  /**
51
54
  * Formats a message to OpenAI payload format based on the provided options.
52
55
  *
53
- * @param {FormatMessageParams} params - The parameters for formatting.
54
- * @returns {FormattedMessage | HumanMessage | AIMessage | SystemMessage} - The formatted message.
56
+ * @param params - The parameters for formatting.
57
+ * @returns - The formatted message.
55
58
  */
56
- export declare const formatMessage: ({ message, userName, assistantName, endpoint, langChain, }: FormatMessageParams) => FormattedMessage | HumanMessage | AIMessage | SystemMessage;
59
+ export declare const formatMessage: ({ message, userName, endpoint, assistantName, langChain, }: FormatMessageParams) => FormattedMessage | HumanMessage | AIMessage | SystemMessage;
57
60
  /**
58
61
  * Formats an array of messages for LangChain.
59
62
  *
60
- * @param {Array<MessageInput>} messages - The array of messages to format.
61
- * @param {Omit<FormatMessageParams, 'message' | 'langChain'>} formatOptions - The options for formatting each message.
62
- * @returns {Array<HumanMessage | AIMessage | SystemMessage>} - The array of formatted LangChain messages.
63
+ * @param messages - The array of messages to format.
64
+ * @param formatOptions - The options for formatting each message.
65
+ * @returns - The array of formatted LangChain messages.
63
66
  */
64
67
  export declare const formatLangChainMessages: (messages: Array<MessageInput>, formatOptions: Omit<FormatMessageParams, "message" | "langChain">) => Array<HumanMessage | AIMessage | SystemMessage>;
65
68
  interface LangChainMessage {
@@ -76,17 +79,17 @@ interface LangChainMessage {
76
79
  /**
77
80
  * Formats a LangChain message object by merging properties from `lc_kwargs` or `kwargs` and `additional_kwargs`.
78
81
  *
79
- * @param {LangChainMessage} message - The message object to format.
80
- * @returns {Record<string, any>} The formatted LangChain message.
82
+ * @param message - The message object to format.
83
+ * @returns - The formatted LangChain message.
81
84
  */
82
85
  export declare const formatFromLangChain: (message: LangChainMessage) => Record<string, any>;
83
86
  /**
84
87
  * Formats an array of messages for LangChain, handling tool calls and creating ToolMessage instances.
85
88
  *
86
- * @param {TPayload} payload - The array of messages to format.
87
- * @param {Record<number, number>} [indexTokenCountMap] - Optional map of message indices to token counts.
88
- * @param {Set<string>} [tools] - Optional set of tool names that are allowed in the request.
89
- * @returns {Object} - Object containing formatted messages and updated indexTokenCountMap if provided.
89
+ * @param payload - The array of messages to format.
90
+ * @param indexTokenCountMap - Optional map of message indices to token counts.
91
+ * @param tools - Optional set of tool names that are allowed in the request.
92
+ * @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
90
93
  */
91
94
  export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap?: Record<number, number>, tools?: Set<string>) => {
92
95
  messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;
@@ -94,8 +97,8 @@ export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap
94
97
  };
95
98
  /**
96
99
  * Formats an array of messages for LangChain, making sure all content fields are strings
97
- * @param {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} payload - The array of messages to format.
98
- * @returns {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} - The array of formatted LangChain messages, including ToolMessages for tool calls.
100
+ * @param payload - The array of messages to format.
101
+ * @returns - The array of formatted LangChain messages, including ToolMessages for tool calls.
99
102
  */
100
103
  export declare const formatContentStrings: (payload: Array<BaseMessage>) => Array<BaseMessage>;
101
104
  /**
@@ -7,7 +7,7 @@ export declare const defaultOmitOptions: Set<string>;
7
7
  export declare class Run<_T extends t.BaseGraphState> {
8
8
  id: string;
9
9
  private tokenCounter?;
10
- private handlerRegistry;
10
+ private handlerRegistry?;
11
11
  private indexTokenCountMap?;
12
12
  graphRunnable?: t.CompiledStateWorkflow;
13
13
  Graph: StandardGraph | MultiAgentGraph | undefined;
@@ -3,9 +3,10 @@ import type * as t from './types';
3
3
  * Firecrawl scraper implementation
4
4
  * Uses the Firecrawl API to scrape web pages
5
5
  */
6
- export declare class FirecrawlScraper {
6
+ export declare class FirecrawlScraper implements t.BaseScraper {
7
7
  private apiKey;
8
8
  private apiUrl;
9
+ private version;
9
10
  private defaultFormats;
10
11
  private timeout;
11
12
  private logger;
@@ -7,8 +7,10 @@ export declare abstract class BaseReranker {
7
7
  protected getDefaultRanking(documents: string[], topK: number): t.Highlight[];
8
8
  }
9
9
  export declare class JinaReranker extends BaseReranker {
10
- constructor({ apiKey, logger, }: {
10
+ private apiUrl;
11
+ constructor({ apiKey, apiUrl, logger, }: {
11
12
  apiKey?: string;
13
+ apiUrl?: string;
12
14
  logger?: t.Logger;
13
15
  });
14
16
  rerank(query: string, documents: string[], topK?: number): Promise<t.Highlight[]>;
@@ -30,6 +32,7 @@ export declare class InfinityReranker extends BaseReranker {
30
32
  export declare const createReranker: (config: {
31
33
  rerankerType: t.RerankerType;
32
34
  jinaApiKey?: string;
35
+ jinaApiUrl?: string;
33
36
  cohereApiKey?: string;
34
37
  logger?: t.Logger;
35
38
  }) => BaseReranker | undefined;
@@ -1,9 +1,8 @@
1
1
  import type * as t from './types';
2
- import { FirecrawlScraper } from './firecrawl';
3
2
  export declare const createSearchAPI: (config: t.SearchConfig) => {
4
3
  getSources: (params: t.GetSourcesParams) => Promise<t.SearchResult>;
5
4
  };
6
- export declare const createSourceProcessor: (config?: t.ProcessSourcesConfig, scraperInstance?: FirecrawlScraper) => {
5
+ export declare const createSourceProcessor: (config?: t.ProcessSourcesConfig, scraperInstance?: t.BaseScraper) => {
7
6
  processSources: (fields: t.ProcessSourcesFields) => Promise<t.SearchResultData>;
8
7
  topResults: number;
9
8
  };
@@ -0,0 +1,59 @@
1
+ import type * as t from './types';
2
+ /**
3
+ * Serper scraper implementation
4
+ * Uses the Serper Scrape API (https://scrape.serper.dev) to scrape web pages
5
+ *
6
+ * Features:
7
+ * - Simple API with single endpoint
8
+ * - Returns both text and markdown content
9
+ * - Includes metadata from scraped pages
10
+ * - Credits-based pricing model
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const scraper = createSerperScraper({
15
+ * apiKey: 'your-serper-api-key',
16
+ * includeMarkdown: true,
17
+ * timeout: 10000
18
+ * });
19
+ *
20
+ * const [url, response] = await scraper.scrapeUrl('https://example.com');
21
+ * if (response.success) {
22
+ * const [content] = scraper.extractContent(response);
23
+ * console.log(content);
24
+ * }
25
+ * ```
26
+ */
27
+ export declare class SerperScraper implements t.BaseScraper {
28
+ private apiKey;
29
+ private apiUrl;
30
+ private timeout;
31
+ private logger;
32
+ private includeMarkdown;
33
+ constructor(config?: t.SerperScraperConfig);
34
+ /**
35
+ * Scrape a single URL
36
+ * @param url URL to scrape
37
+ * @param options Scrape options
38
+ * @returns Scrape response
39
+ */
40
+ scrapeUrl(url: string, options?: t.SerperScrapeOptions): Promise<[string, t.SerperScrapeResponse]>;
41
+ /**
42
+ * Extract content from scrape response
43
+ * @param response Scrape response
44
+ * @returns Extracted content or empty string if not available
45
+ */
46
+ extractContent(response: t.SerperScrapeResponse): [string, undefined | t.References];
47
+ /**
48
+ * Extract metadata from scrape response
49
+ * @param response Scrape response
50
+ * @returns Metadata object
51
+ */
52
+ extractMetadata(response: t.SerperScrapeResponse): Record<string, string | number | boolean | null | undefined>;
53
+ }
54
+ /**
55
+ * Create a Serper scraper instance
56
+ * @param config Scraper configuration
57
+ * @returns Serper scraper instance
58
+ */
59
+ export declare const createSerperScraper: (config?: t.SerperScraperConfig) => SerperScraper;
@@ -6,6 +6,27 @@ import { DATE_RANGE } from './schema';
6
6
  * Creates a search tool with a schema that dynamically includes the country field
7
7
  * only when the searchProvider is 'serper'.
8
8
  *
9
+ * Supports multiple scraper providers:
10
+ * - Firecrawl (default): Full-featured web scraping with multiple formats
11
+ * - Serper: Lightweight scraping using Serper's scrape API
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * // Using Firecrawl scraper (default)
16
+ * const searchTool = createSearchTool({
17
+ * searchProvider: 'serper',
18
+ * scraperProvider: 'firecrawl',
19
+ * firecrawlApiKey: 'your-firecrawl-key'
20
+ * });
21
+ *
22
+ * // Using Serper scraper
23
+ * const searchTool = createSearchTool({
24
+ * searchProvider: 'serper',
25
+ * scraperProvider: 'serper',
26
+ * serperApiKey: 'your-serper-key'
27
+ * });
28
+ * ```
29
+ *
9
30
  * @param config - The search tool configuration
10
31
  * @returns A DynamicStructuredTool with a schema that depends on the searchProvider
11
32
  */
@@ -18,16 +39,16 @@ export declare const createSearchTool: (config?: t.SearchToolConfig) => DynamicS
18
39
  news: z.ZodOptional<z.ZodBoolean>;
19
40
  }, "strip", z.ZodTypeAny, {
20
41
  query: string;
21
- date?: DATE_RANGE | undefined;
22
- images?: boolean | undefined;
23
42
  videos?: boolean | undefined;
43
+ images?: boolean | undefined;
24
44
  news?: boolean | undefined;
45
+ date?: DATE_RANGE | undefined;
25
46
  country?: unknown;
26
47
  }, {
27
48
  query: string;
28
- date?: DATE_RANGE | undefined;
29
- images?: boolean | undefined;
30
49
  videos?: boolean | undefined;
50
+ images?: boolean | undefined;
31
51
  news?: boolean | undefined;
52
+ date?: DATE_RANGE | undefined;
32
53
  country?: unknown;
33
54
  }>>;