64 lines
2.2 KiB
Python
64 lines
2.2 KiB
Python
"""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)
|