video_library.py 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. """
  2. 票圈视频库工具
  3. 提供视频搜索、详情获取、账号分析等功能。
  4. """
  5. import json
  6. from typing import Optional, List, Dict, Any
  7. import httpx
  8. from agent.tools import tool, ToolResult
  9. # API 基础配置
  10. VIDEO_LIBRARY_API = "http://your-video-library-api.com" # 替换为实际API地址
  11. DEFAULT_TIMEOUT = 60.0
  12. @tool(
  13. display={
  14. "zh": {
  15. "name": "搜索票圈视频库",
  16. "params": {
  17. "keyword": "搜索关键词",
  18. "max_count": "返回条数",
  19. "filters": "过滤条件"
  20. }
  21. }
  22. }
  23. )
  24. async def video_library_search(
  25. keyword: str,
  26. max_count: int = 10,
  27. filters: Optional[Dict[str, Any]] = None,
  28. ) -> ToolResult:
  29. """
  30. 在票圈视频库中搜索视频
  31. Args:
  32. keyword: 搜索关键词
  33. max_count: 返回的最大条数,默认为 10
  34. filters: 过滤条件,可选字段:
  35. - platform: 平台过滤(douyin/xhs/bili等)
  36. - min_likes: 最小点赞数
  37. - date_range: 发布时间范围
  38. - tags: 标签过滤
  39. Returns:
  40. ToolResult 包含搜索结果:
  41. {
  42. "code": 0,
  43. "message": "success",
  44. "data": [
  45. {
  46. "video_id": "v123456",
  47. "title": "14岁抗日娃娃军",
  48. "platform": "douyin",
  49. "account_id": "acc789",
  50. "account_name": "历史故事",
  51. "like_count": 12700,
  52. "publish_time": "2025-01-15",
  53. "tags": ["抗日", "娃娃军", "感动"],
  54. "shipping_info": {
  55. "status": "approved",
  56. "category": "历史教育"
  57. }
  58. }
  59. ]
  60. }
  61. """
  62. try:
  63. url = f"{VIDEO_LIBRARY_API}/api/videos/search"
  64. payload = {
  65. "keyword": keyword,
  66. "max_count": max_count,
  67. }
  68. if filters:
  69. payload["filters"] = filters
  70. async with httpx.AsyncClient(timeout=DEFAULT_TIMEOUT) as client:
  71. response = await client.post(
  72. url,
  73. json=payload,
  74. headers={"Content-Type": "application/json"},
  75. )
  76. response.raise_for_status()
  77. data = response.json()
  78. result_count = len(data.get("data", []))
  79. return ToolResult(
  80. title=f"视频库搜索: {keyword}",
  81. output=json.dumps(data, ensure_ascii=False, indent=2),
  82. long_term_memory=f"Searched video library for '{keyword}', found {result_count} videos"
  83. )
  84. except httpx.HTTPStatusError as e:
  85. return ToolResult(
  86. title="搜索失败",
  87. output="",
  88. error=f"HTTP error {e.response.status_code}: {e.response.text}"
  89. )
  90. except Exception as e:
  91. return ToolResult(
  92. title="搜索失败",
  93. output="",
  94. error=str(e)
  95. )
  96. @tool(
  97. display={
  98. "zh": {
  99. "name": "获取视频详情",
  100. "params": {
  101. "video_id": "视频ID"
  102. }
  103. }
  104. }
  105. )
  106. async def video_library_get_detail(
  107. video_id: str,
  108. ) -> ToolResult:
  109. """
  110. 获取视频的详细信息
  111. Args:
  112. video_id: 视频唯一标识符
  113. Returns:
  114. ToolResult 包含视频详情:
  115. {
  116. "code": 0,
  117. "message": "success",
  118. "data": {
  119. "video_id": "v123456",
  120. "title": "14岁抗日娃娃军",
  121. "description": "...",
  122. "platform": "douyin",
  123. "platform_video_id": "7123456789",
  124. "account_id": "acc789",
  125. "account_name": "历史故事",
  126. "like_count": 12700,
  127. "comment_count": 856,
  128. "share_count": 432,
  129. "publish_time": "2025-01-15",
  130. "duration": 180,
  131. "tags": ["抗日", "娃娃军", "感动"],
  132. "shipping_info": {
  133. "status": "approved",
  134. "category": "历史教育",
  135. "target_audience": "50+",
  136. "emotional_tone": "感动",
  137. "quality_score": 8.5
  138. },
  139. "url": "https://..."
  140. }
  141. }
  142. """
  143. try:
  144. url = f"{VIDEO_LIBRARY_API}/api/videos/{video_id}"
  145. async with httpx.AsyncClient(timeout=DEFAULT_TIMEOUT) as client:
  146. response = await client.get(url)
  147. response.raise_for_status()
  148. data = response.json()
  149. video_data = data.get("data", {})
  150. title = video_data.get("title", "Unknown")
  151. return ToolResult(
  152. title=f"视频详情: {title}",
  153. output=json.dumps(data, ensure_ascii=False, indent=2),
  154. long_term_memory=f"Retrieved video detail for {video_id}"
  155. )
  156. except httpx.HTTPStatusError as e:
  157. return ToolResult(
  158. title="获取详情失败",
  159. output="",
  160. error=f"HTTP error {e.response.status_code}: {e.response.text}"
  161. )
  162. except Exception as e:
  163. return ToolResult(
  164. title="获取详情失败",
  165. output="",
  166. error=str(e)
  167. )
  168. @tool(
  169. display={
  170. "zh": {
  171. "name": "获取账号信息",
  172. "params": {
  173. "account_id": "账号ID",
  174. "include_videos": "是否包含视频列表",
  175. "include_recommendations": "是否包含推荐账号"
  176. }
  177. }
  178. }
  179. )
  180. async def video_library_get_account(
  181. account_id: str,
  182. include_videos: bool = True,
  183. include_recommendations: bool = True,
  184. ) -> ToolResult:
  185. """
  186. 获取账号信息及相关推荐
  187. Args:
  188. account_id: 账号唯一标识符
  189. include_videos: 是否包含该账号的视频列表,默认 True
  190. include_recommendations: 是否包含相关推荐账号,默认 True
  191. Returns:
  192. ToolResult 包含账号信息:
  193. {
  194. "code": 0,
  195. "message": "success",
  196. "data": {
  197. "account_id": "acc789",
  198. "account_name": "历史故事",
  199. "platform": "douyin",
  200. "follower_count": 125000,
  201. "video_count": 342,
  202. "tags": ["历史", "教育", "正能量"],
  203. "videos": [
  204. {
  205. "video_id": "v123456",
  206. "title": "...",
  207. "like_count": 12700
  208. }
  209. ],
  210. "recommended_accounts": [
  211. {
  212. "account_id": "acc790",
  213. "account_name": "红色记忆",
  214. "similarity_score": 0.85,
  215. "reason": "内容相似"
  216. }
  217. ]
  218. }
  219. }
  220. """
  221. try:
  222. url = f"{VIDEO_LIBRARY_API}/api/accounts/{account_id}"
  223. params = {
  224. "include_videos": include_videos,
  225. "include_recommendations": include_recommendations,
  226. }
  227. async with httpx.AsyncClient(timeout=DEFAULT_TIMEOUT) as client:
  228. response = await client.get(url, params=params)
  229. response.raise_for_status()
  230. data = response.json()
  231. account_data = data.get("data", {})
  232. account_name = account_data.get("account_name", "Unknown")
  233. return ToolResult(
  234. title=f"账号信息: {account_name}",
  235. output=json.dumps(data, ensure_ascii=False, indent=2),
  236. long_term_memory=f"Retrieved account info for {account_id}"
  237. )
  238. except httpx.HTTPStatusError as e:
  239. return ToolResult(
  240. title="获取账号信息失败",
  241. output="",
  242. error=f"HTTP error {e.response.status_code}: {e.response.text}"
  243. )
  244. except Exception as e:
  245. return ToolResult(
  246. title="获取账号信息失败",
  247. output="",
  248. error=str(e)
  249. )