"""Web Search: 通过博查 API 搜索互联网,返回结果列表。""" from __future__ import annotations from .base import Tool from core.bocha_client import BochaClient, BochaConfig, BochaError class WebSearchTool(Tool): name = "web_search" description = ( "Search the web using Bocha AI search engine. " "Returns titles, URLs, and summaries for each result. " "Use this to find current information, news, documentation, or anything on the public internet." ) parameters = { "type": "object", "properties": { "query": {"type": "string", "description": "Search query string"}, "count": { "type": "integer", "default": 10, "description": "Number of results to return (1-20, default 10)", }, "freshness": { "type": "string", "enum": ["noLimit", "oneDay", "oneWeek", "oneMonth", "oneYear"], "default": "noLimit", "description": "Filter results by recency", }, }, "required": ["query"], } def __init__(self, cfg: BochaConfig) -> None: super().__init__() self._cfg = cfg def execute(self, query: str, count: int = 10, freshness: str = "noLimit") -> str: count = min(max(int(count), 1), 20) try: with BochaClient(self._cfg) as client: data = client.search(query=query, count=count, freshness=freshness) except BochaError as e: return f"[Error] web search failed: {e}" web_pages = (data.get("data") or {}).get("webPages") or {} results = web_pages.get("value") or [] if not results: return f"(no results found for query: {query!r})" lines = [f"Search results for: {query!r}\n"] for i, r in enumerate(results, 1): name = r.get("name", "?") url = r.get("url", "") summary = r.get("summary") or r.get("snippet", "") lines.append(f"{i}. **{name}**") if url: lines.append(f" URL: {url}") if summary: lines.append(f" {summary}") lines.append("") return "\n".join(lines)