|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
import json
|
|
import json
|
|
|
import logging
|
|
import logging
|
|
|
|
|
|
|
|
-from agent.tools import tool, ToolResult
|
|
|
|
|
|
|
+from agent.tools import tool, ToolContext, ToolResult
|
|
|
from src.infra.shared.http_client import AsyncHttpClient
|
|
from src.infra.shared.http_client import AsyncHttpClient
|
|
|
from src.infra.shared.common import extract_history_articles
|
|
from src.infra.shared.common import extract_history_articles
|
|
|
|
|
|
|
@@ -14,8 +14,23 @@ base_url = "http://crawler-cn.aiddit.com/crawler/wei_xin"
|
|
|
headers = {"Content-Type": "application/json"}
|
|
headers = {"Content-Type": "application/json"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def _build_success_result(title: str, response: dict) -> ToolResult:
|
|
|
|
|
+ """把上游响应规范为 ToolResult。"""
|
|
|
|
|
+ output = response.get("output")
|
|
|
|
|
+ if not output:
|
|
|
|
|
+ output = json.dumps(response, ensure_ascii=False)
|
|
|
|
|
+
|
|
|
|
|
+ metadata = response.get("metadata")
|
|
|
|
|
+ if not isinstance(metadata, dict):
|
|
|
|
|
+ metadata = {"raw_data": response}
|
|
|
|
|
+ elif "raw_data" not in metadata:
|
|
|
|
|
+ metadata["raw_data"] = response
|
|
|
|
|
+
|
|
|
|
|
+ return ToolResult(title=title, output=output, metadata=metadata)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
@tool(description="通过关键词搜索微信文章")
|
|
@tool(description="通过关键词搜索微信文章")
|
|
|
-async def weixin_search(keyword: str, page="1") -> dict | None:
|
|
|
|
|
|
|
+async def weixin_search(keyword: str, page: str = "1", ctx: ToolContext = None) -> ToolResult:
|
|
|
"""
|
|
"""
|
|
|
微信关键词搜索
|
|
微信关键词搜索
|
|
|
|
|
|
|
@@ -44,16 +59,19 @@ async def weixin_search(keyword: str, page="1") -> dict | None:
|
|
|
try:
|
|
try:
|
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
|
-
|
|
|
|
|
|
|
+ return _build_success_result("微信文章搜索结果", response)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- print(e)
|
|
|
|
|
- return None
|
|
|
|
|
- print(json.dumps(response, ensure_ascii=False, indent=4))
|
|
|
|
|
- return response
|
|
|
|
|
|
|
+ logger.exception("weixin_search failed")
|
|
|
|
|
+ return ToolResult(
|
|
|
|
|
+ title="微信文章搜索失败",
|
|
|
|
|
+ output="",
|
|
|
|
|
+ error=str(e),
|
|
|
|
|
+ metadata={"keyword": keyword, "page": page},
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
@tool(description="通过公众号文章链接获取公众号详情信息")
|
|
@tool(description="通过公众号文章链接获取公众号详情信息")
|
|
|
-async def fetch_weixin_account(content_link: str) -> dict | None:
|
|
|
|
|
|
|
+async def fetch_weixin_account(content_link: str, ctx: ToolContext = None) -> ToolResult:
|
|
|
"""
|
|
"""
|
|
|
通过公众号文章链接获取公众号的详情信息
|
|
通过公众号文章链接获取公众号的详情信息
|
|
|
|
|
|
|
@@ -79,16 +97,24 @@ async def fetch_weixin_account(content_link: str) -> dict | None:
|
|
|
try:
|
|
try:
|
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
|
-
|
|
|
|
|
|
|
+ return _build_success_result("公众号详情信息", response)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- logger.error(e)
|
|
|
|
|
- return None
|
|
|
|
|
- print(json.dumps(response, ensure_ascii=False, indent=4))
|
|
|
|
|
- return response
|
|
|
|
|
|
|
+ logger.exception("fetch_weixin_account failed")
|
|
|
|
|
+ return ToolResult(
|
|
|
|
|
+ title="公众号详情获取失败",
|
|
|
|
|
+ output="",
|
|
|
|
|
+ error=str(e),
|
|
|
|
|
+ metadata={"content_link": content_link},
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
@tool(description="通过微信公众号的 wx_gh 获取微信公众号的历史发文列表")
|
|
@tool(description="通过微信公众号的 wx_gh 获取微信公众号的历史发文列表")
|
|
|
-async def fetch_account_article_list(wx_gh: str, index=None, is_cache=True) -> dict | None:
|
|
|
|
|
|
|
+async def fetch_account_article_list(
|
|
|
|
|
+ wx_gh: str,
|
|
|
|
|
+ index: str | None = None,
|
|
|
|
|
+ is_cache: bool = True,
|
|
|
|
|
+ ctx: ToolContext = None,
|
|
|
|
|
+) -> ToolResult:
|
|
|
"""
|
|
"""
|
|
|
通过公众号的 wx_gh 获取历史发文列表
|
|
通过公众号的 wx_gh 获取历史发文列表
|
|
|
|
|
|
|
@@ -134,16 +160,25 @@ async def fetch_account_article_list(wx_gh: str, index=None, is_cache=True) -> d
|
|
|
try:
|
|
try:
|
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
async with AsyncHttpClient(timeout=120) as http_client:
|
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
response = await http_client.post(url=url, headers=headers, data=payload)
|
|
|
-
|
|
|
|
|
|
|
+ normalized = extract_history_articles(response)
|
|
|
|
|
+ return _build_success_result("公众号历史发文列表", normalized)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- logger.error(e)
|
|
|
|
|
- return None
|
|
|
|
|
-
|
|
|
|
|
- return extract_history_articles(response)
|
|
|
|
|
|
|
+ logger.exception("fetch_account_article_list failed")
|
|
|
|
|
+ return ToolResult(
|
|
|
|
|
+ title="公众号历史发文获取失败",
|
|
|
|
|
+ output="",
|
|
|
|
|
+ error=str(e),
|
|
|
|
|
+ metadata={"wx_gh": wx_gh, "index": index, "is_cache": is_cache},
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
@tool(description="通过公众号文章链接获取文章详情")
|
|
@tool(description="通过公众号文章链接获取文章详情")
|
|
|
-async def fetch_article_detail(article_link: str, is_count: bool = False, is_cache: bool = True) -> dict | None:
|
|
|
|
|
|
|
+async def fetch_article_detail(
|
|
|
|
|
+ article_link: str,
|
|
|
|
|
+ is_count: bool = False,
|
|
|
|
|
+ is_cache: bool = True,
|
|
|
|
|
+ ctx: ToolContext = None,
|
|
|
|
|
+) -> ToolResult:
|
|
|
"""
|
|
"""
|
|
|
通过公众号的 文章链接获取文章详情
|
|
通过公众号的 文章链接获取文章详情
|
|
|
Args:
|
|
Args:
|
|
@@ -180,11 +215,19 @@ async def fetch_article_detail(article_link: str, is_count: bool = False, is_cac
|
|
|
try:
|
|
try:
|
|
|
async with AsyncHttpClient(timeout=10) as http_client:
|
|
async with AsyncHttpClient(timeout=10) as http_client:
|
|
|
response = await http_client.post(target_url, headers=headers, data=payload)
|
|
response = await http_client.post(target_url, headers=headers, data=payload)
|
|
|
|
|
+ return _build_success_result("文章详情信息", response)
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- print(e)
|
|
|
|
|
- return None
|
|
|
|
|
-
|
|
|
|
|
- return response
|
|
|
|
|
|
|
+ logger.exception("fetch_article_detail failed")
|
|
|
|
|
+ return ToolResult(
|
|
|
|
|
+ title="文章详情获取失败",
|
|
|
|
|
+ output="",
|
|
|
|
|
+ error=str(e),
|
|
|
|
|
+ metadata={
|
|
|
|
|
+ "article_link": article_link,
|
|
|
|
|
+ "is_count": is_count,
|
|
|
|
|
+ "is_cache": is_cache,
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if __name__ == "__main__":
|