{"version":3,"file":"tool.mjs","sources":["../../../../src/tools/search/tool.ts"],"sourcesContent":["import { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { RunnableConfig } from '@langchain/core/runnables';\nimport type * as t from './types';\nimport {\n  countrySchema,\n  imagesSchema,\n  videosSchema,\n  querySchema,\n  dateSchema,\n  newsSchema,\n  DATE_RANGE,\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 * URL regex pattern to detect direct URLs in query\n */\nconst URL_PATTERN = /https?:\\/\\/[^\\s<>\"{}|\\\\^`[\\]]+/gi;\n\n/**\n * Extracts URLs from a query string\n * @param query - The search query\n * @returns Array of URLs found in the query\n */\nfunction extractUrlsFromQuery(query: string): string[] {\n  const matches = query.match(URL_PATTERN);\n  return matches ?? [];\n}\n\n/**\n * Checks if the query is primarily a URL request (contains URL and minimal other text)\n * @param query - The search query\n * @returns True if the query appears to be a direct URL request\n */\nfunction isDirectUrlRequest(query: string): boolean {\n  const urls = extractUrlsFromQuery(query);\n  if (urls.length === 0) {\n    return false;\n  }\n\n  // Remove URLs from query and check remaining text\n  let remainingText = query;\n  for (const url of urls) {\n    remainingText = remainingText.replace(url, '');\n  }\n\n  // Clean up and check if remaining text is minimal (just filler words or questions about the URL)\n  remainingText = remainingText.trim().toLowerCase();\n\n  // If very little text remains, it's likely a direct URL request\n  if (remainingText.length < 50) {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Directly extracts content from URLs using the scraper\n * @param urls - URLs to extract content from\n * @param scraper - The scraper instance to use\n * @param logger - Logger instance\n * @returns Search result with extracted content\n */\nasync function extractDirectUrlContent({\n  urls,\n  scraper,\n  logger,\n}: {\n  urls: string[];\n  scraper: t.BaseScraper;\n  logger: t.Logger;\n}): Promise<t.SearchResult> {\n  try {\n    const results: t.ProcessedOrganic[] = [];\n\n    for (const url of urls) {\n      try {\n        logger.debug(`Direct URL extraction: ${url}`);\n        const [, response] = await scraper.scrapeUrl(url);\n\n        if (response.success && response.data) {\n          const [content, references] = scraper.extractContent(response);\n          const metadata = scraper.extractMetadata(response);\n\n          // Helper to safely extract string from metadata\n          const getString = (value: unknown): string | undefined => {\n            return typeof value === 'string' ? value : undefined;\n          };\n\n          results.push({\n            position: results.length + 1,\n            title:\n              getString(metadata.title) ?? getString(metadata.ogTitle) ?? url,\n            link: url,\n            snippet:\n              getString(metadata.description) ??\n              getString(metadata.ogDescription) ??\n              '',\n            content: content,\n            references: references,\n            processed: true,\n          });\n        } else {\n          logger.warn(\n            `Failed to extract content from ${url}: ${response.error}`\n          );\n          // Still add the URL as a result, but without content\n          results.push({\n            position: results.length + 1,\n            title: url,\n            link: url,\n            snippet: response.error ?? 'Failed to extract content',\n            processed: false,\n          });\n        }\n      } catch (error) {\n        logger.error(`Error extracting URL ${url}:`, error);\n        results.push({\n          position: results.length + 1,\n          title: url,\n          link: url,\n          snippet: error instanceof Error ? error.message : String(error),\n          processed: false,\n        });\n      }\n    }\n\n    return {\n      success: true,\n      data: {\n        organic: results,\n        topStories: [],\n        images: [],\n        videos: [],\n        relatedSearches: [],\n      },\n    };\n  } catch (error) {\n    logger.error('Error in direct URL extraction:', error);\n    return {\n      success: false,\n      error: error instanceof Error ? error.message : String(error),\n    };\n  }\n}\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  scraper,\n  onGetHighlights,\n  logger,\n}: {\n  safeSearch: t.SearchToolConfig['safeSearch'];\n  searchAPI: ReturnType<typeof createSearchAPI>;\n  sourceProcessor: ReturnType<typeof createSourceProcessor>;\n  scraper: t.BaseScraper;\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      // Check if query contains direct URLs for extraction\n      const urls = extractUrlsFromQuery(query);\n      const isDirectUrl = isDirectUrlRequest(query);\n\n      let searchResult: t.SearchResult;\n\n      if (isDirectUrl && urls.length > 0) {\n        // Direct URL extraction mode - skip search API and extract directly\n        logger.debug(`Direct URL extraction mode for: ${urls.join(', ')}`);\n        searchResult = await extractDirectUrlContent({\n          urls,\n          scraper,\n          logger,\n        });\n      } else {\n        // Normal search mode - execute parallel searches and merge results\n        searchResult = await executeParallelSearches({\n          searchAPI,\n          query,\n          date,\n          country,\n          safeSearch,\n          images,\n          videos,\n          news,\n          logger,\n        });\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        // Skip additional scraping if we already extracted content directly\n        skipScraping: isDirectUrl,\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: Record<string, unknown>;\n  search: ReturnType<typeof createSearchProcessor>;\n  onSearchResults: t.SearchToolConfig['onSearchResults'];\n}): DynamicStructuredTool {\n  return tool(\n    async (rawParams, runnableConfig) => {\n      const params = rawParams as SearchToolParams;\n      const { query, date, country: _c, images, videos, news } = params;\n      const country = typeof _c === 'string' && _c ? _c : undefined;\n\n      // Log the incoming query for debugging URL detection\n      const toolLogger = createDefaultLogger();\n      toolLogger.debug(`[web_search] Received query: \"${query}\"`);\n      const detectedUrls = extractUrlsFromQuery(query);\n      if (detectedUrls.length > 0) {\n        toolLogger.debug(\n          `[web_search] Detected URLs in query: ${detectedUrls.join(', ')}`\n        );\n      }\n\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:\n        `Real-time web search and direct URL content extraction. Results have required citation anchors.\n\n**CAPABILITIES:**\n- Search: Query the web for information on any topic\n- Direct URL: Fetch and extract content from a specific URL for summarization or analysis\n\n**CRITICAL - URL HANDLING:**\nWhen user provides a URL (e.g., \"summarize https://example.com/article\"), you MUST include the FULL URL in the query parameter.\n- CORRECT: query = \"https://example.com/article\" or \"summarize https://example.com/article\"\n- WRONG: query = \"example article summary\" (do NOT convert URLs to search terms)\n\n**USAGE:**\n- For search: Use concise search terms as query\n- For URL extraction: Pass the complete URL in the query field\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 */\n/** Input params type for search tool */\ninterface SearchToolParams {\n  query: string;\n  date?: DATE_RANGE;\n  country?: string;\n  images?: boolean;\n  videos?: boolean;\n  news?: boolean;\n}\n\nexport const createSearchTool = (\n  config: t.SearchToolConfig = {}\n): DynamicStructuredTool => {\n  const {\n    searchProvider = 'serper',\n    serperApiKey,\n    searxngInstanceUrl,\n    searxngApiKey,\n    domainBlocklist,\n    countryBlocklist,\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 schemaProperties: Record<string, unknown> = {\n    query: querySchema,\n    date: dateSchema,\n    images: imagesSchema,\n    videos: videosSchema,\n    news: newsSchema,\n  };\n\n  if (searchProvider === 'serper') {\n    schemaProperties.country = countrySchema;\n  }\n\n  const toolSchema = {\n    type: 'object',\n    properties: schemaProperties,\n    required: ['query'],\n  };\n\n  const searchAPI = createSearchAPI({\n    searchProvider,\n    serperApiKey,\n    searxngInstanceUrl,\n    searxngApiKey,\n    domainBlocklist,\n    countryBlocklist,\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    scraper: scraperInstance,\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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"}