Coverage for web_search / types.py: 88%
32 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-29 02:55 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-29 02:55 +0800
1from abc import ABC, abstractmethod
2from typing import List, Optional, Dict, Any
3from pydantic import BaseModel, Field
6class SearchResult(BaseModel):
7 title: str = Field(description="网页标题")
8 url: str = Field(description="网页链接")
9 snippet: str = Field(description="摘要内容")
10 score: Optional[float] = Field(description="相关性得分", default=None)
11 published_date: Optional[str] = Field(description="发布日期", default=None)
14class WebSearchResponse(BaseModel):
15 query: str
16 provider: str
17 count: int
18 took_ms: Optional[float] = None
19 results: List[SearchResult]
20 answer: Optional[str] = Field(description="AI生成的直接答案", default=None)
21 raw_response: Optional[Dict[str, Any]] = Field(description="原始API响应", default=None, exclude=True)
24class WebSearchProvider(ABC):
25 """
26 Web 搜索 Provider 抽象基类
27 所有搜索引擎插件都需要继承此类并实现 search 方法
28 """
30 @property
31 @abstractmethod
32 def id(self) -> str:
33 """Provider ID (例如: 'tavily', 'google')"""
34 pass
36 @property
37 @abstractmethod
38 def name(self) -> str:
39 """Provider 名称 (例如: 'Tavily Search')"""
40 pass
42 @abstractmethod
43 def is_available(self) -> bool:
44 """检查此 Provider 是否可用(例如 API Key 是否已配置)"""
45 pass
47 @abstractmethod
48 def search(self, query: str, max_results: int = 5, **kwargs) -> WebSearchResponse:
49 """执行搜索"""
50 pass