{"version":3,"sources":["../src/index.ts","../src/libs/logger/index.ts","../src/search/logger.ts","../src/search/bing.ts","../src/search/duckduckgo.ts","../src/search/searxng.ts","../src/search/tavily.ts","../src/libs/agent-browser/index.ts","../src/libs/browser/finder.ts","../src/libs/agent-browser/config.ts","../src/search/local.ts","../src/search/google.ts","../src/search/zhipu.ts","../src/search/exa.ts","../src/search/bocha.ts","../src/schemas.ts","../src/tools.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { ISearchRequestOptions, ISearchResponse, SearchProvider } from './interface.js';\nimport { bingSearch, duckDuckGoSearch, searxngSearch, tavilySearch, localSearch, googleSearch, zhipuSearch, exaSearch, bochaSearch } from './search/index.js';\nimport { SEARCH_TOOL, EXTRACT_TOOL, SCRAPE_TOOL, MAP_TOOL } from './tools.js';\nimport type { SearchInput, MapInput, ScrapeInput, ExtractInput } from './schemas.js';\nimport { AgentBrowser } from './libs/agent-browser/index.js';\nimport dotenvx from '@dotenvx/dotenvx';\nimport { SafeSearchType } from 'duck-duck-scrape';\n\n// Load environment variables silently (suppress all output)\ndotenvx.config({ quiet: true });\n\n// search api\nconst SEARCH_API_URL = process.env.SEARCH_API_URL;\nconst SEARCH_API_KEY = process.env.SEARCH_API_KEY;\nconst SEARCH_PROVIDER: SearchProvider = process.env.SEARCH_PROVIDER as SearchProvider ?? 'local';\n\n// search query params\nconst SAFE_SEARCH = process.env.SAFE_SEARCH ?? 0;\nconst LIMIT = process.env.LIMIT ?? 10;\nconst CATEGORIES = process.env.CATEGORIES ?? 'general';\nconst ENGINES = process.env.ENGINES ?? 'all';\nconst FORMAT = process.env.FORMAT ?? 'json';\nconst LANGUAGE = process.env.LANGUAGE ?? 'auto';\nconst TIME_RANGE = process.env.TIME_RANGE ?? '';\nconst DEFAULT_TIMEOUT = process.env.TIMEOUT ?? 10000;\n\n// Server implementation using MCP SDK v1.25+ pattern\nconst server = new McpServer(\n  {\n    name: 'one-search-mcp',\n    version: '1.1.2',\n  },\n  {\n    capabilities: {\n      tools: {},\n      logging: {},\n    },\n  },\n);\n\nconst searchDefaultConfig = {\n  limit: Number(LIMIT),\n  categories: CATEGORIES,\n  format: FORMAT,\n  safesearch: SAFE_SEARCH,\n  language: LANGUAGE,\n  engines: ENGINES,\n  time_range: TIME_RANGE,\n  timeout: DEFAULT_TIMEOUT,\n};\n\n// Helper function to wrap tool handlers with logging and error handling\nfunction createToolHandler<TInput, TOutput>(\n  toolName: string,\n  handler: (args: TInput) => Promise<TOutput>,\n) {\n  return async (args: TInput) => {\n    const startTime = Date.now();\n\n    try {\n      await server.sendLoggingMessage({\n        level: 'info',\n        data: `[${new Date().toISOString()}] Request started for tool: [${toolName}]`,\n      });\n\n      const result = await handler(args);\n\n      await server.sendLoggingMessage({\n        level: 'info',\n        data: `[${new Date().toISOString()}] Request completed in ${Date.now() - startTime}ms`,\n      });\n\n      return result;\n    } catch (error) {\n      await server.sendLoggingMessage({\n        level: 'error',\n        data: `[${new Date().toISOString()}] Error in ${toolName}: ${error}`,\n      });\n      const msg = error instanceof Error ? error.message : String(error);\n      return {\n        content: [\n          {\n            type: 'text' as const,\n            text: msg,\n          },\n        ],\n        isError: true,\n      };\n    }\n  };\n}\n\n// Register tools using the new registerTool API\nserver.registerTool(\n  SEARCH_TOOL.name,\n  {\n    description: SEARCH_TOOL.description,\n    inputSchema: SEARCH_TOOL.schema,\n  },\n  createToolHandler(SEARCH_TOOL.name, async (args: SearchInput) => {\n    const { results, success } = await processSearch({\n      ...args,\n      apiKey: SEARCH_API_KEY ?? '',\n      apiUrl: SEARCH_API_URL,\n    });\n\n    if (!success) {\n      throw new Error('Failed to search');\n    }\n\n    const resultsText = results.map((result) => (\n      `Title: ${result.title}\nURL: ${result.url}\nDescription: ${result.snippet}\n${result.markdown ? `Content: ${result.markdown}` : ''}`\n    ));\n\n    return {\n      content: [\n        {\n          type: 'text' as const,\n          text: resultsText.join('\\n\\n'),\n        },\n      ],\n    };\n  }),\n);\n\nserver.registerTool(\n  SCRAPE_TOOL.name,\n  {\n    description: SCRAPE_TOOL.description,\n    inputSchema: SCRAPE_TOOL.schema,\n  },\n  createToolHandler(SCRAPE_TOOL.name, async (args: ScrapeInput) => {\n    const { url, ...scrapeArgs } = args;\n    const { content } = await processScrape(url, scrapeArgs);\n\n    return {\n      content,\n    };\n  }),\n);\n\nserver.registerTool(\n  MAP_TOOL.name,\n  {\n    description: MAP_TOOL.description,\n    inputSchema: MAP_TOOL.schema,\n  },\n  createToolHandler(MAP_TOOL.name, async (args: MapInput) => {\n    const { content } = await processMapUrl(args.url, args);\n\n    return {\n      content,\n    };\n  }),\n);\n\nserver.registerTool(\n  EXTRACT_TOOL.name,\n  {\n    description: EXTRACT_TOOL.description,\n    inputSchema: EXTRACT_TOOL.schema,\n  },\n  createToolHandler(EXTRACT_TOOL.name, async (args: ExtractInput) => {\n    const { content } = await processExtract(args);\n\n    return {\n      content,\n    };\n  }),\n);\n\n// Business logic functions\nasync function processSearch(args: ISearchRequestOptions): Promise<ISearchResponse> {\n  switch (SEARCH_PROVIDER) {\n    case 'searxng': {\n      // merge default config with args\n      const params = {\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      };\n\n      // but categories and language have higher priority (ENV > args).\n      const { categories, language } = searchDefaultConfig;\n\n      if (categories) {\n        params.categories = categories;\n      }\n      if (language) {\n        params.language = language;\n      }\n      return await searxngSearch(params);\n    }\n    case 'tavily': {\n      return await tavilySearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      });\n    }\n    case 'bing': {\n      return await bingSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      });\n    }\n    case 'duckduckgo': {\n      const safeSearch = args.safeSearch ?? 0;\n      const safeSearchOptions = [SafeSearchType.STRICT, SafeSearchType.MODERATE, SafeSearchType.OFF];\n      return await duckDuckGoSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n        safeSearch: safeSearchOptions[safeSearch],\n      });\n    }\n    case 'local': {\n      return await localSearch({\n        ...searchDefaultConfig,\n        ...args,\n      });\n    }\n    case 'google': {\n      return await googleSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n        apiUrl: SEARCH_API_URL,\n      });\n    }\n    case 'zhipu': {\n      return await zhipuSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      });\n    }\n    case 'exa': {\n      return await exaSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      });\n    }\n    case 'bocha': {\n      return await bochaSearch({\n        ...searchDefaultConfig,\n        ...args,\n        apiKey: SEARCH_API_KEY,\n      });\n    }\n    default:\n      throw new Error(`Unsupported search provider: ${SEARCH_PROVIDER}`);\n  }\n}\n\nasync function processScrape(url: string, args: Omit<ScrapeInput, 'url'>): Promise<{\n  content: Array<{ type: 'text'; text: string }>;\n  result: any;\n  success: boolean;\n}> {\n  const browser = new AgentBrowser({\n    headless: true,\n    timeout: 30000,\n  });\n\n  try {\n    const res = await browser.scrapeUrl(url, args);\n\n    if (!res.success) {\n      throw new Error(`Failed to scrape: ${res.error}`);\n    }\n\n    const content: string[] = [];\n\n    if (res.markdown) {\n      content.push(res.markdown);\n    }\n\n    if (res.rawHtml) {\n      content.push(res.rawHtml);\n    }\n\n    if (res.links) {\n      content.push(res.links.join('\\n'));\n    }\n\n    if (res.screenshot) {\n      content.push(res.screenshot);\n    }\n\n    if (res.html) {\n      content.push(res.html);\n    }\n\n    return {\n      content: [\n        {\n          type: 'text' as const,\n          text: content.join('\\n\\n') || 'No content found',\n        },\n      ],\n      result: res,\n      success: true,\n    };\n  } finally {\n    await browser.close();\n  }\n}\n\nasync function processMapUrl(url: string, args: Omit<MapInput, 'url'>): Promise<{\n  content: Array<{ type: 'text'; text: string }>;\n  result: string[];\n  success: boolean;\n}> {\n  const browser = new AgentBrowser({\n    headless: true,\n    timeout: 30000,\n  });\n\n  try {\n    const res = await browser.mapUrl(url, args);\n\n    if (!res.success) {\n      throw new Error(`Failed to map: ${res.error}`);\n    }\n\n    if (!res.links) {\n      throw new Error(`No links found from: ${url}`);\n    }\n\n    return {\n      content: [\n        {\n          type: 'text' as const,\n          text: res.links.join('\\n').trim(),\n        },\n      ],\n      result: res.links,\n      success: true,\n    };\n  } finally {\n    await browser.close();\n  }\n}\n\nasync function processExtract(args: ExtractInput): Promise<{\n  content: Array<{ type: 'text'; text: string }>;\n}> {\n  const { urls, prompt, systemPrompt, schema } = args;\n  const browser = new AgentBrowser({\n    headless: true,\n    timeout: 30000,\n  });\n\n  try {\n    const results: string[] = [];\n\n    // Extract content from each URL\n    for (const url of urls) {\n      try {\n        const res = await browser.scrapeUrl(url, {\n          formats: ['markdown'],\n          onlyMainContent: true,\n        });\n\n        if (res.success && res.markdown) {\n          results.push(`## Content from ${url}\\n\\n${res.markdown}`);\n        } else {\n          results.push(`## Failed to extract from ${url}\\n\\nError: ${res.error || 'Unknown error'}`);\n        }\n      } catch (error) {\n        const errorMsg = error instanceof Error ? error.message : String(error);\n        results.push(`## Failed to extract from ${url}\\n\\nError: ${errorMsg}`);\n      }\n    }\n\n    let finalText = results.join('\\n\\n---\\n\\n');\n\n    // Add extraction instructions if provided\n    if (prompt || systemPrompt || schema) {\n      const instructions: string[] = [];\n\n      if (systemPrompt) {\n        instructions.push(`System Instructions: ${systemPrompt}`);\n      }\n\n      if (prompt) {\n        instructions.push(`Extraction Task: ${prompt}`);\n      }\n\n      if (schema) {\n        instructions.push(`Expected Schema:\\n${JSON.stringify(schema, null, 2)}`);\n      }\n\n      finalText = `${instructions.join('\\n\\n')}\\n\\n---\\n\\nExtracted Content:\\n\\n${finalText}`;\n    }\n\n    return {\n      content: [\n        {\n          type: 'text' as const,\n          text: finalText,\n        },\n      ],\n    };\n  } finally {\n    await browser.close();\n  }\n}\n\nasync function runServer(): Promise<void> {\n  try {\n    // Do NOT write to stdout before connecting - it will break MCP protocol\n    const transport = new StdioServerTransport();\n    await server.connect(transport);\n\n    // Now we can send logging messages through MCP protocol\n    await server.sendLoggingMessage({\n      level: 'info',\n      data: 'OneSearch MCP server started',\n    });\n\n  } catch (error) {\n    const msg = error instanceof Error ? error.message : String(error);\n    process.stderr.write(`Error starting server: ${msg}\\n`);\n    process.exit(1);\n  }\n}\n\n// run server\nrunServer().catch((error) => {\n  const msg = error instanceof Error ? error.message : String(error);\n  process.stderr.write(`Error running server: ${msg}\\n`);\n  process.exit(1);\n});\n\n// export types\nexport * from './interface.js';\n","import pino from 'pino';\n\nexport interface Logger {\n  info(message: string, ...args: any[]): void;\n  error(message: string, ...args: any[]): void;\n  success(message: string, ...args: any[]): void;\n  warn(message: string, ...args: any[]): void;\n  log(message: string, ...args: any[]): void;\n}\n\nexport class PinoLogger implements Logger {\n  private logger: pino.Logger;\n\n  constructor(name?: string) {\n    this.logger = pino(\n      {\n        name: name || 'one-search-mcp',\n        level: process.env.LOG_LEVEL || 'info',\n        transport: process.env.NODE_ENV === 'development' ? {\n          target: 'pino-pretty',\n          options: {\n            colorize: true,\n            translateTime: 'SYS:standard',\n            ignore: 'pid,hostname',\n          },\n        } : undefined,\n      },\n      // CRITICAL: Write to stderr, not stdout (MCP protocol requirement)\n      process.stderr,\n    );\n  }\n\n  private logWithLevel(level: 'info' | 'error' | 'warn', message: string, ...args: any[]): void {\n    if (args.length > 0) {\n      this.logger[level]({ data: args }, message);\n    } else {\n      this.logger[level](message);\n    }\n  }\n\n  info(message: string, ...args: any[]): void {\n    this.logWithLevel('info', message, ...args);\n  }\n\n  error(message: string, ...args: any[]): void {\n    this.logWithLevel('error', message, ...args);\n  }\n\n  success(message: string, ...args: any[]): void {\n    if (args.length > 0) {\n      this.logger.info({ level: 'success', data: args }, message);\n    } else {\n      this.logger.info({ level: 'success' }, message);\n    }\n  }\n\n  warn(message: string, ...args: any[]): void {\n    this.logWithLevel('warn', message, ...args);\n  }\n\n  log(message: string, ...args: any[]): void {\n    this.logWithLevel('info', message, ...args);\n  }\n}\n\nexport const defaultLogger = new PinoLogger();\n","/**\n * Shared logger for search providers\n */\n\nimport { PinoLogger } from '../libs/logger/index.js';\n\nexport const searchLogger = new PinoLogger('search');\n","/**\n * Bing Search API\n * @reference https://learn.microsoft.com/en-us/previous-versions/bing/search-apis/bing-web-search/create-bing-search-service-resource\n */\nimport { ISearchRequestOptions, ISearchResponse } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst DEFAULT_TIMEOUT = 20000;\n\n\n/**\n * Options for performing a Bing search\n */\nexport interface BingSearchOptions {\n  /**\n   * Search query string\n   */\n  q: string;\n\n  /**\n   * Number of results to return\n   */\n  count?: number;\n\n  /**\n   * Result offset for pagination\n   */\n  offset?: number;\n\n  /**\n   * Market code (e.g., 'en-US')\n   */\n  mkt?: string;\n\n  /**\n   * Safe search filtering level\n   */\n  safeSearch?: 'Off' | 'Moderate' | 'Strict';\n\n  /**\n   * Bing API key\n   */\n  apiKey: string;\n\n  /**\n   * Bing Search API URL\n   */\n  apiUrl?: string;\n\n  /**\n   * Additional parameters supported by Bing Search API\n   */\n  [key: string]: any;\n}\n\n/**\n * Represents a web page result from Bing Search\n */\nexport interface BingSearchWebPage {\n  /**\n   * Title of the web page\n   */\n  name: string;\n\n  /**\n   * URL of the web page\n   */\n  url: string;\n\n  /**\n   * Text snippet from the web page\n   */\n  snippet: string;\n\n  /**\n   * Date the page was last crawled by Bing\n   */\n  dateLastCrawled?: string;\n\n  /**\n   * Display URL for the web page\n   */\n  displayUrl?: string;\n\n  /**\n   * Unique identifier for the result\n   */\n  id?: string;\n\n  /**\n   * Indicates if the content is family friendly\n   */\n  isFamilyFriendly?: boolean;\n\n  /**\n   * Indicates if the result is navigational\n   */\n  isNavigational?: boolean;\n\n  /**\n   * Language of the web page\n   */\n  language?: string;\n\n  /**\n   * Indicates if caching should be disabled\n   */\n  noCache?: boolean;\n\n  /**\n   * Name of the website\n   */\n  siteName?: string;\n\n  /**\n   * URL to a thumbnail image\n   */\n  thumbnailUrl?: string;\n}\n\n/**\n * Represents an image result from Bing Search\n */\nexport interface BingSearchImage {\n  contentSize: string;\n  contentUrl: string;\n  datePublished: string;\n  encodingFormat: string;\n  height: number;\n  width: number;\n  hostPageDisplayUrl: string;\n  hostPageUrl: string;\n  name: string;\n  thumbnail: {\n    height: number;\n    width: number;\n  };\n  thumbnailUrl: string;\n  webSearchUrl: string;\n}\n\n/**\n * Represents a video result from Bing Search\n */\nexport interface BingSearchVideo {\n  allowHttpsEmbed: boolean;\n  allowMobileEmbed: boolean;\n  contentUrl: string;\n  creator?: {\n    name: string;\n  };\n  datePublished: string;\n  description: string;\n  duration: string;\n  embedHtml: string;\n  encodingFormat: string;\n  height: number;\n  width: number;\n  hostPageDisplayUrl: string;\n  hostPageUrl: string;\n  name: string;\n  publisher?: {\n    name: string;\n  }[];\n  thumbnail: {\n    height: number;\n    width: number;\n  };\n  thumbnailUrl: string;\n  viewCount?: number;\n  webSearchUrl: string;\n}\n\nexport interface BingSearchResponse {\n  _type?: string;\n  queryContext?: {\n    originalQuery: string;\n  };\n  webPages?: {\n    value: BingSearchWebPage[];\n    totalEstimatedMatches?: number;\n    someResultsRemoved?: boolean;\n    webSearchUrl?: string;\n  };\n  images?: {\n    value: BingSearchImage[];\n    isFamilyFriendly?: boolean;\n    readLink?: string;\n    webSearchUrl?: string;\n    id?: string;\n  };\n  videos?: {\n    value: BingSearchVideo[];\n    isFamilyFriendly?: boolean;\n    readLink?: string;\n    webSearchUrl?: string;\n    id?: string;\n    scenario?: string;\n  };\n  rankingResponse?: {\n    mainline?: {\n      items: {\n        answerType: string;\n        resultIndex?: number;\n        value: {\n          id: string;\n        };\n      }[];\n    };\n  };\n  [key: string]: any; // Allow other response fields\n}\n\nexport async function bingSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, limit = 10, safeSearch = 0, page = 1, apiUrl = 'https://api.bing.microsoft.com/v7.0/search', apiKey, language } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey) {\n    throw new Error('Bing API key is required');\n  }\n\n  const bingSafeSearchOptions = ['Off', 'Moderate', 'Strict'];\n\n  const searchOptions = {\n    q: query,\n    count: limit,\n    offset: (page - 1) * limit,\n    mkt: language,\n    safeSearch: bingSafeSearchOptions[safeSearch] as 'Off' | 'Moderate' | 'Strict',\n  };\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);\n\n  try {\n    const queryParams = new URLSearchParams();\n    Object.entries(searchOptions).forEach(([key, value]) => {\n      if (value !== undefined) {\n        queryParams.set(key, value.toString());\n      }\n    });\n\n    const res = await fetch(`${apiUrl}?${queryParams}`, {\n      method: 'GET',\n      headers: {\n        'Content-Type': 'application/json',\n        'Ocp-Apim-Subscription-Key': apiKey,\n      },\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!res.ok) {\n      throw new Error(`Bing search error: ${res.status} ${res.statusText}`);\n    }\n\n    const data = await res.json();\n    const serp = data.webPages?.value as Array<BingSearchWebPage>;\n    const results = serp?.map((item: BingSearchWebPage) => ({\n      title: item.name,\n      snippet: item.snippet,\n      url: item.url,\n      source: item.siteName,\n      thumbnailUrl: item.thumbnailUrl,\n      language: item.language,\n      image: null,\n      video: null,\n      engine: 'bing',\n    })) ?? [];\n\n    return {\n      results,\n      success: true,\n    };\n  } catch (err: unknown) {\n    clearTimeout(timeoutId);\n    const msg = err instanceof Error ? err.message : 'Bing search error.';\n    searchLogger.error(msg);\n    throw err;\n  }\n}","import * as DDG from 'duck-duck-scrape';\nimport asyncRetry from 'async-retry';\nimport type { SearchOptions } from 'duck-duck-scrape';\nimport { ISearchRequestOptions, ISearchResponse } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nexport async function duckDuckGoSearch(options: Omit<ISearchRequestOptions, 'safeSearch'> & SearchOptions): Promise<ISearchResponse> {\n  const { query, timeout = 10000, safeSearch = DDG.SafeSearchType.OFF, retry = { retries: 3 }, ...searchOptions } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  try {\n    const res = await asyncRetry(\n      () => {\n        return DDG.search(query, {\n          ...searchOptions,\n          safeSearch,\n        }, {\n          // needle options\n          response_timeout: timeout,\n        });\n      },\n      retry,\n    );\n\n    const results = res ? {\n      noResults: res.noResults,\n      vqd: res.vqd,\n      results: res.results,\n    } : {\n      noResults: true,\n      vqd: '',\n      results: [],\n    };\n\n    return {\n      results: results.results.map((result) => ({\n        title: result.title,\n        snippet: result.description,\n        url: result.url,\n        source: result.hostname,\n        image: null,\n        video: null,\n        engine: 'duckduckgo',\n      })),\n      success: true,\n    };\n  } catch (error) {\n    const msg = error instanceof Error ? error.message : 'DuckDuckGo search error.';\n    searchLogger.error(msg);\n    throw error;\n  }\n}\n","import url from 'node:url';\nimport { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\n/**\n * SearxNG Search API\n * @reference https://docs.searxng.org/dev/search_api.html\n */\nexport async function searxngSearch(params: ISearchRequestOptions): Promise<ISearchResponse> {\n  const {\n    query,\n    page = 1,\n    limit = 10,\n    categories = 'general',\n    engines = 'all',\n    safeSearch = 0,\n    format = 'json',\n    language = 'auto',\n    timeRange = '',\n    timeout = 10000,\n    apiKey,\n    apiUrl,\n  } = params;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiUrl) {\n    throw new Error('SearxNG API URL is required');\n  }\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), Number(timeout));\n\n  try {\n    const config = {\n      q: query,\n      pageno: page,\n      categories,\n      format,\n      safesearch: safeSearch,\n      language,\n      engines,\n      time_range: timeRange,\n    };\n\n    const endpoint = `${apiUrl}/search`;\n\n    const queryParams = url.format({ query: config });\n\n    const headers: HeadersInit = {\n      'Content-Type': 'application/json',\n    };\n\n    if (apiKey) {\n      headers['Authorization'] = `Bearer ${apiKey}`;\n    }\n\n    const res = await fetch(`${endpoint}${queryParams}`, {\n      method: 'POST',\n      headers,\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n    const response = await res.json();\n    if (response.results) {\n      const list = (response.results as Array<Record<string, any>>).slice(0, limit);\n      const results: ISearchResponseResult[] = list.map((item: Record<string, any>) => {\n        const image = item.img_src ? {\n          thumbnail: item.thumbnail_src,\n          src: item.img_src,\n        } : null;\n        const video = item.iframe_src ? {\n          thumbnail: item.thumbnail_src,\n          src: item.iframe_src,\n        } : null;\n        return {\n          title: item.title,\n          snippet: item.content,\n          url: item.url,\n          source: item.source,\n          image,\n          video,\n          engine: item.engine,\n        };\n      });\n      return {\n        results,\n        success: true,\n      };\n    }\n    return {\n      results: [],\n      success: false,\n    };\n  } catch (err: unknown) {\n    clearTimeout(timeoutId);\n    const msg = err instanceof Error ? err.message : 'Searxng search error.';\n    searchLogger.error(msg);\n    throw err;\n  }\n}\n","/**\n * Tavily Search API\n * @reference https://docs.tavily.com/documentation/quickstart\n */\nimport { tavily, TavilySearchOptions } from '@tavily/core';\nimport { ISearchRequestOptions, ISearchResponse } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst DEFAULT_TIMEOUT = 20000;\n\nexport async function tavilySearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const {\n    query,\n    limit = 10,\n    categories = 'general',\n    timeRange,\n    apiKey,\n  } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey) {\n    throw new Error('Tavily API key is required');\n  }\n\n  let timeoutId: NodeJS.Timeout | undefined;\n\n  try {\n    const tvly = tavily({\n      apiKey,\n    });\n\n    const params: TavilySearchOptions = {\n      topic: categories as TavilySearchOptions['topic'],\n      timeRange: timeRange as TavilySearchOptions['timeRange'],\n      maxResults: limit,\n    };\n\n    const res = await Promise.race([\n      tvly.search(query, params),\n      new Promise<never>((_, reject) => {\n        timeoutId = setTimeout(() => reject(new Error('Tavily search timeout')), DEFAULT_TIMEOUT);\n      }),\n    ]);\n\n    clearTimeout(timeoutId);\n\n    const results = res.results.map(item => ({\n      title: item.title,\n      url: item.url,\n      snippet: item.content,\n      engine: 'tavily',\n    }));\n\n    return {\n      results,\n      success: true,\n    };\n  } catch (error) {\n    clearTimeout(timeoutId);\n    const msg = error instanceof Error ? error.message : 'Tavily search error.';\n    searchLogger.error(msg);\n    throw error;\n  }\n}\n","import { BrowserManager } from 'agent-browser/dist/browser.js';\nimport type { Page } from 'playwright-core';\nimport TurndownService from 'turndown';\nimport { gfm } from 'turndown-plugin-gfm';\nimport * as cheerio from 'cheerio';\nimport { BrowserFinder } from '../browser/finder.js';\nimport { defaultLogger } from '../logger/index.js';\nimport { BROWSER_CONFIG } from './config.js';\nimport type {\n  AgentBrowserOptions,\n  ScrapeResult,\n  ScrapeOptions,\n  MapResult,\n  MapOptions,\n  SearchResult,\n  SearchEngine,\n  SearchOptions,\n} from './types.js';\n\nexport class AgentBrowser {\n  private browser: BrowserManager;\n  private turndown: TurndownService;\n  private browserPath?: string;\n\n  constructor(private options: AgentBrowserOptions = {}) {\n    this.browser = new BrowserManager();\n\n    // Try to find local browser installation\n    try {\n      const finder = new BrowserFinder();\n      const { executable } = finder.findBrowser();\n      this.browserPath = executable;\n    } catch (error) {\n      // If no local browser found, agent-browser will try to use Playwright's Chromium\n      this.browserPath = undefined;\n    }\n\n    // Initialize Turndown for HTML to Markdown conversion\n    this.turndown = new TurndownService({\n      headingStyle: 'atx',\n      codeBlockStyle: 'fenced',\n    });\n    this.turndown.use(gfm);\n  }\n\n  /**\n   * Ensure browser is launched\n   */\n  private async ensureLaunched(): Promise<void> {\n    if (!this.browser.isLaunched()) {\n      try {\n        await this.browser.launch({\n          id: `session-${Date.now()}`,\n          action: 'launch',\n          headless: this.options.headless ?? true,\n          executablePath: this.browserPath,\n        });\n      } catch (error) {\n        const errorMessage = error instanceof Error ? error.message : String(error);\n\n        // Check if this is a browser not installed error\n        if (errorMessage.includes('Executable') || errorMessage.includes('browser')) {\n          throw new Error(\n            'Browser not found. Please install one of the following:\\n' +\n            '  - Google Chrome: https://www.google.com/chrome/\\n' +\n            '  - Microsoft Edge: https://www.microsoft.com/edge\\n' +\n            '  - Chromium: https://www.chromium.org/getting-involved/download-chromium/\\n' +\n            'Or install via Playwright:\\n' +\n            '  npx playwright install chromium\\n' +\n            `Original error: ${errorMessage}`,\n          );\n        }\n\n        throw error;\n      }\n    }\n  }\n\n  /**\n   * Get current page\n   */\n  private async getPage(): Promise<Page> {\n    await this.ensureLaunched();\n    return this.browser.getPage();\n  }\n\n  /**\n   * Navigate to URL\n   */\n  async navigate(url: string): Promise<void> {\n    const page = await this.getPage();\n    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: this.options.timeout });\n  }\n\n  /**\n   * Get page HTML\n   */\n  async getHtml(): Promise<string> {\n    const page = await this.getPage();\n    return await page.content();\n  }\n\n  /**\n   * Get page text\n   */\n  async getText(): Promise<string> {\n    const page = await this.getPage();\n    return await page.evaluate(() => document.body.innerText);\n  }\n\n  /**\n   * Take screenshot\n   */\n  async screenshot(): Promise<string> {\n    const page = await this.getPage();\n    const screenshot = await page.screenshot({\n      type: 'png',\n      fullPage: false,\n    });\n    return `data:image/png;base64,${screenshot.toString('base64')}`;\n  }\n\n  /**\n   * Wait for time\n   */\n  async wait(ms: number): Promise<void> {\n    await new Promise((resolve) => setTimeout(resolve, ms));\n  }\n\n  /**\n   * Close browser\n   */\n  async close(): Promise<void> {\n    if (this.browser.isLaunched()) {\n      await this.browser.close();\n    }\n  }\n\n  /**\n   * Scrape a URL and extract content\n   */\n  async scrapeUrl(url: string, options: ScrapeOptions = {}): Promise<ScrapeResult> {\n    try {\n      await this.navigate(url);\n\n      // Wait for page load\n      if (options.waitFor) {\n        await this.wait(options.waitFor);\n      } else {\n        await this.wait(BROWSER_CONFIG.DEFAULT_WAIT_MS);\n      }\n\n      const result: ScrapeResult = { success: true };\n      const formats = options.formats || ['markdown'];\n\n      // Get HTML\n      const html = await this.getHtml();\n\n      if (formats.includes('markdown')) {\n        result.markdown = this.turndown.turndown(html);\n      }\n\n      if (formats.includes('html') || formats.includes('rawHtml')) {\n        result.html = html;\n        result.rawHtml = html;\n      }\n\n      if (formats.includes('links')) {\n        result.links = this.extractLinks(html, url);\n      }\n\n      if (formats.includes('screenshot') || formats.includes('screenshot@fullPage')) {\n        result.screenshot = await this.screenshot();\n      }\n\n      return result;\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Map URLs from a starting URL\n   */\n  async mapUrl(url: string, options: MapOptions = {}): Promise<MapResult> {\n    try {\n      await this.navigate(url);\n      await this.wait(BROWSER_CONFIG.DEFAULT_WAIT_MS);\n\n      const html = await this.getHtml();\n      let links = this.extractLinks(html, url);\n\n      // Filter links\n      if (options.search) {\n        links = links.filter((link) =>\n          link.toLowerCase().includes(options.search!.toLowerCase()),\n        );\n      }\n\n      if (!options.includeSubdomains) {\n        const baseHost = new URL(url).hostname;\n        links = links.filter((link) => {\n          try {\n            return new URL(link).hostname === baseHost;\n          } catch {\n            return false;\n          }\n        });\n      }\n\n      if (options.limit) {\n        links = links.slice(0, options.limit);\n      }\n\n      return {\n        success: true,\n        links,\n      };\n    } catch (error) {\n      return {\n        success: false,\n        error: error instanceof Error ? error.message : String(error),\n      };\n    }\n  }\n\n  /**\n   * Search using a search engine\n   */\n  async search(options: SearchOptions): Promise<SearchResult[]> {\n    const { query, engine, limit = 10 } = options;\n    const searchUrl = this.getSearchUrl(engine, query);\n\n    await this.navigate(searchUrl);\n    await this.wait(BROWSER_CONFIG.SEARCH_WAIT_MS);\n\n    const html = await this.getHtml();\n    const results = this.extractSearchResults(engine, html);\n\n    return results.slice(0, limit);\n  }\n\n  /**\n   * Get search URL for different engines\n   */\n  private getSearchUrl(engine: SearchEngine, query: string): string {\n    const encodedQuery = encodeURIComponent(query);\n    switch (engine) {\n      case 'google':\n        return `https://www.google.com/search?q=${encodedQuery}`;\n      case 'bing':\n        return `https://www.bing.com/search?q=${encodedQuery}`;\n      case 'baidu':\n        return `https://www.baidu.com/s?wd=${encodedQuery}`;\n      case 'sogou':\n        return `https://www.sogou.com/web?query=${encodedQuery}`;\n      default:\n        throw new Error(`Unsupported search engine: ${engine}`);\n    }\n  }\n\n  /**\n   * Extract search results from HTML\n   */\n  private extractSearchResults(engine: SearchEngine, html: string): SearchResult[] {\n    try {\n      switch (engine) {\n        case 'google':\n          return this.extractGoogleResults(html);\n        case 'bing':\n          return this.extractBingResults(html);\n        case 'baidu':\n          return this.extractBaiduResults(html);\n        case 'sogou':\n          return this.extractSogouResults(html);\n        default:\n          return [];\n      }\n    } catch (error) {\n      const errorMessage = error instanceof Error ? error.message : String(error);\n      defaultLogger.warn(`Failed to extract ${engine} search results: ${errorMessage}`);\n      return [];\n    }\n  }\n\n  /**\n   * Extract Google search results using cheerio\n   */\n  private extractGoogleResults(html: string): SearchResult[] {\n    const $ = cheerio.load(html);\n    const results: SearchResult[] = [];\n\n    // Google uses div.g for search results\n    $('div.g').each((_, element) => {\n      const $el = $(element);\n      const $link = $el.find('a[href]').first();\n      const $title = $el.find('h3').first();\n      const $snippet = $el.find('div.VwiC3b, div[data-sncf]').first();\n\n      const url = $link.attr('href');\n      const title = $title.text().trim();\n      const snippet = $snippet.text().trim();\n\n      if (url && title && !url.startsWith('/search')) {\n        results.push({ title, url, snippet });\n      }\n    });\n\n    return results;\n  }\n\n  /**\n   * Extract Bing search results using cheerio\n   */\n  private extractBingResults(html: string): SearchResult[] {\n    const $ = cheerio.load(html);\n    const results: SearchResult[] = [];\n\n    // Bing uses li.b_algo for search results\n    $('li.b_algo').each((_, element) => {\n      const $el = $(element);\n      const $link = $el.find('h2 a').first();\n      const $snippet = $el.find('p, div.b_caption p').first();\n\n      const url = $link.attr('href');\n      const title = $link.text().trim();\n      const snippet = $snippet.text().trim();\n\n      if (url && title) {\n        results.push({ title, url, snippet });\n      }\n    });\n\n    return results;\n  }\n\n  /**\n   * Extract Baidu search results using cheerio\n   */\n  private extractBaiduResults(html: string): SearchResult[] {\n    const $ = cheerio.load(html);\n    const results: SearchResult[] = [];\n\n    // Baidu uses div.result for search results\n    $('div.result').each((_, element) => {\n      const $el = $(element);\n      const $link = $el.find('h3 a').first();\n      const $snippet = $el.find('div.c-abstract, div[class*=\"abstract\"]').first();\n\n      const url = $link.attr('href');\n      const title = $link.text().trim();\n      const snippet = $snippet.text().trim();\n\n      if (url && title) {\n        results.push({ title, url, snippet });\n      }\n    });\n\n    return results;\n  }\n\n  /**\n   * Extract Sogou search results using cheerio\n   */\n  private extractSogouResults(html: string): SearchResult[] {\n    const $ = cheerio.load(html);\n    const results: SearchResult[] = [];\n\n    // Sogou uses div.vrwrap for search results\n    $('div.vrwrap').each((_, element) => {\n      const $el = $(element);\n      const $link = $el.find('h3 a').first();\n      const $snippet = $el.find('p.str-text, p[class*=\"text\"]').first();\n\n      const url = $link.attr('href');\n      const title = $link.text().trim();\n      const snippet = $snippet.text().trim();\n\n      if (url && title) {\n        results.push({ title, url, snippet });\n      }\n    });\n\n    return results;\n  }\n\n  /**\n   * Extract links from HTML\n   */\n  private extractLinks(html: string, baseUrl: string): string[] {\n    const linkRegex = /<a[^>]+href=[\"']([^\"']+)[\"']/gi;\n    const links: string[] = [];\n    let match;\n\n    while ((match = linkRegex.exec(html)) !== null) {\n      try {\n        const link = new URL(match[1], baseUrl).href;\n        if (!links.includes(link)) {\n          links.push(link);\n        }\n      } catch {\n        // Ignore invalid links\n      }\n    }\n\n    return links;\n  }\n\n}\n\nexport * from './types.js';\nexport * from './config.js';\n","/**\n * The following code is modified based on\n * https://github.com/egoist/local-web-search/blob/main/src/find-browser.ts\n * Copy from\n * https://github.com/bytedance/UI-TARS-desktop/blob/main/packages/agent-infra/browser/src/browser-finder.ts\n *\n * MIT Licensed\n * Copyright (c) 2025 ChatWise (https://chatwise.app) <kevin@chatwise.app>\n * https://github.com/egoist/local-web-search/blob/main/LICENSE\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { Logger, defaultLogger } from '../logger/index.js';\n\n/**\n * Interface defining browser locations and configurations\n * Contains paths and settings for different operating systems\n * @interface Browser\n */\ninterface Browser {\n  /**\n   * Browser name identifier\n   */\n  name: string;\n\n  /**\n   * Executable paths by platform\n   * @property {string} win32 - Windows executable path\n   * @property {string} darwin - macOS executable path\n   * @property {string} linux - Linux executable path\n   */\n  executable: {\n    win32: string;\n    darwin: string;\n    linux: string;\n  };\n\n  /**\n   * User data directory paths by platform\n   * @property {string} win32 - Windows user data directory\n   * @property {string} darwin - macOS user data directory\n   * @property {string} linux - Linux user data directory\n   */\n  userDataDir: {\n    win32: string;\n    darwin: string;\n    linux: string;\n  };\n}\n\n/**\n * Class responsible for finding and managing browser installations\n * Detects installed browsers and their profiles across different platforms\n */\nexport class BrowserFinder {\n  /**\n   * Logger instance for diagnostic output\n   */\n  private logger: Logger;\n\n  /**\n   * Creates a new BrowserFinder instance\n   * @param {Logger} [logger] - Optional custom logger\n   */\n  constructor(logger?: Logger) {\n    this.logger = logger ?? defaultLogger;\n  }\n\n  /**\n   * Getter that returns the list of supported browsers with their platform-specific paths\n   * @returns {Browser[]} Array of browser configurations\n   * @private\n   */\n  private get browsers(): Browser[] {\n    // Get HOME_DIR inside the getter to ensure it's always current\n    const HOME_DIR = os.homedir();\n    const LOCAL_APP_DATA = process.env.LOCALAPPDATA;\n\n    return [\n      {\n        name: 'Chromium',\n        executable: {\n          win32: 'C:\\\\Program Files\\\\Chromium\\\\Application\\\\chrome.exe',\n          darwin: '/Applications/Chromium.app/Contents/MacOS/Chromium',\n          linux: '/usr/bin/chromium',\n        },\n        userDataDir: {\n          win32: `${LOCAL_APP_DATA}\\\\Chromium\\\\User Data`,\n          darwin: `${HOME_DIR}/Library/Application Support/Chromium`,\n          linux: `${HOME_DIR}/.config/chromium`,\n        },\n      },\n      {\n        name: 'Google Chrome',\n        executable: {\n          win32: 'C:\\\\Program Files\\\\Google\\\\Chrome\\\\Application\\\\chrome.exe',\n          darwin:\n            '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n          linux: '/usr/bin/google-chrome',\n        },\n        userDataDir: {\n          win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome\\\\User Data`,\n          darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome`,\n          linux: `${HOME_DIR}/.config/google-chrome`,\n        },\n      },\n      {\n        name: 'Google Chrome Canary',\n        executable: {\n          win32:\n            'C:\\\\Program Files\\\\Google\\\\Chrome Canary\\\\Application\\\\chrome.exe',\n          darwin:\n            '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',\n          linux: '/usr/bin/google-chrome-canary',\n        },\n        userDataDir: {\n          win32: `${LOCAL_APP_DATA}\\\\Google\\\\Chrome Canary\\\\User Data`,\n          darwin: `${HOME_DIR}/Library/Application Support/Google/Chrome Canary`,\n          linux: `${HOME_DIR}/.config/google-chrome-canary`,\n        },\n      },\n      {\n        name: 'Microsoft Edge',\n        executable: {\n          win32: 'C:\\\\Program Files (x86)\\\\Microsoft\\\\Edge\\\\Application\\\\msedge.exe',\n          darwin: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',\n          linux: '/usr/bin/microsoft-edge',\n        },\n        userDataDir: {\n          win32: `${LOCAL_APP_DATA}\\\\Microsoft\\\\Edge\\\\User Data`,\n          darwin: `${HOME_DIR}/Library/Application Support/Microsoft Edge`,\n          linux: `${HOME_DIR}/.config/microsoft-edge`,\n        },\n      },\n    ];\n  }\n\n  /**\n   * Find a specific browser or the first available browser\n   * @param {string} [name] - Optional browser name to find\n   * @returns {{ executable: string; userDataDir: string }} Browser executable and user data paths\n   * @throws {Error} If no supported browser is found or the platform is unsupported\n   */\n  findBrowser(name?: string): {\n    executable: string;\n    userDataDir: string;\n  } {\n    const platform = process.platform;\n    this.logger.info('Finding browser on platform:', platform);\n\n    if (platform !== 'darwin' && platform !== 'win32' && platform !== 'linux') {\n      const error = new Error(`Unsupported platform: ${platform}`);\n      this.logger.error(error.message);\n      throw error;\n    }\n\n    const browser = name\n      ? this.browsers.find(\n        (b) => b.name === name && fs.existsSync(b.executable[platform]),\n      )\n      : this.browsers.find((b) => fs.existsSync(b.executable[platform]));\n\n    this.logger.log('browser', browser);\n\n    if (!browser) {\n      const error = name\n        ? new Error(`Cannot find browser: ${name}`)\n        : new Error(\n          'Cannot find a supported browser on your system. Please install Chrome, Chromium, Edge, or Brave.',\n        );\n      this.logger.error(error.message);\n      throw error;\n    }\n\n    const result = {\n      executable: browser.executable[platform],\n      userDataDir: browser.userDataDir[platform],\n    };\n\n    this.logger.success(`Found browser: ${browser.name}`);\n    this.logger.info('Browser details:', result);\n\n    return result;\n  }\n\n  /**\n   * Get browser profiles for a specific browser\n   * Reads the Local State file to extract profile information\n   * @param {string} [browserName] - Optional browser name to get profiles for\n   * @returns {Array<{ displayName: string; path: string }>} Array of profile objects with display names and paths\n   */\n  getBrowserProfiles(\n    browserName?: string,\n  ): Array<{ displayName: string; path: string }> {\n    const browser = this.findBrowser(browserName);\n\n    try {\n      const localState = JSON.parse(\n        fs.readFileSync(path.join(browser.userDataDir, 'Local State'), 'utf8'),\n      );\n      const profileInfo = localState.profile.info_cache;\n\n      return Object.entries(profileInfo).map(\n        ([profileName, info]: [string, any]) => ({\n          displayName: info.name,\n          path: path.join(browser.userDataDir, profileName),\n        }),\n      );\n    } catch (error) {\n      return [];\n    }\n  }\n\n  /**\n   * Legacy method for backwards compatibility\n   * Finds Chrome browser executable path\n   * @deprecated Use findBrowser instead\n   * @returns {string | null} Chrome executable path or null if not found\n   */\n  findChrome(): string | null {\n    try {\n      const { executable } = this.findBrowser('Google Chrome');\n      return executable;\n    } catch {\n      return null;\n    }\n  }\n}\n","/**\n * Configuration constants for agent-browser\n */\nexport const BROWSER_CONFIG = {\n  /** Default wait time after page load (ms) */\n  DEFAULT_WAIT_MS: 2000,\n\n  /** Wait time for search results to load (ms) */\n  SEARCH_WAIT_MS: 3000,\n\n  /** Default browser timeout (ms) */\n  DEFAULT_TIMEOUT: 30000,\n\n  /** Run browser in headless mode by default */\n  DEFAULT_HEADLESS: true,\n} as const;\n\n/**\n * Valid search engines\n */\nexport const VALID_SEARCH_ENGINES = ['bing', 'google', 'baidu', 'sogou'] as const;\n","import { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { AgentBrowser, type SearchEngine, VALID_SEARCH_ENGINES } from '../libs/agent-browser/index.js';\nimport { PinoLogger } from '../libs/logger/index.js';\n\nconst logger = new PinoLogger('[LocalSearch]');\n\n/**\n * Validate if a string is a valid search engine\n */\nfunction isValidEngine(engine: string): engine is SearchEngine {\n  return VALID_SEARCH_ENGINES.includes(engine as SearchEngine);\n}\n\n/**\n * Convert SearchResult to ISearchResponseResult\n */\nfunction toSearchResponseResult(result: { title: string; url: string; snippet: string; content?: string }, engine: string): ISearchResponseResult {\n  return {\n    title: result.title,\n    snippet: result.snippet,\n    url: result.url,\n    markdown: result.content,\n    engine,\n  };\n}\n\nexport async function localSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, limit = 10 } = options;\n  let { engines = 'all' } = options;\n\n  if (engines === 'all') {\n    engines = 'bing,google,baidu,sogou';\n  }\n\n  const engineList = engines.split(',').map(e => e.trim()).filter(Boolean);\n\n  if (engineList.length === 0) {\n    throw new Error('engines is required');\n  }\n\n  // Validate engines\n  const validEngines = engineList.filter(isValidEngine);\n  const invalidEngines = engineList.filter(e => !isValidEngine(e));\n\n  if (invalidEngines.length > 0) {\n    logger.warn(`Invalid search engines ignored: ${invalidEngines.join(', ')}`);\n  }\n\n  if (validEngines.length === 0) {\n    throw new Error(`No valid search engines provided. Valid engines: ${VALID_SEARCH_ENGINES.join(', ')}`);\n  }\n\n  const browser = new AgentBrowser({\n    headless: true,\n    timeout: 30000,\n  });\n\n  try {\n    const results: ISearchResponseResult[] = [];\n\n    for (const engine of validEngines) {\n      try {\n        logger.info(`Searching with engine: ${engine}`);\n        const searchResults = await browser.search({\n          query,\n          engine,\n          limit,\n        });\n\n        if (searchResults.length > 0) {\n          // Convert SearchResult to ISearchResponseResult\n          const converted = searchResults.map(r => toSearchResponseResult(r, engine));\n          results.push(...converted);\n          logger.info(`Found ${searchResults.length} results from ${engine}`);\n          break; // Use first successful engine\n        }\n      } catch (err) {\n        logger.error(`Failed to search with ${engine}:`, err);\n        // Continue to next engine\n      }\n    }\n\n    logger.info(`Total results found: ${results.length}`);\n\n    return {\n      results,\n      success: true,\n    };\n  } catch (err: unknown) {\n    const msg = err instanceof Error ? err.message : 'Local search error.';\n    logger.error(msg, err);\n    throw err;\n  } finally {\n    await browser.close();\n  }\n}\n","/**\n * Google Custom Search API\n * @reference https://developers.google.com/custom-search/v1/overview\n */\n\nimport { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst GOOGLE_SEARCH_ENDPOINT = 'https://www.googleapis.com/customsearch/v1';\nconst DEFAULT_TIMEOUT = 20000;\n\ninterface GoogleSearchItem {\n  title: string;\n  link: string;\n  snippet: string;\n  displayLink?: string;\n  formattedUrl?: string;\n  pagemap?: {\n    cse_thumbnail?: Array<{ src: string }>;\n  };\n}\n\ninterface GoogleSearchResponse {\n  items?: GoogleSearchItem[];\n  error?: {\n    message: string;\n  };\n}\n\nexport async function googleSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, apiKey, apiUrl, limit = 10, language } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey || !apiUrl) {\n    throw new Error('Google search requires SEARCH_API_KEY and SEARCH_API_URL (Search Engine ID)');\n  }\n\n  const params = new URLSearchParams({\n    key: apiKey,\n    cx: apiUrl,\n    q: query,\n    num: String(Math.min(limit, 10)),\n  });\n\n  if (language && language !== 'auto') {\n    params.set('lr', `lang_${language}`);\n  }\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);\n\n  try {\n    const response = await fetch(`${GOOGLE_SEARCH_ENDPOINT}?${params}`, {\n      method: 'GET',\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!response.ok) {\n      throw new Error(`Google search failed: ${response.status} ${response.statusText}`);\n    }\n\n    const data: GoogleSearchResponse = await response.json();\n\n    if (data.error) {\n      throw new Error(`Google API error: ${data.error.message}`);\n    }\n\n    const items = data.items ?? [];\n    const results: ISearchResponseResult[] = items.map((item) => ({\n      title: item.title,\n      url: item.link,\n      snippet: item.snippet || '',\n      source: item.displayLink,\n      thumbnailUrl: item.pagemap?.cse_thumbnail?.[0]?.src,\n      engine: 'google',\n    }));\n\n    return { results, success: true };\n  } catch (error) {\n    clearTimeout(timeoutId);\n    const msg = error instanceof Error ? error.message : 'Google search error.';\n    searchLogger.error(msg);\n    throw error;\n  }\n}\n","/**\n * 智谱搜索接口\n * @reference https://bigmodel.cn/dev/api/search-tool/web-search\n */\n\nimport { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst ZHIPU_SEARCH_ENDPOINT = 'https://open.bigmodel.cn/api/paas/v4/web_search';\nconst DEFAULT_TIMEOUT = 20000;\n\nexport type ZhipuSearchEngine =\n  | 'search_std'\n  | 'search_pro'\n  | 'search_pro_sogou'\n  | 'search_pro_quark'\n  | 'search_pro_jina'\n  | 'search_pro_bing';\n\ninterface ZhipuWebSearchItem {\n  icon: string;\n  title: string;\n  link: string;\n  content: string;\n  media: string;\n  refer: string;\n  publish_date: string;\n}\n\ninterface ZhipuSearchResponse {\n  search_result?: ZhipuWebSearchItem[];\n  search_intent?: Record<string, unknown>;\n}\n\nexport async function zhipuSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, apiKey, limit = 10, engines } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey) {\n    throw new Error('Zhipu search requires SEARCH_API_KEY');\n  }\n\n  const validEngines: ZhipuSearchEngine[] = [\n    'search_std',\n    'search_pro',\n    'search_pro_sogou',\n    'search_pro_quark',\n    'search_pro_jina',\n    'search_pro_bing',\n  ];\n  const searchEngine: ZhipuSearchEngine = validEngines.includes(engines as ZhipuSearchEngine)\n    ? (engines as ZhipuSearchEngine)\n    : 'search_std';\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);\n\n  try {\n    const response = await fetch(ZHIPU_SEARCH_ENDPOINT, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${apiKey}`,\n      },\n      body: JSON.stringify({\n        search_engine: searchEngine,\n        search_query: query,\n        search_intent: false,\n        count: limit,\n      }),\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!response.ok) {\n      throw new Error(`Zhipu search failed: ${response.status} ${response.statusText}`);\n    }\n\n    const data: ZhipuSearchResponse = await response.json();\n    const items = data.search_result ?? [];\n\n    const results: ISearchResponseResult[] = items.map((item) => ({\n      title: item.title,\n      url: item.link,\n      snippet: item.content,\n      source: item.media,\n      engine: 'zhipu',\n    }));\n\n    return { results, success: true };\n  } catch (err: unknown) {\n    clearTimeout(timeoutId);\n    const msg = err instanceof Error ? err.message : 'Zhipu search error.';\n    searchLogger.error(msg);\n    throw err;\n  }\n}\n","/**\n * Exa Search API\n * @reference https://docs.exa.ai/reference/search\n */\n\nimport { Exa } from 'exa-js';\nimport { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst DEFAULT_TIMEOUT = 20000;\n\nexport async function exaSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, apiKey, limit = 10 } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey) {\n    throw new Error('Exa search requires SEARCH_API_KEY');\n  }\n\n  let timeoutId: NodeJS.Timeout | undefined;\n\n  try {\n    const exa = new Exa(apiKey);\n\n    const result = await Promise.race([\n      exa.search(query, {\n        numResults: limit,\n        contents: {\n          text: true,\n        },\n      }),\n      new Promise<never>((_, reject) => {\n        timeoutId = setTimeout(() => reject(new Error('Exa search timeout')), DEFAULT_TIMEOUT);\n      }),\n    ]);\n\n    clearTimeout(timeoutId);\n\n    const results: ISearchResponseResult[] = result.results.map((item) => ({\n      title: item.title || '',\n      url: item.url,\n      snippet: (item as { text?: string }).text || '',\n      engine: 'exa',\n    }));\n\n    return { results, success: true };\n  } catch (err: unknown) {\n    clearTimeout(timeoutId);\n    const msg = err instanceof Error ? err.message : 'Exa search error.';\n    searchLogger.error(msg);\n    throw err;\n  }\n}\n","/**\n * Bocha Search API\n * @reference https://api.bocha.cn/docs\n */\n\nimport { ISearchRequestOptions, ISearchResponse, ISearchResponseResult } from '../interface.js';\nimport { searchLogger } from './logger.js';\n\nconst BOCHA_SEARCH_ENDPOINT = 'https://api.bocha.cn/v1/web-search';\nconst DEFAULT_TIMEOUT = 20000;\n\nexport type BochaFreshness = 'noLimit' | 'oneDay' | 'oneWeek' | 'oneMonth' | 'oneYear';\n\ninterface BochaSearchItem {\n  name?: string;\n  title?: string;\n  url?: string;\n  link?: string;\n  snippet?: string;\n  summary?: string;\n  content?: string;\n  datePublished?: string;\n  publish_date?: string;\n  siteName?: string;\n  site_name?: string;\n  urlToImage?: string;\n  icon?: string;\n}\n\ninterface BochaSearchResponse {\n  data?: {\n    webPages?: {\n      value?: BochaSearchItem[];\n    };\n  };\n  webPages?: {\n    value?: BochaSearchItem[];\n  };\n  results?: BochaSearchItem[];\n}\n\nexport async function bochaSearch(options: ISearchRequestOptions): Promise<ISearchResponse> {\n  const { query, apiKey, limit = 10, timeRange } = options;\n\n  if (!query?.trim()) {\n    throw new Error('Query cannot be empty');\n  }\n\n  if (!apiKey) {\n    throw new Error('Bocha search requires SEARCH_API_KEY');\n  }\n\n  let freshness: BochaFreshness = 'noLimit';\n  if (timeRange) {\n    const freshnessMap: Record<string, BochaFreshness> = {\n      day: 'oneDay',\n      week: 'oneWeek',\n      month: 'oneMonth',\n      year: 'oneYear',\n    };\n    freshness = freshnessMap[timeRange] || 'noLimit';\n  }\n\n  const controller = new AbortController();\n  const timeoutId = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT);\n\n  try {\n    const response = await fetch(BOCHA_SEARCH_ENDPOINT, {\n      method: 'POST',\n      headers: {\n        'Content-Type': 'application/json',\n        Authorization: `Bearer ${apiKey}`,\n      },\n      body: JSON.stringify({\n        query,\n        count: limit,\n        summary: true,\n        freshness,\n      }),\n      signal: controller.signal,\n    });\n\n    clearTimeout(timeoutId);\n\n    if (!response.ok) {\n      throw new Error(`Bocha search failed: ${response.status} ${response.statusText}`);\n    }\n\n    const data: BochaSearchResponse = await response.json();\n    const items: BochaSearchItem[] =\n      data?.data?.webPages?.value || data?.webPages?.value || data?.results || [];\n\n    const results: ISearchResponseResult[] = items.map((item) => ({\n      title: item.name || item.title || '',\n      url: item.url || item.link || '',\n      snippet: item.snippet || item.summary || item.content || '',\n      source: item.siteName || item.site_name,\n      thumbnailUrl: item.urlToImage || item.icon,\n      engine: 'bocha',\n    }));\n\n    return { results, success: true };\n  } catch (err: unknown) {\n    clearTimeout(timeoutId);\n    const msg = err instanceof Error ? err.message : 'Bocha search error.';\n    searchLogger.error(msg);\n    throw err;\n  }\n}\n","import { z } from 'zod/v3';\n\n// Search Schema\nexport const SearchSchema = z.object({\n  query: z.string().describe('Search query string'),\n  limit: z.number().optional().describe('Maximum number of results to return (default: 10)'),\n  language: z.string().optional().describe('Language code for search results (default: auto)'),\n  categories: z.enum([\n    'general',\n    'news',\n    'images',\n    'videos',\n    'it',\n    'science',\n    'map',\n    'music',\n    'files',\n    'social_media',\n  ]).optional().describe('Categories to search for (default: general)'),\n  timeRange: z.enum([\n    'all',\n    'day',\n    'week',\n    'month',\n    'year',\n  ]).optional().describe('Time range for search results (default: all)'),\n});\n\nexport type SearchInput = z.infer<typeof SearchSchema>;\n\n// Map Schema\nexport const MapSchema = z.object({\n  url: z.string().describe('Starting URL for URL discovery'),\n  search: z.string().optional().describe('Optional search term to filter URLs'),\n  ignoreSitemap: z.boolean().optional().describe('Skip sitemap.xml discovery and only use HTML links'),\n  sitemapOnly: z.boolean().optional().describe('Only use sitemap.xml for discovery, ignore HTML links'),\n  includeSubdomains: z.boolean().optional().describe('Include URLs from subdomains in results'),\n  limit: z.number().optional().describe('Maximum number of URLs to return'),\n});\n\nexport type MapInput = z.infer<typeof MapSchema>;\n\n// Action Schema for Scrape\nconst ActionSchema = z.discriminatedUnion('type', [\n  z.object({\n    type: z.literal('wait'),\n    milliseconds: z.number().describe('Time to wait in milliseconds'),\n  }),\n  z.object({\n    type: z.literal('click'),\n    selector: z.string().describe('CSS selector for the target element'),\n  }),\n  z.object({\n    type: z.literal('screenshot'),\n    fullPage: z.boolean().optional().describe('Take full page screenshot'),\n  }),\n  z.object({\n    type: z.literal('write'),\n    selector: z.string().describe('CSS selector for the target element'),\n    text: z.string().describe('Text to write'),\n  }),\n  z.object({\n    type: z.literal('press'),\n    key: z.string().describe('Key to press'),\n  }),\n  z.object({\n    type: z.literal('scroll'),\n    direction: z.enum(['up', 'down']).describe('Scroll direction'),\n  }),\n  z.object({\n    type: z.literal('scrape'),\n  }),\n  z.object({\n    type: z.literal('executeJavascript'),\n    script: z.string().describe('JavaScript code to execute'),\n  }),\n]);\n\n// Scrape Schema\nexport const ScrapeSchema = z.object({\n  url: z.string().describe('The URL to scrape'),\n  formats: z.array(z.enum([\n    'markdown',\n    'html',\n    'rawHtml',\n    'screenshot',\n    'links',\n    'screenshot@fullPage',\n    'extract',\n  ])).optional().describe(\"Content formats to extract (default: ['markdown'])\"),\n  onlyMainContent: z.boolean().optional().describe('Extract only the main content, filtering out navigation, footers, etc.'),\n  includeTags: z.array(z.string()).optional().describe('HTML tags to specifically include in extraction'),\n  excludeTags: z.array(z.string()).optional().describe('HTML tags to exclude from extraction'),\n  waitFor: z.number().optional().describe('Time in milliseconds to wait for dynamic content to load'),\n  timeout: z.number().optional().describe('Maximum time in milliseconds to wait for the page to load'),\n  actions: z.array(ActionSchema).optional().describe('List of actions to perform before scraping'),\n  extract: z.object({\n    schema: z.record(z.any()).optional().describe('Schema for structured data extraction'),\n    systemPrompt: z.string().optional().describe('System prompt for LLM extraction'),\n    prompt: z.string().optional().describe('User prompt for LLM extraction'),\n  }).optional().describe('Configuration for structured data extraction'),\n  mobile: z.boolean().optional().describe('Use mobile viewport'),\n  skipTlsVerification: z.boolean().optional().describe('Skip TLS certificate verification'),\n  removeBase64Images: z.boolean().optional().describe('Remove base64 encoded images from output'),\n  location: z.object({\n    country: z.string().optional().describe('Country code for geolocation'),\n    languages: z.array(z.string()).optional().describe('Language codes for content'),\n  }).optional().describe('Location settings for scraping'),\n});\n\nexport type ScrapeInput = z.infer<typeof ScrapeSchema>;\n\n// Extract Schema\nexport const ExtractSchema = z.object({\n  urls: z.array(z.string()).describe('List of URLs to extract information from'),\n  prompt: z.string().optional().describe('Prompt for the LLM extraction'),\n  systemPrompt: z.string().optional().describe('System prompt for LLM extraction'),\n  schema: z.record(z.any()).optional().describe('JSON schema for structured data extraction'),\n  allowExternalLinks: z.boolean().optional().describe('Allow extraction from external links'),\n  enableWebSearch: z.boolean().optional().describe('Enable web search for additional context'),\n  includeSubdomains: z.boolean().optional().describe('Include subdomains in extraction'),\n});\n\nexport type ExtractInput = z.infer<typeof ExtractSchema>;\n","import { SearchSchema, MapSchema, ScrapeSchema, ExtractSchema } from './schemas.js';\n\n// Tool definitions following MCP SDK v1.25+ pattern\nexport const SEARCH_TOOL = {\n  name: 'one_search',\n  description: 'Search and retrieve content from web pages. Returns SERP results by default (url, title, description).',\n  schema: SearchSchema,\n} as const;\n\nexport const MAP_TOOL = {\n  name: 'one_map',\n  description: 'Discover URLs from a starting point. Can use both sitemap.xml and HTML link discovery.',\n  schema: MapSchema,\n} as const;\n\nexport const SCRAPE_TOOL = {\n  name: 'one_scrape',\n  description: 'Scrape a single webpage with advanced options for content extraction. Supports various formats including markdown, HTML, and screenshots. Can execute custom actions like clicking or scrolling before scraping.',\n  schema: ScrapeSchema,\n} as const;\n\nexport const EXTRACT_TOOL = {\n  name: 'one_extract',\n  description: 'Extract structured information from web pages using LLM. Supports both cloud AI and self-hosted LLM extraction.',\n  schema: ExtractSchema,\n} as const;\n"],"mappings":"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","names":["index_exports","__toCommonJS","import_mcp","import_stdio","import_pino","PinoLogger","name","pino","level","message","args","defaultLogger","searchLogger","PinoLogger","DEFAULT_TIMEOUT","bingSearch","options","query","limit","safeSearch","page","apiUrl","apiKey","language","bingSafeSearchOptions","searchOptions","controller","timeoutId","queryParams","key","value","res","item","err","msg","searchLogger","DDG","import_async_retry","duckDuckGoSearch","options","query","timeout","safeSearch","retry","searchOptions","res","asyncRetry","result","error","msg","searchLogger","import_node_url","searxngSearch","params","query","page","limit","categories","engines","safeSearch","format","language","timeRange","timeout","apiKey","apiUrl","controller","timeoutId","config","endpoint","queryParams","url","headers","res","response","item","image","video","err","msg","searchLogger","import_core","DEFAULT_TIMEOUT","tavilySearch","options","query","limit","categories","timeRange","apiKey","timeoutId","tvly","params","res","_","reject","item","error","msg","searchLogger","import_browser","import_turndown","import_turndown_plugin_gfm","cheerio","fs","path","os","BrowserFinder","logger","defaultLogger","HOME_DIR","LOCAL_APP_DATA","name","platform","error","browser","b","result","browserName","profileInfo","profileName","info","executable","BROWSER_CONFIG","VALID_SEARCH_ENGINES","AgentBrowser","options","finder","BrowserFinder","executable","TurndownService","error","errorMessage","url","ms","resolve","BROWSER_CONFIG","result","formats","html","links","link","baseHost","query","engine","limit","searchUrl","encodedQuery","defaultLogger","$","results","_","element","$el","$link","$title","$snippet","title","snippet","baseUrl","linkRegex","match","logger","PinoLogger","isValidEngine","engine","VALID_SEARCH_ENGINES","toSearchResponseResult","result","localSearch","options","query","limit","engines","engineList","e","validEngines","invalidEngines","browser","AgentBrowser","results","searchResults","converted","r","err","msg","GOOGLE_SEARCH_ENDPOINT","DEFAULT_TIMEOUT","googleSearch","options","query","apiKey","apiUrl","limit","language","params","controller","timeoutId","response","data","item","error","msg","searchLogger","ZHIPU_SEARCH_ENDPOINT","DEFAULT_TIMEOUT","zhipuSearch","options","query","apiKey","limit","engines","searchEngine","controller","timeoutId","response","item","err","msg","searchLogger","import_exa_js","DEFAULT_TIMEOUT","exaSearch","options","query","apiKey","limit","timeoutId","exa","result","_","reject","item","err","msg","searchLogger","BOCHA_SEARCH_ENDPOINT","DEFAULT_TIMEOUT","bochaSearch","options","query","apiKey","limit","timeRange","freshness","controller","timeoutId","response","data","item","err","msg","searchLogger","import_v3","SearchSchema","MapSchema","ActionSchema","ScrapeSchema","ExtractSchema","SEARCH_TOOL","SearchSchema","MAP_TOOL","MapSchema","SCRAPE_TOOL","ScrapeSchema","EXTRACT_TOOL","ExtractSchema","import_dotenvx","import_duck_duck_scrape","dotenvx","SEARCH_API_URL","SEARCH_API_KEY","SEARCH_PROVIDER","SAFE_SEARCH","LIMIT","CATEGORIES","ENGINES","FORMAT","LANGUAGE","TIME_RANGE","DEFAULT_TIMEOUT","server","searchDefaultConfig","createToolHandler","toolName","handler","args","startTime","result","error","SEARCH_TOOL","results","success","processSearch","SCRAPE_TOOL","url","scrapeArgs","content","processScrape","MAP_TOOL","processMapUrl","EXTRACT_TOOL","processExtract","params","categories","language","searxngSearch","tavilySearch","bingSearch","safeSearch","safeSearchOptions","duckDuckGoSearch","localSearch","googleSearch","zhipuSearch","exaSearch","bochaSearch","browser","AgentBrowser","res","urls","prompt","systemPrompt","schema","errorMsg","finalText","instructions","runServer","transport","msg"]}