fix agent tools

This commit is contained in:
jxxghp
2025-11-01 12:01:48 +08:00
parent 247208b8a9
commit b45b603b97
12 changed files with 145 additions and 331 deletions
-297
View File
@@ -1,297 +0,0 @@
[
{
"description": "Search for media resources including movies, TV shows, anime, etc. Supports searching by title, year, type, and other criteria. Returns detailed media information from TMDB database.",
"name": "search_media",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"title": {
"description": "The title of the media to search for (e.g., 'The Matrix', 'Breaking Bad')",
"type": "string"
},
"year": {
"description": "Release year of the media (optional, helps narrow down results)",
"type": "string"
},
"media_type": {
"description": "Type of media content: 'movie' for films, 'tv' for television series, 'anime' for anime series",
"type": "string"
},
"season": {
"description": "Season number for TV shows and anime (optional, only applicable for series)",
"type": "integer"
}
},
"required": [
"title",
"explanation"
],
"type": "object"
}
},
{
"description": "Add media subscription to create automated download rules for movies and TV shows. The system will automatically search and download new episodes or releases based on the subscription criteria.",
"name": "add_subscribe",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"title": {
"description": "The title of the media to subscribe to (e.g., 'The Matrix', 'Breaking Bad')",
"type": "string"
},
"year": {
"description": "Release year of the media (required for accurate identification)",
"type": "string"
},
"media_type": {
"description": "Type of media content: 'movie' for films, 'tv' for television series",
"type": "string"
},
"season": {
"description": "Season number for TV shows (optional, if not specified will subscribe to all seasons)",
"type": "integer"
},
"tmdb_id": {
"description": "TMDB database ID for precise media identification (optional but recommended for accuracy)",
"type": "string"
}
},
"required": [
"title",
"year",
"media_type",
"explanation"
],
"type": "object"
}
},
{
"description": "Search for torrent files across configured indexer sites based on media information. Returns available torrent downloads with details like file size, quality, and download links.",
"name": "search_torrents",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"title": {
"description": "The title of the media resource to search for (e.g., 'The Matrix 1999', 'Breaking Bad S01E01')",
"type": "string"
},
"year": {
"description": "Release year of the media (optional, helps narrow down search results)",
"type": "string"
},
"media_type": {
"description": "Type of media content: 'movie' for films, 'tv' for television series",
"type": "string"
},
"season": {
"description": "Season number for TV shows (optional, only applicable for series)",
"type": "integer"
},
"sites": {
"description": "Array of specific site IDs to search on (optional, if not provided searches all configured sites)",
"items": {
"type": "integer"
},
"type": "array"
}
},
"required": [
"title",
"explanation"
],
"type": "object"
}
},
{
"description": "Add torrent download task to the configured downloader (qBittorrent, Transmission, etc.). Downloads the torrent file and starts the download process with specified settings.",
"name": "add_download",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"torrent_title": {
"description": "The display name/title of the torrent (e.g., 'The.Matrix.1999.1080p.BluRay.x264')",
"type": "string"
},
"torrent_url": {
"description": "Direct URL to the torrent file (.torrent) or magnet link",
"type": "string"
},
"downloader": {
"description": "Name of the downloader to use (optional, uses default if not specified)",
"type": "string"
},
"save_path": {
"description": "Directory path where the downloaded files should be saved (optional, uses default path if not specified)",
"type": "string"
},
"labels": {
"description": "Comma-separated list of labels/tags to assign to the download (optional, e.g., 'movie,hd,bluray')",
"type": "string"
}
},
"required": [
"torrent_title",
"torrent_url",
"explanation"
],
"type": "object"
}
},
{
"description": "Query subscription status and list all user subscriptions. Shows active subscriptions, their download status, and configuration details.",
"name": "query_subscribes",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"status": {
"description": "Filter subscriptions by status: 'active' for enabled subscriptions, 'inactive' for disabled ones, 'all' for all subscriptions",
"type": "string"
},
"media_type": {
"description": "Filter by media type: 'movie' for films, 'tv' for television series, 'all' for all types",
"type": "string"
}
},
"required": [
"explanation"
],
"type": "object"
}
},
{
"description": "Query download status and list all active download tasks. Shows download progress, completion status, and task details from configured downloaders.",
"name": "query_downloads",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"downloader": {
"description": "Name of specific downloader to query (optional, if not provided queries all configured downloaders)",
"type": "string"
},
"status": {
"description": "Filter downloads by status: 'downloading' for active downloads, 'completed' for finished downloads, 'paused' for paused downloads, 'all' for all downloads",
"type": "string"
}
},
"required": [
"explanation"
],
"type": "object"
}
},
{
"description": "Query downloader configuration and list all available downloaders. Shows downloader status, connection details, and configuration settings.",
"name": "query_downloaders",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
}
},
"required": [
"explanation"
],
"type": "object"
}
},
{
"description": "Get trending and popular media recommendations from various sources. Returns curated lists of popular movies, TV shows, and anime based on different criteria like trending, ratings, or calendar schedules.",
"name": "get_recommendations",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"source": {
"description": "Recommendation source: 'tmdb_trending' for TMDB trending content, 'douban_hot' for Douban popular content, 'bangumi_calendar' for Bangumi anime calendar",
"type": "string"
},
"media_type": {
"description": "Type of media content: 'movie' for films, 'tv' for television series, 'all' for all types",
"type": "string"
},
"limit": {
"description": "Maximum number of recommendations to return (default: 20, maximum: 100)",
"type": "integer"
}
},
"required": [
"explanation"
],
"type": "object"
}
},
{
"description": "Query media library status and list all media files that have been successfully processed and added to the media server (Plex, Emby, Jellyfin). Shows library statistics and file details.",
"name": "query_media_library",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"media_type": {
"description": "Type of media content: 'movie' for films, 'tv' for television series, 'all' for all types",
"type": "string"
},
"title": {
"description": "Specific media title to search for (optional, if provided returns detailed info for that specific media)",
"type": "string"
},
"year": {
"description": "Release year of the media (optional, helps narrow down search results)",
"type": "string"
}
},
"required": [
"explanation"
],
"type": "object"
}
},
{
"description": "Send notification message to the user through configured notification channels (Telegram, Slack, WeChat, etc.). Used to inform users about operation results, errors, or important updates.",
"name": "send_message",
"parameters": {
"properties": {
"explanation": {
"description": "Clear explanation of why this tool is being used in the current context",
"type": "string"
},
"message": {
"description": "The message content to send to the user (should be clear and informative)",
"type": "string"
},
"message_type": {
"description": "Type of message: 'info' for general information, 'success' for successful operations, 'warning' for warnings, 'error' for error messages",
"type": "string"
}
},
"required": [
"message",
"explanation"
],
"type": "object"
}
}
]
+4 -4
View File
@@ -41,10 +41,10 @@ class MoviePilotTool(BaseTool):
"""发送工具消息""" """发送工具消息"""
ToolChain().post_message( ToolChain().post_message(
Notification( Notification(
channel=self.channel, channel=self._channel,
source=self.source, source=self._source,
userid=self.user_id, userid=self._user_id,
username=self.username, username=self._username,
title=title, title=title,
text=message text=message
) )
+16 -3
View File
@@ -1,6 +1,8 @@
"""添加下载工具""" """添加下载工具"""
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.chain.download import DownloadChain from app.chain.download import DownloadChain
@@ -10,11 +12,22 @@ from app.log import logger
from app.schemas import TorrentInfo from app.schemas import TorrentInfo
class AddDownloadInput(BaseModel):
"""添加下载工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
torrent_title: str = Field(..., description="The display name/title of the torrent (e.g., 'The.Matrix.1999.1080p.BluRay.x264')")
torrent_url: str = Field(..., description="Direct URL to the torrent file (.torrent) or magnet link")
downloader: Optional[str] = Field(None, description="Name of the downloader to use (optional, uses default if not specified)")
save_path: Optional[str] = Field(None, description="Directory path where the downloaded files should be saved (optional, uses default path if not specified)")
labels: Optional[str] = Field(None, description="Comma-separated list of labels/tags to assign to the download (optional, e.g., 'movie,hd,bluray')")
class AddDownloadTool(MoviePilotTool): class AddDownloadTool(MoviePilotTool):
name: str = "add_download" name: str = "add_download"
description: str = "添加下载任务,将搜索到的种子资源添加到下载器。" description: str = "Add torrent download task to the configured downloader (qBittorrent, Transmission, etc.). Downloads the torrent file and starts the download process with specified settings."
args_schema: Type[BaseModel] = AddDownloadInput
async def _arun(self, torrent_title: str, torrent_url: str, explanation: str, async def _arun(self, torrent_title: str, torrent_url: str,
downloader: Optional[str] = None, save_path: Optional[str] = None, downloader: Optional[str] = None, save_path: Optional[str] = None,
labels: Optional[str] = None, **kwargs) -> str: labels: Optional[str] = None, **kwargs) -> str:
logger.info( logger.info(
+16 -3
View File
@@ -1,6 +1,8 @@
"""添加订阅工具""" """添加订阅工具"""
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.chain.subscribe import SubscribeChain from app.chain.subscribe import SubscribeChain
@@ -8,11 +10,22 @@ from app.log import logger
from app.schemas.types import MediaType from app.schemas.types import MediaType
class AddSubscribeInput(BaseModel):
"""添加订阅工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
title: str = Field(..., description="The title of the media to subscribe to (e.g., 'The Matrix', 'Breaking Bad')")
year: str = Field(..., description="Release year of the media (required for accurate identification)")
media_type: str = Field(..., description="Type of media content: 'movie' for films, 'tv' for television series")
season: Optional[int] = Field(None, description="Season number for TV shows (optional, if not specified will subscribe to all seasons)")
tmdb_id: Optional[str] = Field(None, description="TMDB database ID for precise media identification (optional but recommended for accuracy)")
class AddSubscribeTool(MoviePilotTool): class AddSubscribeTool(MoviePilotTool):
name: str = "add_subscribe" name: str = "add_subscribe"
description: str = "添加媒体订阅,为用户感兴趣的媒体内容创建订阅规则。" description: str = "Add media subscription to create automated download rules for movies and TV shows. The system will automatically search and download new episodes or releases based on the subscription criteria."
args_schema: Type[BaseModel] = AddSubscribeInput
async def _arun(self, title: str, year: str, media_type: str, explanation: str, async def _arun(self, title: str, year: str, media_type: str,
season: Optional[int] = None, tmdb_id: Optional[str] = None, **kwargs) -> str: season: Optional[int] = None, tmdb_id: Optional[str] = None, **kwargs) -> str:
logger.info( logger.info(
f"执行工具: {self.name}, 参数: title={title}, year={year}, media_type={media_type}, season={season}, tmdb_id={tmdb_id}") f"执行工具: {self.name}, 参数: title={title}, year={year}, media_type={media_type}, season={season}, tmdb_id={tmdb_id}")
+14 -3
View File
@@ -1,18 +1,29 @@
"""获取推荐工具""" """获取推荐工具"""
import json import json
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.chain.recommend import RecommendChain from app.chain.recommend import RecommendChain
from app.log import logger from app.log import logger
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
class GetRecommendationsInput(BaseModel):
"""获取推荐工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
source: Optional[str] = Field("tmdb_trending", description="Recommendation source: 'tmdb_trending' for TMDB trending content, 'douban_hot' for Douban popular content, 'bangumi_calendar' for Bangumi anime calendar")
media_type: Optional[str] = Field("all", description="Type of media content: 'movie' for films, 'tv' for television series, 'all' for all types")
limit: Optional[int] = Field(20, description="Maximum number of recommendations to return (default: 20, maximum: 100)")
class GetRecommendationsTool(MoviePilotTool): class GetRecommendationsTool(MoviePilotTool):
name: str = "get_recommendations" name: str = "get_recommendations"
description: str = "获取热门媒体推荐,包括电影、电视剧等热门内容。" description: str = "Get trending and popular media recommendations from various sources. Returns curated lists of popular movies, TV shows, and anime based on different criteria like trending, ratings, or calendar schedules."
args_schema: Type[BaseModel] = GetRecommendationsInput
async def _arun(self, explanation: str, source: Optional[str] = "tmdb_trending", async def _arun(self, source: Optional[str] = "tmdb_trending",
media_type: Optional[str] = "all", limit: Optional[int] = 20, **kwargs) -> str: media_type: Optional[str] = "all", limit: Optional[int] = 20, **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: source={source}, media_type={media_type}, limit={limit}") logger.info(f"执行工具: {self.name}, 参数: source={source}, media_type={media_type}, limit={limit}")
try: try:
+11 -2
View File
@@ -1,6 +1,9 @@
"""查询下载器工具""" """查询下载器工具"""
import json import json
from typing import Type
from pydantic import BaseModel, Field
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.log import logger from app.log import logger
@@ -8,11 +11,17 @@ from app.schemas.types import SystemConfigKey
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
class QueryDownloadersInput(BaseModel):
"""查询下载器工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
class QueryDownloadersTool(MoviePilotTool): class QueryDownloadersTool(MoviePilotTool):
name: str = "query_downloaders" name: str = "query_downloaders"
description: str = "查询下载器配置,查看可用的下载器列表和配置信息。" description: str = "Query downloader configuration and list all available downloaders. Shows downloader status, connection details, and configuration settings."
args_schema: Type[BaseModel] = QueryDownloadersInput
async def _arun(self, explanation: str, **kwargs) -> str: async def _arun(self, **kwargs) -> str:
logger.info(f"执行工具: {self.name}") logger.info(f"执行工具: {self.name}")
try: try:
system_config_oper = SystemConfigOper() system_config_oper = SystemConfigOper()
+13 -3
View File
@@ -1,18 +1,28 @@
"""查询下载工具""" """查询下载工具"""
import json import json
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.chain.download import DownloadChain from app.chain.download import DownloadChain
from app.log import logger from app.log import logger
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
class QueryDownloadsInput(BaseModel):
"""查询下载工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
downloader: Optional[str] = Field(None, description="Name of specific downloader to query (optional, if not provided queries all configured downloaders)")
status: Optional[str] = Field("all", description="Filter downloads by status: 'downloading' for active downloads, 'completed' for finished downloads, 'paused' for paused downloads, 'all' for all downloads")
class QueryDownloadsTool(MoviePilotTool): class QueryDownloadsTool(MoviePilotTool):
name: str = "query_downloads" name: str = "query_downloads"
description: str = "查询下载状态,查看下载器的任务列表和进度。" description: str = "Query download status and list all active download tasks. Shows download progress, completion status, and task details from configured downloaders."
args_schema: Type[BaseModel] = QueryDownloadsInput
async def _arun(self, explanation: str, downloader: Optional[str] = None, async def _arun(self, downloader: Optional[str] = None,
status: Optional[str] = "all", **kwargs) -> str: status: Optional[str] = "all", **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: downloader={downloader}, status={status}") logger.info(f"执行工具: {self.name}, 参数: downloader={downloader}, status={status}")
try: try:
+14 -3
View File
@@ -1,7 +1,9 @@
"""查询媒体库工具""" """查询媒体库工具"""
import json import json
from typing import Optional, List from typing import Optional, List, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.db.mediaserver_oper import MediaServerOper from app.db.mediaserver_oper import MediaServerOper
@@ -9,11 +11,20 @@ from app.log import logger
from app.schemas import MediaServerItem from app.schemas import MediaServerItem
class QueryMediaLibraryInput(BaseModel):
"""查询媒体库工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
media_type: Optional[str] = Field("all", description="Type of media content: 'movie' for films, 'tv' for television series, 'all' for all types")
title: Optional[str] = Field(None, description="Specific media title to search for (optional, if provided returns detailed info for that specific media)")
year: Optional[str] = Field(None, description="Release year of the media (optional, helps narrow down search results)")
class QueryMediaLibraryTool(MoviePilotTool): class QueryMediaLibraryTool(MoviePilotTool):
name: str = "query_media_library" name: str = "query_media_library"
description: str = "查询媒体库状态,查看已入库的媒体文件情况。" description: str = "Query media library status and list all media files that have been successfully processed and added to the media server (Plex, Emby, Jellyfin). Shows library statistics and file details."
args_schema: Type[BaseModel] = QueryMediaLibraryInput
async def _arun(self, explanation: str, media_type: Optional[str] = "all", async def _arun(self, media_type: Optional[str] = "all",
title: Optional[str] = None, year: Optional[str] = None, **kwargs) -> str: title: Optional[str] = None, year: Optional[str] = None, **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: media_type={media_type}, title={title}") logger.info(f"执行工具: {self.name}, 参数: media_type={media_type}, title={title}")
try: try:
+13 -4
View File
@@ -1,19 +1,28 @@
"""查询订阅工具""" """查询订阅工具"""
import json import json
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.db.subscribe_oper import SubscribeOper from app.db.subscribe_oper import SubscribeOper
from app.log import logger from app.log import logger
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
class QuerySubscribesInput(BaseModel):
"""查询订阅工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
status: Optional[str] = Field("all", description="Filter subscriptions by status: 'active' for enabled subscriptions, 'inactive' for disabled ones, 'all' for all subscriptions")
media_type: Optional[str] = Field("all", description="Filter by media type: 'movie' for films, 'tv' for television series, 'all' for all types")
class QuerySubscribesTool(MoviePilotTool): class QuerySubscribesTool(MoviePilotTool):
name: str = "query_subscribes" name: str = "query_subscribes"
description: str = "查询订阅状态,查看用户的订阅列表和状态。" description: str = "Query subscription status and list all user subscriptions. Shows active subscriptions, their download status, and configuration details."
args_schema: Type[BaseModel] = QuerySubscribesInput
async def _arun(self, explanation: str, status: Optional[str] = "all", async def _arun(self, status: Optional[str] = "all", media_type: Optional[str] = "all", **kwargs) -> str:
media_type: Optional[str] = "all", **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: status={status}, media_type={media_type}") logger.info(f"执行工具: {self.name}, 参数: status={status}, media_type={media_type}")
try: try:
subscribe_oper = SubscribeOper() subscribe_oper = SubscribeOper()
+15 -3
View File
@@ -1,7 +1,9 @@
"""搜索媒体工具""" """搜索媒体工具"""
import json import json
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.chain.media import MediaChain from app.chain.media import MediaChain
@@ -9,11 +11,21 @@ from app.log import logger
from app.schemas.types import MediaType from app.schemas.types import MediaType
class SearchMediaInput(BaseModel):
"""搜索媒体工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
title: str = Field(..., description="The title of the media to search for (e.g., 'The Matrix', 'Breaking Bad')")
year: Optional[str] = Field(None, description="Release year of the media (optional, helps narrow down results)")
media_type: Optional[str] = Field(None, description="Type of media content: 'movie' for films, 'tv' for television series, 'anime' for anime series")
season: Optional[int] = Field(None, description="Season number for TV shows and anime (optional, only applicable for series)")
class SearchMediaTool(MoviePilotTool): class SearchMediaTool(MoviePilotTool):
name: str = "search_media" name: str = "search_media"
description: str = "搜索媒体资源,包括电影、电视剧、动漫等。可以根据标题、年份、类型等条件进行搜索。" description: str = "Search for media resources including movies, TV shows, anime, etc. Supports searching by title, year, type, and other criteria. Returns detailed media information from TMDB database."
args_schema: Type[BaseModel] = SearchMediaInput
async def _arun(self, title: str, explanation: str, year: Optional[str] = None, async def _arun(self, title: str, year: Optional[str] = None,
media_type: Optional[str] = None, season: Optional[int] = None, **kwargs) -> str: media_type: Optional[str] = None, season: Optional[int] = None, **kwargs) -> str:
logger.info( logger.info(
f"执行工具: {self.name}, 参数: title={title}, year={year}, media_type={media_type}, season={season}") f"执行工具: {self.name}, 参数: title={title}, year={year}, media_type={media_type}, season={season}")
+16 -3
View File
@@ -1,7 +1,9 @@
"""搜索种子工具""" """搜索种子工具"""
import json import json
from typing import List, Optional from typing import List, Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.chain.search import SearchChain from app.chain.search import SearchChain
@@ -9,11 +11,22 @@ from app.log import logger
from app.schemas.types import MediaType from app.schemas.types import MediaType
class SearchTorrentsInput(BaseModel):
"""搜索种子工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
title: str = Field(..., description="The title of the media resource to search for (e.g., 'The Matrix 1999', 'Breaking Bad S01E01')")
year: Optional[str] = Field(None, description="Release year of the media (optional, helps narrow down search results)")
media_type: Optional[str] = Field(None, description="Type of media content: 'movie' for films, 'tv' for television series")
season: Optional[int] = Field(None, description="Season number for TV shows (optional, only applicable for series)")
sites: Optional[List[int]] = Field(None, description="Array of specific site IDs to search on (optional, if not provided searches all configured sites)")
class SearchTorrentsTool(MoviePilotTool): class SearchTorrentsTool(MoviePilotTool):
name: str = "search_torrents" name: str = "search_torrents"
description: str = "搜索站点种子资源,根据媒体信息搜索可下载的种子文件。" description: str = "Search for torrent files across configured indexer sites based on media information. Returns available torrent downloads with details like file size, quality, and download links."
args_schema: Type[BaseModel] = SearchTorrentsInput
async def _arun(self, title: str, explanation: str, year: Optional[str] = None, async def _arun(self, title: str, year: Optional[str] = None,
media_type: Optional[str] = None, season: Optional[int] = None, media_type: Optional[str] = None, season: Optional[int] = None,
sites: Optional[List[int]] = None, **kwargs) -> str: sites: Optional[List[int]] = None, **kwargs) -> str:
logger.info( logger.info(
+13 -3
View File
@@ -1,16 +1,26 @@
"""发送消息工具""" """发送消息工具"""
from typing import Optional from typing import Optional, Type
from pydantic import BaseModel, Field
from app.agent.tools.base import MoviePilotTool from app.agent.tools.base import MoviePilotTool
from app.log import logger from app.log import logger
class SendMessageInput(BaseModel):
"""发送消息工具的输入参数模型"""
explanation: str = Field(..., description="Clear explanation of why this tool is being used in the current context")
message: str = Field(..., description="The message content to send to the user (should be clear and informative)")
message_type: Optional[str] = Field("info", description="Type of message: 'info' for general information, 'success' for successful operations, 'warning' for warnings, 'error' for error messages")
class SendMessageTool(MoviePilotTool): class SendMessageTool(MoviePilotTool):
name: str = "send_message" name: str = "send_message"
description: str = "发送消息通知,向用户发送操作结果或重要信息。" description: str = "Send notification message to the user through configured notification channels (Telegram, Slack, WeChat, etc.). Used to inform users about operation results, errors, or important updates."
args_schema: Type[BaseModel] = SendMessageInput
async def _arun(self, message: str, explanation: str, message_type: Optional[str] = "info", **kwargs) -> str: async def _arun(self, message: str, message_type: Optional[str] = None, **kwargs) -> str:
logger.info(f"执行工具: {self.name}, 参数: message={message}, message_type={message_type}") logger.info(f"执行工具: {self.name}, 参数: message={message}, message_type={message_type}")
try: try:
self.send_tool_message(message, title=message_type) self.send_tool_message(message, title=message_type)