From d572e523ba5dc29a6877f21c4334d49d27085372 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Mon, 17 Nov 2025 09:57:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96Agent=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/agent/tools/base.py | 2 +- app/agent/tools/impl/get_recommendations.py | 29 ++++++++++++- app/agent/tools/impl/query_downloads.py | 36 +++++++++++++++- app/agent/tools/impl/query_subscribes.py | 33 ++++++++++++++- app/agent/tools/impl/search_media.py | 27 +++++++++++- app/agent/tools/impl/search_torrents.py | 47 ++++++++++++++++++++- app/chain/message.py | 2 +- 7 files changed, 167 insertions(+), 9 deletions(-) diff --git a/app/agent/tools/base.py b/app/agent/tools/base.py index 0016b072..ba3f1ee4 100644 --- a/app/agent/tools/base.py +++ b/app/agent/tools/base.py @@ -60,7 +60,7 @@ class MoviePilotTool(BaseTool, metaclass=ABCMeta): """设置回调处理器""" self._callback_handler = callback_handler - async def send_tool_message(self, message: str, title: str = ""): + async def send_tool_message(self, message: str, title: str = "MoviePilot助手"): """发送工具消息""" await ToolChain().async_post_message( Notification( diff --git a/app/agent/tools/impl/get_recommendations.py b/app/agent/tools/impl/get_recommendations.py index 3f15aa2e..cbbe439a 100644 --- a/app/agent/tools/impl/get_recommendations.py +++ b/app/agent/tools/impl/get_recommendations.py @@ -51,8 +51,33 @@ class GetRecommendationsTool(MoviePilotTool): results = recommend_chain.bangumi_calendar(limit=limit) if results: - # 使用 to_dict() 方法 - return json.dumps(results) + # 限制最多20条结果 + total_count = len(results) + limited_results = results[:20] + # 精简字段,只保留关键信息 + simplified_results = [] + for r in limited_results: + # r 已经是字典格式(to_dict的结果) + simplified = { + "title": r.get("title"), + "en_title": r.get("en_title"), + "year": r.get("year"), + "type": r.get("type"), + "season": r.get("season"), + "tmdb_id": r.get("tmdb_id"), + "imdb_id": r.get("imdb_id"), + "douban_id": r.get("douban_id"), + "overview": r.get("overview", "")[:200] + "..." if r.get("overview") and len(r.get("overview", "")) > 200 else r.get("overview"), + "vote_average": r.get("vote_average"), + "poster_path": r.get("poster_path"), + "detail_link": r.get("detail_link") + } + simplified_results.append(simplified) + result_json = json.dumps(simplified_results, ensure_ascii=False, indent=2) + # 如果结果被裁剪,添加提示信息 + if total_count > 20: + return f"注意:推荐结果共找到 {total_count} 条,为节省上下文空间,仅显示前 20 条结果。\n\n{result_json}" + return result_json return "未找到推荐内容。" except Exception as e: logger.error(f"获取推荐失败: {e}", exc_info=True) diff --git a/app/agent/tools/impl/query_downloads.py b/app/agent/tools/impl/query_downloads.py index 4cd15d4b..aca3020b 100644 --- a/app/agent/tools/impl/query_downloads.py +++ b/app/agent/tools/impl/query_downloads.py @@ -39,7 +39,41 @@ class QueryDownloadsTool(MoviePilotTool): continue filtered_downloads.append(dl) if filtered_downloads: - return json.dumps([d.model_dump() for d in filtered_downloads]) + # 限制最多20条结果 + total_count = len(filtered_downloads) + limited_downloads = filtered_downloads[:20] + # 精简字段,只保留关键信息 + simplified_downloads = [] + for d in limited_downloads: + simplified = { + "downloader": d.downloader, + "hash": d.hash, + "title": d.title, + "name": d.name, + "year": d.year, + "season_episode": d.season_episode, + "size": d.size, + "progress": d.progress, + "state": d.state, + "upspeed": d.upspeed, + "dlspeed": d.dlspeed, + "left_time": d.left_time + } + # 精简 media 字段 + if d.media: + simplified["media"] = { + "tmdbid": d.media.get("tmdbid"), + "type": d.media.get("type"), + "title": d.media.get("title"), + "season": d.media.get("season"), + "episode": d.media.get("episode") + } + simplified_downloads.append(simplified) + result_json = json.dumps(simplified_downloads, ensure_ascii=False, indent=2) + # 如果结果被裁剪,添加提示信息 + if total_count > 20: + return f"注意:查询结果共找到 {total_count} 条,为节省上下文空间,仅显示前 20 条结果。\n\n{result_json}" + return result_json return "未找到相关下载任务。" except Exception as e: logger.error(f"查询下载失败: {e}", exc_info=True) diff --git a/app/agent/tools/impl/query_subscribes.py b/app/agent/tools/impl/query_subscribes.py index 2e0bf266..81215183 100644 --- a/app/agent/tools/impl/query_subscribes.py +++ b/app/agent/tools/impl/query_subscribes.py @@ -37,8 +37,37 @@ class QuerySubscribesTool(MoviePilotTool): continue filtered_subscribes.append(sub) if filtered_subscribes: - return json.dumps([s.to_dict() for s in filtered_subscribes], ensure_ascii=False, indent=2) - return "未找到相关订阅。" + # 限制最多20条结果 + total_count = len(filtered_subscribes) + limited_subscribes = filtered_subscribes[:20] + # 精简字段,只保留关键信息 + simplified_subscribes = [] + for s in limited_subscribes: + simplified = { + "id": s.id, + "name": s.name, + "year": s.year, + "type": s.type, + "season": s.season, + "tmdbid": s.tmdbid, + "doubanid": s.doubanid, + "bangumiid": s.bangumiid, + "poster": s.poster, + "vote": s.vote, + "description": s.description[:200] + "..." if s.description and len(s.description) > 200 else s.description, + "state": s.state, + "total_episode": s.total_episode, + "lack_episode": s.lack_episode, + "last_update": s.last_update, + "username": s.username + } + simplified_subscribes.append(simplified) + result_json = json.dumps(simplified_subscribes, ensure_ascii=False, indent=2) + # 如果结果被裁剪,添加提示信息 + if total_count > 20: + return f"注意:查询结果共找到 {total_count} 条,为节省上下文空间,仅显示前 20 条结果。\n\n{result_json}" + return result_json + return "未找到相关订阅" except Exception as e: logger.error(f"查询订阅失败: {e}", exc_info=True) return f"查询订阅时发生错误: {str(e)}" diff --git a/app/agent/tools/impl/search_media.py b/app/agent/tools/impl/search_media.py index d37863b5..a9f606cc 100644 --- a/app/agent/tools/impl/search_media.py +++ b/app/agent/tools/impl/search_media.py @@ -60,7 +60,32 @@ class SearchMediaTool(MoviePilotTool): filtered_results.append(result) if filtered_results: - return json.dumps([r.to_dict() for r in filtered_results], ensure_ascii=False, indent=2) + # 限制最多20条结果 + total_count = len(filtered_results) + limited_results = filtered_results[:20] + # 精简字段,只保留关键信息 + simplified_results = [] + for r in limited_results: + simplified = { + "title": r.title, + "en_title": r.en_title, + "year": r.year, + "type": r.type.value if r.type else None, + "season": r.season, + "tmdb_id": r.tmdb_id, + "imdb_id": r.imdb_id, + "douban_id": r.douban_id, + "overview": r.overview[:200] + "..." if r.overview and len(r.overview) > 200 else r.overview, + "vote_average": r.vote_average, + "poster_path": r.poster_path, + "detail_link": r.detail_link + } + simplified_results.append(simplified) + result_json = json.dumps(simplified_results, ensure_ascii=False, indent=2) + # 如果结果被裁剪,添加提示信息 + if total_count > 20: + return f"注意:搜索结果共找到 {total_count} 条,为节省上下文空间,仅显示前 20 条结果。\n\n{result_json}" + return result_json else: return f"未找到符合条件的媒体资源: {title}" else: diff --git a/app/agent/tools/impl/search_torrents.py b/app/agent/tools/impl/search_torrents.py index cdd81583..08a66314 100644 --- a/app/agent/tools/impl/search_torrents.py +++ b/app/agent/tools/impl/search_torrents.py @@ -52,7 +52,52 @@ class SearchTorrentsTool(MoviePilotTool): filtered_torrents.append(torrent) if filtered_torrents: - return json.dumps([t.to_dict() for t in filtered_torrents], ensure_ascii=False, indent=2) + # 限制最多50条结果 + total_count = len(filtered_torrents) + limited_torrents = filtered_torrents[:50] + # 精简字段,只保留关键信息 + simplified_torrents = [] + for t in limited_torrents: + simplified = {} + # 精简 torrent_info + if t.torrent_info: + simplified["torrent_info"] = { + "title": t.torrent_info.title, + "size": t.torrent_info.size, + "seeders": t.torrent_info.seeders, + "peers": t.torrent_info.peers, + "site_name": t.torrent_info.site_name, + "enclosure": t.torrent_info.enclosure, + "page_url": t.torrent_info.page_url, + "volume_factor": t.torrent_info.volume_factor, + "pubdate": t.torrent_info.pubdate + } + # 精简 media_info + if t.media_info: + simplified["media_info"] = { + "title": t.media_info.title, + "en_title": t.media_info.en_title, + "year": t.media_info.year, + "type": t.media_info.type.value if t.media_info.type else None, + "season": t.media_info.season, + "tmdb_id": t.media_info.tmdb_id + } + # 精简 meta_info + if t.meta_info: + simplified["meta_info"] = { + "name": t.meta_info.name, + "cn_name": t.meta_info.cn_name, + "en_name": t.meta_info.en_name, + "year": t.meta_info.year, + "type": t.meta_info.type.value if t.meta_info.type else None, + "begin_season": t.meta_info.begin_season + } + simplified_torrents.append(simplified) + result_json = json.dumps(simplified_torrents, ensure_ascii=False, indent=2) + # 如果结果被裁剪,添加提示信息 + if total_count > 50: + return f"注意:搜索结果共找到 {total_count} 条,为节省上下文空间,仅显示前 50 条结果。\n\n{result_json}" + return result_json else: return f"未找到相关种子资源: {title}" except Exception as e: diff --git a/app/chain/message.py b/app/chain/message.py index 1f290a9a..81e6385f 100644 --- a/app/chain/message.py +++ b/app/chain/message.py @@ -868,7 +868,7 @@ class MessageChain(ChainBase): source=source, userid=userid, username=username, - title="正在处理您的请求,请稍候..." + title="MoviePilot助手已收到您的请求,请稍候..." )) # 生成会话ID