Coverage for web_search/types.py: 88%

1 from abc import ABC, abstractmethod

2 from typing import List, Optional, Dict, Any

3 from pydantic import BaseModel, Field

4

5

6 class 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)

12

13

14 class 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)

22

23

24 class WebSearchProvider(ABC):

25 """

26 Web 搜索 Provider 抽象基类

27 所有搜索引擎插件都需要继承此类并实现 search 方法

28 """

29

30 @property

31 @abstractmethod

32 def id(self) -> str:

33 """Provider ID (例如: 'tavily', 'google')"""

34 pass

35

36 @property

37 @abstractmethod

38 def name(self) -> str:

39 """Provider 名称 (例如: 'Tavily Search')"""

40 pass

41

42 @abstractmethod

43 def is_available(self) -> bool:

44 """检查此 Provider 是否可用（例如 API Key 是否已配置）"""

45 pass

46

47 @abstractmethod

48 def search(self, query: str, max_results: int = 5, **kwargs) -> WebSearchResponse:

49 """执行搜索"""

50 pass