diff --git a/app/runtime/event/contracts.py b/app/runtime/event/contracts.py index 5c1b05a29..709f293cc 100644 --- a/app/runtime/event/contracts.py +++ b/app/runtime/event/contracts.py @@ -9,7 +9,9 @@ from typing import Any from pydantic import BaseModel, ValidationError import app.schemas.event as event_schemas +from app.schemas.mediaserver import WebhookEventInfo from app.schemas.types import ChainEventType, EventType +from app.schemas.workflow import ActionContext class EventDelivery(StrEnum): @@ -53,6 +55,13 @@ class EventContract: _PAYLOAD_MODELS: dict[EventType | ChainEventType, type[BaseModel]] = { EventType.ConfigChanged: event_schemas.ConfigChangeEventData, + EventType.PluginReload: event_schemas.PluginReloadEventData, + EventType.PluginAction: event_schemas.PluginActionEventData, + EventType.PluginTriggered: event_schemas.PluginTriggeredEventData, + EventType.CommandExcute: event_schemas.CommandExecuteEventData, + EventType.SiteDeleted: event_schemas.SiteEventData, + EventType.SiteUpdated: event_schemas.SiteEventData, + EventType.SiteRefreshed: event_schemas.SiteEventData, EventType.AgentTokensUsage: event_schemas.AgentTokensUsageEventData, EventType.SubscribeAdded: event_schemas.SubscribeAddedEventData, EventType.SubscribeDeleted: event_schemas.SubscribeDeletedEventData, @@ -60,6 +69,22 @@ _PAYLOAD_MODELS: dict[EventType | ChainEventType, type[BaseModel]] = { EventType.DownloadAdded: event_schemas.DownloadAddedEventData, EventType.TransferComplete: event_schemas.TransferResultEventData, EventType.TransferFailed: event_schemas.TransferResultEventData, + EventType.SubtitleTransferComplete: event_schemas.TransferResultEventData, + EventType.SubtitleTransferFailed: event_schemas.TransferResultEventData, + EventType.AudioTransferComplete: event_schemas.TransferResultEventData, + EventType.AudioTransferFailed: event_schemas.TransferResultEventData, + EventType.HistoryDeleted: event_schemas.HistoryDeletedEventData, + EventType.DownloadFileDeleted: event_schemas.DownloadFileDeletedEventData, + EventType.DownloadDeleted: event_schemas.DownloadDeletedEventData, + EventType.UserMessage: event_schemas.UserMessageEventData, + EventType.WebhookMessage: WebhookEventInfo, + EventType.NoticeMessage: event_schemas.NoticeMessageEventData, + EventType.SubscribeComplete: event_schemas.SubscribeCompleteEventData, + EventType.SystemError: event_schemas.SystemErrorEventData, + EventType.MetadataScrape: event_schemas.MetadataScrapeEventData, + EventType.ModuleReload: event_schemas.EmptyEventData, + EventType.MessageAction: event_schemas.MessageActionEventData, + EventType.WorkflowExecute: event_schemas.WorkflowExecuteEventData, ChainEventType.PluginDataReset: event_schemas.PluginDataResetEventData, ChainEventType.AuthVerification: event_schemas.AuthCredentials, ChainEventType.AuthIntercept: event_schemas.AuthInterceptCredentials, @@ -77,6 +102,11 @@ _PAYLOAD_MODELS: dict[EventType | ChainEventType, type[BaseModel]] = { ChainEventType.AgentLLMProvider: event_schemas.AgentLLMProviderEventData, ChainEventType.SubscribeEpisodesRefresh: event_schemas.SubscribeEpisodesRefreshEventData, ChainEventType.SubscribeCompletionCheck: event_schemas.SubscribeCompletionCheckEventData, + ChainEventType.NameRecognize: event_schemas.NameRecognizeEventData, + ChainEventType.MusicNameRecognize: event_schemas.MusicNameRecognizeEventData, + ChainEventType.MediaRecognize: event_schemas.MediaRecognizeEventData, + ChainEventType.MusicMediaRecognize: event_schemas.MusicMediaRecognizeEventData, + ChainEventType.WorkflowExecution: ActionContext, } _DURABLE_REQUIRED = { diff --git a/app/runtime/extensions/module/contracts.py b/app/runtime/extensions/module/contracts.py index e99194f4d..2adf488de 100644 --- a/app/runtime/extensions/module/contracts.py +++ b/app/runtime/extensions/module/contracts.py @@ -83,7 +83,7 @@ _METHOD_CONTRACTS = { "get_folder": ModuleMethodContract(family="storage", input_contract="StorageFolderRequest", result_contract="FileItem | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("storage", "path")), "get_parent_item": ModuleMethodContract(family="storage", input_contract="StorageParentRequest", result_contract="FileItem | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("fileitem",)), "rename_file": ModuleMethodContract(family="storage", input_contract="StorageRenameRequest", result_contract="bool | FileItem", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("fileitem", "name")), - "storage_manage": ModuleMethodContract(family="storage", input_contract="StorageManageRequest", result_contract="Any", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("storage", "action")), + "storage_manage": ModuleMethodContract(family="storage", input_contract="StorageManageRequest", result_contract="StorageProviderResult", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("storage", "action")), "snapshot_storage": ModuleMethodContract(family="storage", input_contract="StorageSnapshotRequest", result_contract="dict[str, dict] | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("storage", "path", "last_snapshot_time", "max_depth", "previous_snapshot")), "send_message": ModuleMethodContract(family="messaging", input_contract="MessageSendRequest", result_contract="Message | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY), "finalize_message": ModuleMethodContract(family="messaging", input_contract="MessageFinalizeRequest", result_contract="Message | None", aggregation=ModuleResultAggregation.FIRST_NON_EMPTY, required_parameters=("response",)), @@ -107,6 +107,318 @@ _PREFIX_CONTRACTS = ( ) +# 宿主静态扫描到的全部字符串能力名。第三方插件仍可声明未在这里出现的自定义方法, +# 自定义方法继续走开放的 legacy contract;宿主新增调用则必须先进入本清单。 +_OBSERVED_HOST_METHODS = ( + 'anilist_credits', + 'anilist_discover', + 'anilist_info', + 'anilist_person_credits', + 'anilist_person_detail', + 'anilist_popular_this_season', + 'anilist_recommendations', + 'anilist_trending', + 'any_files', + 'async_anilist_credits', + 'async_anilist_discover', + 'async_anilist_info', + 'async_anilist_person_credits', + 'async_anilist_person_detail', + 'async_anilist_popular_this_season', + 'async_anilist_recommendations', + 'async_anilist_trending', + 'async_bangumi_calendar', + 'async_bangumi_credits', + 'async_bangumi_discover', + 'async_bangumi_info', + 'async_bangumi_person_credits', + 'async_bangumi_person_detail', + 'async_bangumi_recommend', + 'async_douban_discover', + 'async_douban_info', + 'async_douban_movie_credits', + 'async_douban_movie_recommend', + 'async_douban_person_credits', + 'async_douban_person_detail', + 'async_douban_tv_credits', + 'async_douban_tv_recommend', + 'async_identify_music_by_fingerprint', + 'async_match_doubaninfo', + 'async_match_music_album', + 'async_match_tmdbinfo', + 'async_movie_hot', + 'async_movie_showing', + 'async_movie_top250', + 'async_obtain_images', + 'async_recognize_media', + 'async_refresh_torrents', + 'async_search_collections', + 'async_search_medias', + 'async_search_persons', + 'async_search_subtitles', + 'async_search_torrents', + 'async_tmdb_collection', + 'async_tmdb_discover', + 'async_tmdb_episodes', + 'async_tmdb_group_seasons', + 'async_tmdb_info', + 'async_tmdb_movie_credits', + 'async_tmdb_movie_recommend', + 'async_tmdb_movie_similar', + 'async_tmdb_person_credits', + 'async_tmdb_person_detail', + 'async_tmdb_seasons', + 'async_tmdb_trending', + 'async_tmdb_tv_credits', + 'async_tmdb_tv_recommend', + 'async_tmdb_tv_similar', + 'async_tv_animation', + 'async_tv_hot', + 'async_tv_weekly_chinese', + 'async_tv_weekly_global', + 'async_update_recognize_cache', + 'bangumi_calendar', + 'bangumi_credits', + 'bangumi_discover', + 'bangumi_info', + 'bangumi_person_credits', + 'bangumi_person_detail', + 'bangumi_recommend', + 'channel_manage', + 'clear_cache', + 'create_folder', + 'delete_file', + 'delete_message', + 'douban_discover', + 'douban_info', + 'douban_movie_credits', + 'douban_movie_recommend', + 'douban_person_credits', + 'douban_person_detail', + 'douban_tv_credits', + 'douban_tv_recommend', + 'download', + 'download_added', + 'download_discord_file_bytes', + 'download_feishu_file_bytes', + 'download_feishu_image_to_data_url', + 'download_file', + 'download_qq_file_bytes', + 'download_slack_file_bytes', + 'download_slack_file_to_data_url', + 'download_synologychat_file_bytes', + 'download_telegram_file_bytes', + 'download_telegram_file_to_base64', + 'download_vocechat_file_bytes', + 'download_vocechat_image_to_data_url', + 'download_wechat_image_to_data_url', + 'download_wechat_media_bytes', + 'downloader_info', + 'edit_message', + 'filter_torrents', + 'finalize_message', + 'get_file_item', + 'get_folder', + 'get_parent_item', + 'get_search_page_size', + 'get_torrent_trackers', + 'identify_music_by_fingerprint', + 'list_files', + 'list_torrents', + 'load_category_config', + 'mark_message_processing_finished', + 'mark_message_processing_started', + 'match_doubaninfo', + 'match_music_album', + 'match_tmdbinfo', + 'media_category', + 'media_exists', + 'media_files', + 'media_statistic', + 'mediaserver_image_cookies', + 'mediaserver_iteminfo', + 'mediaserver_items', + 'mediaserver_items_count', + 'mediaserver_latest', + 'mediaserver_latest_images', + 'mediaserver_librarys', + 'mediaserver_play_url', + 'mediaserver_playing', + 'mediaserver_season_episode_ids', + 'mediaserver_tv_episodes', + 'message_parser', + 'metadata_img', + 'metadata_nfo', + 'movie_hot', + 'movie_showing', + 'movie_top250', + 'music_album', + 'music_album_related', + 'music_artist', + 'music_artist_albums', + 'music_artist_related', + 'music_cache_clear', + 'music_cache_delete', + 'music_cache_items', + 'music_chart', + 'music_discover', + 'music_fresh_releases', + 'music_lyrics', + 'obtain_images', + 'obtain_specific_image', + 'recognize_media', + 'recommend_name', + 'refresh_torrents', + 'refresh_userdata', + 'register_commands', + 'remove_torrents', + 'rename_file', + 'save_category_config', + 'scheduler_job', + 'search_collections', + 'search_medias', + 'search_music', + 'search_persons', + 'search_subtitles', + 'search_torrents', + 'search_tvdb', + 'send_direct_message', + 'set_torrents_tag', + 'site_subtitle_links', + 'snapshot_storage', + 'start_torrents', + 'stop_torrents', + 'storage_manage', + 'tmdb_cache_clear', + 'tmdb_cache_delete', + 'tmdb_cache_items', + 'tmdb_collection', + 'tmdb_discover', + 'tmdb_episodes', + 'tmdb_group_seasons', + 'tmdb_info', + 'tmdb_movie_credits', + 'tmdb_movie_recommend', + 'tmdb_movie_similar', + 'tmdb_person_credits', + 'tmdb_person_detail', + 'tmdb_seasons', + 'tmdb_trending', + 'tmdb_tv_credits', + 'tmdb_tv_recommend', + 'tmdb_tv_similar', + 'torrent_files', + 'transfer', + 'transfer_completed', + 'tv_animation', + 'tv_hot', + 'tv_weekly_chinese', + 'tv_weekly_global', + 'tvdb_info', + 'tvdb_slug', + 'update_recognize_cache', + 'update_torrent', + 'upload_file', + 'user_authenticate', + 'webhook_parser', +) + +_FAMILY_IO_CONTRACTS = { + "anilist": ("AniListKeywordArguments", "AniListProviderResult"), + "authentication": ("AuthenticationKeywordArguments", "AuthenticationResult"), + "bangumi": ("BangumiKeywordArguments", "BangumiProviderResult"), + "category": ("CategoryKeywordArguments", "CategoryProviderResult"), + "douban": ("DoubanKeywordArguments", "DoubanProviderResult"), + "downloader": ("DownloaderKeywordArguments", "DownloaderProviderResult"), + "integration": ("IntegrationKeywordArguments", "IntegrationProviderResult"), + "media-discovery": ("MediaDiscoveryKeywordArguments", "MediaDiscoveryProviderResult"), + "media-recognition": ("MediaRecognitionKeywordArguments", "MediaRecognitionProviderResult"), + "media-server": ("MediaServerKeywordArguments", "MediaServerProviderResult"), + "messaging": ("MessagingKeywordArguments", "MessagingProviderResult"), + "metadata": ("MetadataKeywordArguments", "MetadataProviderResult"), + "music": ("MusicKeywordArguments", "MusicProviderResult"), + "site": ("SiteKeywordArguments", "SiteProviderResult"), + "storage": ("StorageKeywordArguments", "StorageProviderResult"), + "tmdb": ("TmdbKeywordArguments", "TmdbProviderResult"), + "tvdb": ("TvdbKeywordArguments", "TvdbProviderResult"), +} + + +def _infer_observed_family(method: str) -> str: + """按稳定能力前缀把已观察宿主方法归入可审计的输入/结果族。""" + for prefix, contract in _PREFIX_CONTRACTS: + if method.startswith(prefix): + return contract.family + if method.startswith(("mediaserver_", "media_exists", "media_statistic")): + return "media-server" + if method.startswith(( + "download", "torrent_", "list_torrents", "refresh_torrents", + "remove_torrents", "start_torrents", "stop_torrents", + "set_torrents_tag", "update_torrent", "get_torrent_trackers", + "downloader_info", "filter_torrents", "transfer_completed", + )): + return "downloader" + if method.startswith(( + "channel_", "delete_message", "edit_message", "finalize_message", + "mark_message_", "message_parser", "register_commands", + "send_direct_message", "send_message", + )): + return "messaging" + if method.startswith(( + "any_files", "create_folder", "delete_file", "get_file_item", + "get_folder", "get_parent_item", "list_files", "media_files", + "rename_file", "snapshot_storage", "storage_manage", "transfer", + "upload_file", + )): + return "storage" + if method.startswith(( + "metadata_", "obtain_specific_image", "recommend_name", + )): + return "metadata" + if method.startswith(( + "async_identify_music", "async_match_music", "identify_music", + "match_music", "search_music", + )): + return "music" + if method.startswith(( + "async_match_", "async_obtain_images", "async_recognize_media", + "async_update_recognize_cache", "match_", "obtain_images", + "recognize_media", "update_recognize_cache", + )): + return "media-recognition" + if method.startswith(( + "async_movie_", "async_search_", "async_tv_", "movie_", + "search_collections", "search_medias", "search_persons", + "search_subtitles", "search_torrents", "tv_", + )): + return "media-discovery" + if method in {"clear_cache", "load_category_config", "save_category_config"}: + return "category" + if method in {"get_search_page_size", "refresh_userdata", "site_subtitle_links"}: + return "site" + if method == "user_authenticate": + return "authentication" + return "integration" + + +def _register_observed_host_contracts() -> None: + """为全部宿主字符串调用登记完整 V2 字段,保留未知插件方法的 legacy fallback。""" + for method in _OBSERVED_HOST_METHODS: + if method in _METHOD_CONTRACTS: + continue + family = _infer_observed_family(method) + input_contract, result_contract = _FAMILY_IO_CONTRACTS[family] + _METHOD_CONTRACTS[method] = ModuleMethodContract( + family=family, + input_contract=input_contract, + result_contract=result_contract, + ) + + +_register_observed_host_contracts() + + + def get_module_method_contract(method: str) -> ModuleMethodContract: """返回方法的显式能力族契约,未知方法保持既有 legacy 协议。""" if contract := _METHOD_CONTRACTS.get(method): diff --git a/app/schemas/event.py b/app/schemas/event.py index 19febb0b8..0c16cec31 100644 --- a/app/schemas/event.py +++ b/app/schemas/event.py @@ -1,7 +1,7 @@ from pathlib import Path from typing import Iterable, Optional, Dict, Any, List, Set, Callable -from pydantic import BaseModel, Field, field_validator, model_validator +from pydantic import BaseModel, ConfigDict, Field, field_validator, model_validator from app.schemas.common import JsonData from app.schemas.types import MediaType, NotificationChannel @@ -29,6 +29,190 @@ class BaseEventData(BaseModel): pass +class ExtensibleEventData(BaseEventData): + """允许第三方插件附加字段的类型化事件载荷基类。""" + + model_config = ConfigDict(extra="allow", arbitrary_types_allowed=True) + + +class EmptyEventData(ExtensibleEventData): + """当前没有固定字段、但仍需进入 typed registry 的事件载荷。""" + + +class PluginReloadEventData(ExtensibleEventData): + """插件重载广播事件载荷。""" + + plugin_id: str = Field(description="重载的插件 ID") + + +class PluginActionEventData(ExtensibleEventData): + """插件命令动作载荷;具体动作参数由目标插件扩展。""" + + plugin_id: Optional[str] = Field(default=None, description="目标插件 ID") + action: Optional[str] = Field(default=None, description="插件动作名称") + channel: Optional[str] = Field(default=None, description="消息渠道") + source: Optional[str] = Field(default=None, description="消息来源") + user: Optional[Any] = Field(default=None, description="发起用户") + + +class PluginTriggeredEventData(ExtensibleEventData): + """插件主动发布的跨插件事件载荷。""" + + plugin_id: str = Field(description="发布事件的插件 ID") + event_name: str = Field(description="插件定义的稳定事件名") + data: Any = Field(default=None, description="插件定义的事件数据") + + +class CommandExecuteEventData(ExtensibleEventData): + """斜杠命令执行事件载荷。""" + + cmd: str = Field(description="包含参数的完整命令文本") + user: Optional[Any] = Field(default=None, description="发起用户") + channel: Optional[str] = Field(default=None, description="消息渠道") + source: Optional[str] = Field(default=None, description="消息来源") + processing_status: Optional[Any] = Field(default=None, description="交互处理状态") + + +class SiteEventData(ExtensibleEventData): + """站点新增、更新、删除或数据刷新事件载荷。""" + + site_id: Optional[int | str] = Field(default=None, description="站点 ID 或通配符") + domain: Optional[str] = Field(default=None, description="站点域名") + name: Optional[str] = Field(default=None, description="站点名称") + site_url: Optional[str] = Field(default=None, description="站点地址") + + +class HistoryDeletedEventData(ExtensibleEventData): + """历史记录删除事件的兼容载荷。""" + + history_id: Optional[int] = Field(default=None, description="历史记录 ID") + src: Optional[str] = Field(default=None, description="关联源路径") + + +class DownloadFileDeletedEventData(ExtensibleEventData): + """下载源文件删除事件载荷。""" + + src: Optional[str] = Field(default=None, description="已删除的下载源路径") + hash: Optional[str] = Field(default=None, description="下载任务 hash") + + +class DownloadDeletedEventData(ExtensibleEventData): + """下载任务删除事件载荷。""" + + hash: str = Field(description="下载任务 hash") + torrents: List[Dict[str, Any]] = Field(default_factory=list, description="删除前任务快照") + + +class UserMessageEventData(ExtensibleEventData): + """未被宿主命令或交互消费的用户文本消息载荷。""" + + text: str = Field(description="用户文本") + userid: Optional[Any] = Field(default=None, description="用户 ID") + channel: Optional[str] = Field(default=None, description="消息渠道") + source: Optional[str] = Field(default=None, description="消息来源") + chat_id: Optional[Any] = Field(default=None, description="会话 ID") + reply_to_message_id: Optional[Any] = Field(default=None, description="回复消息 ID") + + +class NoticeMessageEventData(ExtensibleEventData): + """宿主向消息模块发送的通知事件载荷。""" + + type: Optional[Any] = Field(default=None, description="兼容消息类型") + title: Optional[str] = Field(default=None, description="消息标题") + text: Optional[str] = Field(default=None, description="消息正文") + userid: Optional[Any] = Field(default=None, description="目标用户 ID") + channel: Optional[Any] = Field(default=None, description="目标消息渠道") + source: Optional[str] = Field(default=None, description="消息来源") + + +class SubscribeCompleteEventData(ExtensibleEventData): + """订阅完成广播事件载荷。""" + + subscribe_id: int = Field(description="已完成订阅 ID") + subscribe_info: Dict[str, Any] = Field(default_factory=dict, description="订阅快照") + mediainfo: Dict[str, Any] = Field(default_factory=dict, description="媒体信息快照") + + +class SystemErrorEventData(ExtensibleEventData): + """事件、模块、插件或调度器错误的宿主诊断载荷。""" + + type: str = Field(description="错误来源类别") + error: str = Field(description="错误摘要") + traceback: Optional[str] = Field(default=None, description="错误堆栈") + + +class MetadataScrapeEventData(ExtensibleEventData): + """媒体文件元数据刮削事件载荷。""" + + fileitem: FileItem = Field(description="待刮削目录或文件项") + file_list: List[str] = Field(default_factory=list, description="待刮削文件清单") + meta: Any = Field(default=None, description="文件名解析对象") + mediainfo: Any = Field(default=None, description="媒体信息对象") + overwrite: bool = Field(default=False, description="是否覆盖已有元数据") + file_contexts: List[Any] = Field(default_factory=list, description="逐文件上下文") + + +class MessageActionEventData(ExtensibleEventData): + """定向插件消息交互动作载荷。""" + + plugin_id: Optional[str] = Field(default=None, description="目标插件 ID") + text: Optional[str] = Field(default=None, description="兼容动作文本") + input_text: Optional[str] = Field(default=None, description="用户输入文本") + userid: Optional[Any] = Field(default=None, description="用户 ID") + channel: Optional[str] = Field(default=None, description="消息渠道") + source: Optional[str] = Field(default=None, description="消息来源") + input_session_id: Optional[str] = Field(default=None, description="输入会话 ID") + payload: Any = Field(default=None, description="插件自定义交互数据") + + +class WorkflowExecuteEventData(ExtensibleEventData): + """请求执行指定工作流的事件载荷。""" + + workflow_id: int = Field(description="工作流 ID") + + +class NameRecognizeEventData(ExtensibleEventData): + """影视名称辅助识别的输入和插件回写字段。""" + + title: str = Field(description="待识别标题") + name: Optional[str] = Field(default=None, description="插件识别后的名称") + year: Optional[Any] = Field(default=None, description="年份") + season: Optional[Any] = Field(default=None, description="季号") + episode: Optional[Any] = Field(default=None, description="集号") + + +class MusicNameRecognizeEventData(ExtensibleEventData): + """音乐名称辅助识别的输入和插件回写字段。""" + + title: str = Field(description="待识别曲名") + artist: Optional[str] = Field(default=None, description="艺术家") + album: Optional[str] = Field(default=None, description="专辑") + year: Optional[Any] = Field(default=None, description="年份") + duration: Optional[Any] = Field(default=None, description="时长") + name: Optional[str] = Field(default=None, description="插件识别后的曲名") + + +class MediaRecognizeEventData(ExtensibleEventData): + """影视媒体身份补充识别的输入和插件回写字段。""" + + title: Optional[str] = Field(default=None, description="待识别标题") + year: Optional[Any] = Field(default=None, description="年份") + season: Optional[Any] = Field(default=None, description="季号") + type: Optional[Any] = Field(default=None, description="媒体类型") + media_source: Optional[Any] = Field(default=None, description="媒体数据源") + media_id: Optional[Any] = Field(default=None, description="数据源原生 ID") + mediainfo: Optional[Dict[str, Any]] = Field(default=None, description="插件回写媒体信息") + + +class MusicMediaRecognizeEventData(MediaRecognizeEventData): + """音乐媒体身份补充识别的输入和插件回写字段。""" + + artists: List[str] = Field(default_factory=list, description="艺术家列表") + album: Optional[str] = Field(default=None, description="专辑") + isrc: Optional[str] = Field(default=None, description="ISRC") + music_type: Optional[str] = Field(default=None, description="音乐实体类型") + + class ConfigChangeEventData(BaseEventData): """ ConfigChange 事件的数据模型 diff --git a/app/schemas/exports.py b/app/schemas/exports.py index 3202eaf92..25e8d04f1 100644 --- a/app/schemas/exports.py +++ b/app/schemas/exports.py @@ -65,6 +65,7 @@ SCHEMA_EXPORTS = { 'ChannelCapability': ('app.schemas.notification', 'ChannelCapability'), 'ChannelCapabilityManager': ('app.schemas.notification', 'ChannelCapabilityManager'), 'ClassVar': ('app.schemas.subscribe', 'ClassVar'), + 'CommandExecuteEventData': ('app.schemas.event', 'CommandExecuteEventData'), 'CommandRegisterEventData': ('app.schemas.event', 'CommandRegisterEventData'), 'ConfigChangeEventData': ('app.schemas.event', 'ConfigChangeEventData'), 'ConfigDict': ('app.schemas.workflow', 'ConfigDict'), @@ -86,7 +87,9 @@ SCHEMA_EXPORTS = { 'Discriminator': ('app.schemas.context', 'Discriminator'), 'DownloadAddedData': ('app.schemas.download', 'DownloadAddedData'), 'DownloadAddedEventData': ('app.schemas.event', 'DownloadAddedEventData'), + 'DownloadDeletedEventData': ('app.schemas.event', 'DownloadDeletedEventData'), 'DownloadDirectory': ('app.schemas.download', 'DownloadDirectory'), + 'DownloadFileDeletedEventData': ('app.schemas.event', 'DownloadFileDeletedEventData'), 'DownloadHistory': ('app.schemas.history', 'DownloadHistory'), 'DownloadTask': ('app.schemas.workflow', 'DownloadTask'), 'DownloadTaskMedia': ('app.schemas.transfer', 'DownloadTaskMedia'), @@ -94,6 +97,7 @@ SCHEMA_EXPORTS = { 'DownloaderInfo': ('app.schemas.dashboard', 'DownloaderInfo'), 'DownloaderTorrent': ('app.schemas.transfer', 'DownloaderTorrent'), 'DownloadingTorrent': ('app.schemas.transfer', 'DownloadingTorrent'), + 'EmptyEventData': ('app.schemas.event', 'EmptyEventData'), 'EndpointStats': ('app.schemas.monitoring', 'EndpointStats'), 'Enum': ('app.schemas.notification', 'Enum'), 'EpisodeFormat': ('app.schemas.transfer', 'EpisodeFormat'), @@ -103,12 +107,14 @@ SCHEMA_EXPORTS = { 'ErrorRequest': ('app.schemas.monitoring', 'ErrorRequest'), 'Event': ('app.schemas.event', 'Event'), 'ExistMediaInfo': ('app.schemas.mediaserver', 'ExistMediaInfo'), + 'ExtensibleEventData': ('app.schemas.event', 'ExtensibleEventData'), 'Field': ('app.schemas.mcp', 'Field'), 'FileItem': ('app.schemas.workflow', 'FileItem'), 'FileNameData': ('app.schemas.common', 'FileNameData'), 'FileURI': ('app.schemas.file', 'FileURI'), 'FilterRuleGroup': ('app.schemas.system', 'FilterRuleGroup'), 'Generic': ('app.schemas.response', 'Generic'), + 'HistoryDeletedEventData': ('app.schemas.event', 'HistoryDeletedEventData'), 'IdData': ('app.schemas.common', 'IdData'), 'ImmediateException': ('app.schemas.exception', 'ImmediateException'), 'IncomingMessage': ('app.schemas.message', 'IncomingMessage'), @@ -173,6 +179,7 @@ SCHEMA_EXPORTS = { 'MediaLanguage': ('app.schemas.context', 'MediaLanguage'), 'MediaPerson': ('app.schemas.context', 'MediaPerson'), 'MediaRecognizeConvertEventData': ('app.schemas.event', 'MediaRecognizeConvertEventData'), + 'MediaRecognizeEventData': ('app.schemas.event', 'MediaRecognizeEventData'), 'MediaReleaseDate': ('app.schemas.context', 'MediaReleaseDate'), 'MediaSearchResult': ('app.schemas.context', 'MediaSearchResult'), 'MediaSearchResults': ('app.schemas.context', 'MediaSearchResults'), @@ -190,6 +197,7 @@ SCHEMA_EXPORTS = { 'MediaSourceInfo': ('app.schemas.event', 'MediaSourceInfo'), 'MediaType': ('app.schemas.subscribe', 'MediaType'), 'Message': ('app.schemas.message', 'Message'), + 'MessageActionEventData': ('app.schemas.event', 'MessageActionEventData'), 'MessageClearBefore': ('app.schemas.message', 'MessageClearBefore'), 'MessageClearData': ('app.schemas.message', 'MessageClearData'), 'MessageClearScope': ('app.schemas.message', 'MessageClearScope'), @@ -197,6 +205,7 @@ SCHEMA_EXPORTS = { 'MessageResponse': ('app.schemas.message', 'MessageResponse'), 'MessageType': ('app.schemas.message', 'MessageType'), 'MetaInfo': ('app.schemas.transfer', 'MetaInfo'), + 'MetadataScrapeEventData': ('app.schemas.event', 'MetadataScrapeEventData'), 'MfaChallenge': ('app.schemas.token', 'MfaChallenge'), 'MfaStatusData': ('app.schemas.mfa', 'MfaStatusData'), 'MonitoringConfig': ('app.schemas.monitoring', 'MonitoringConfig'), @@ -205,16 +214,20 @@ SCHEMA_EXPORTS = { 'MusicArtistInfo': ('app.schemas.music', 'MusicArtistInfo'), 'MusicEntityType': ('app.schemas.music', 'MusicEntityType'), 'MusicInfo': ('app.schemas.transfer', 'MusicInfo'), + 'MusicMediaRecognizeEventData': ('app.schemas.event', 'MusicMediaRecognizeEventData'), 'MusicMeta': ('app.schemas.transfer', 'MusicMeta'), + 'MusicNameRecognizeEventData': ('app.schemas.event', 'MusicNameRecognizeEventData'), 'MusicRecognitionCacheData': ('app.schemas.music', 'MusicRecognitionCacheData'), 'MusicRecognitionCacheItem': ('app.schemas.music', 'MusicRecognitionCacheItem'), 'MusicRecognizeRequest': ('app.schemas.music', 'MusicRecognizeRequest'), 'MusicRelease': ('app.schemas.music', 'MusicRelease'), 'MusicTargetEntityType': ('app.schemas.transfer', 'MusicTargetEntityType'), 'NameData': ('app.schemas.common', 'NameData'), + 'NameRecognizeEventData': ('app.schemas.event', 'NameRecognizeEventData'), 'NameValueOption': ('app.schemas.workflow', 'NameValueOption'), 'NetTestTarget': ('app.schemas.system', 'NetTestTarget'), 'NotExistMediaInfo': ('app.schemas.mediaserver', 'NotExistMediaInfo'), + 'NoticeMessageEventData': ('app.schemas.event', 'NoticeMessageEventData'), 'NotificationChannel': ('app.schemas.notification', 'NotificationChannel'), 'NotificationConf': ('app.schemas.system', 'NotificationConf'), 'NotificationSwitch': ('app.schemas.message', 'NotificationSwitch'), @@ -246,6 +259,7 @@ SCHEMA_EXPORTS = { 'Path': ('app.schemas.transfer', 'Path'), 'PerformanceSnapshot': ('app.schemas.monitoring', 'PerformanceSnapshot'), 'Plugin': ('app.schemas.plugin', 'Plugin'), + 'PluginActionEventData': ('app.schemas.event', 'PluginActionEventData'), 'PluginCloneRequest': ('app.schemas.plugin', 'PluginCloneRequest'), 'PluginDashboard': ('app.schemas.plugin', 'PluginDashboard'), 'PluginDashboardMetaItem': ('app.schemas.plugin', 'PluginDashboardMetaItem'), @@ -261,10 +275,12 @@ SCHEMA_EXPORTS = { 'PluginRatingRequest': ('app.schemas.plugin', 'PluginRatingRequest'), 'PluginReleaseData': ('app.schemas.plugin', 'PluginReleaseData'), 'PluginReleaseItem': ('app.schemas.plugin', 'PluginReleaseItem'), + 'PluginReloadEventData': ('app.schemas.event', 'PluginReloadEventData'), 'PluginRemoteInfo': ('app.schemas.plugin', 'PluginRemoteInfo'), 'PluginRuntimeStatus': ('app.schemas.plugin', 'PluginRuntimeStatus'), 'PluginRuntimeSummary': ('app.schemas.plugin', 'PluginRuntimeSummary'), 'PluginSidebarNavItem': ('app.schemas.plugin', 'PluginSidebarNavItem'), + 'PluginTriggeredEventData': ('app.schemas.event', 'PluginTriggeredEventData'), 'PluginWorkflowActionGroup': ('app.schemas.workflow', 'PluginWorkflowActionGroup'), 'ProcessInfo': ('app.schemas.dashboard', 'ProcessInfo'), 'ProgressKeyData': ('app.schemas.common', 'ProgressKeyData'), @@ -304,6 +320,7 @@ SCHEMA_EXPORTS = { 'SiteAuth': ('app.schemas.site', 'SiteAuth'), 'SiteCategory': ('app.schemas.site', 'SiteCategory'), 'SiteCookieUpdate': ('app.schemas.site', 'SiteCookieUpdate'), + 'SiteEventData': ('app.schemas.event', 'SiteEventData'), 'SiteIconData': ('app.schemas.site', 'SiteIconData'), 'SiteMappingData': ('app.schemas.site', 'SiteMappingData'), 'SiteStatistic': ('app.schemas.site', 'SiteStatistic'), @@ -327,6 +344,7 @@ SCHEMA_EXPORTS = { 'SubscrbieInfo': ('app.schemas.subscribe', 'SubscrbieInfo'), 'Subscribe': ('app.schemas.workflow', 'Subscribe'), 'SubscribeAddedEventData': ('app.schemas.event', 'SubscribeAddedEventData'), + 'SubscribeCompleteEventData': ('app.schemas.event', 'SubscribeCompleteEventData'), 'SubscribeCompletionCheckEventData': ('app.schemas.event', 'SubscribeCompletionCheckEventData'), 'SubscribeDeletedEventData': ('app.schemas.event', 'SubscribeDeletedEventData'), 'SubscribeDownloadFileInfo': ('app.schemas.subscribe', 'SubscribeDownloadFileInfo'), @@ -341,6 +359,7 @@ SCHEMA_EXPORTS = { 'SubtitleDownloadData': ('app.schemas.download', 'SubtitleDownloadData'), 'SubtitleInfo': ('app.schemas.search', 'SubtitleInfo'), 'SystemEnvironmentUpdateData': ('app.schemas.system', 'SystemEnvironmentUpdateData'), + 'SystemErrorEventData': ('app.schemas.event', 'SystemErrorEventData'), 'SystemModuleInfo': ('app.schemas.system', 'SystemModuleInfo'), 'SystemModuleListData': ('app.schemas.system', 'SystemModuleListData'), 'TMDbException': ('app.schemas.exception', 'TMDbException'), @@ -386,6 +405,7 @@ SCHEMA_EXPORTS = { 'UserInDB': ('app.schemas.user', 'UserInDB'), 'UserInDBBase': ('app.schemas.user', 'UserInDBBase'), 'UserMessage': ('app.schemas.agent', 'UserMessage'), + 'UserMessageEventData': ('app.schemas.event', 'UserMessageEventData'), 'UserPermissions': ('app.schemas.user', 'UserPermissions'), 'UserUpdate': ('app.schemas.user', 'UserUpdate'), 'ValidationIssue': ('app.schemas.response', 'ValidationIssue'), @@ -397,6 +417,7 @@ SCHEMA_EXPORTS = { 'WechatClawBotKnownTarget': ('app.schemas.notification', 'WechatClawBotKnownTarget'), 'Workflow': ('app.schemas.workflow', 'Workflow'), 'WorkflowActionDefinition': ('app.schemas.workflow', 'WorkflowActionDefinition'), + 'WorkflowExecuteEventData': ('app.schemas.event', 'WorkflowExecuteEventData'), 'WorkflowExecutionConfig': ('app.schemas.workflow', 'WorkflowExecutionConfig'), 'WorkflowExecutionState': ('app.schemas.workflow', 'WorkflowExecutionState'), 'WorkflowNodeState': ('app.schemas.workflow', 'WorkflowNodeState'), @@ -415,7 +436,7 @@ SCHEMA_EXPORTS = { SCHEMA_CONFLICTS = { 'Any': ['app.schemas.common', 'app.schemas.context', 'app.schemas.event', 'app.schemas.mediaserver', 'app.schemas.message', 'app.schemas.response', 'app.schemas.subscribe', 'app.schemas.system', 'app.schemas.workflow'], 'BaseModel': ['app.schemas.agent', 'app.schemas.cache', 'app.schemas.category', 'app.schemas.common', 'app.schemas.context', 'app.schemas.dashboard', 'app.schemas.download', 'app.schemas.event', 'app.schemas.file', 'app.schemas.history', 'app.schemas.llm', 'app.schemas.mediaserver', 'app.schemas.message', 'app.schemas.mfa', 'app.schemas.music', 'app.schemas.monitoring', 'app.schemas.notification', 'app.schemas.plugin', 'app.schemas.response', 'app.schemas.rule', 'app.schemas.search', 'app.schemas.storage', 'app.schemas.openai', 'app.schemas.servarr', 'app.schemas.servcookie', 'app.schemas.site', 'app.schemas.subscribe', 'app.schemas.system', 'app.schemas.tmdb', 'app.schemas.token', 'app.schemas.transfer', 'app.schemas.user', 'app.schemas.workflow', 'app.schemas.mcp'], - 'ConfigDict': ['app.schemas.agent', 'app.schemas.category', 'app.schemas.history', 'app.schemas.mediaserver', 'app.schemas.response', 'app.schemas.openai', 'app.schemas.servcookie', 'app.schemas.site', 'app.schemas.subscribe', 'app.schemas.user', 'app.schemas.workflow'], + 'ConfigDict': ['app.schemas.agent', 'app.schemas.category', 'app.schemas.event', 'app.schemas.history', 'app.schemas.mediaserver', 'app.schemas.response', 'app.schemas.openai', 'app.schemas.servcookie', 'app.schemas.site', 'app.schemas.subscribe', 'app.schemas.user', 'app.schemas.workflow'], 'Context': ['app.schemas.context', 'app.schemas.workflow'], 'Dict': ['app.schemas.category', 'app.schemas.common', 'app.schemas.context', 'app.schemas.event', 'app.schemas.mediaserver', 'app.schemas.message', 'app.schemas.notification', 'app.schemas.plugin', 'app.schemas.openai', 'app.schemas.site', 'app.schemas.subscribe', 'app.schemas.mcp'], 'DownloadTask': ['app.schemas.download', 'app.schemas.workflow'], diff --git a/docs/refactor/backend-architecture-next-stage.md b/docs/refactor/backend-architecture-next-stage.md index c1273822a..87e120c03 100644 --- a/docs/refactor/backend-architecture-next-stage.md +++ b/docs/refactor/backend-architecture-next-stage.md @@ -621,6 +621,9 @@ ModuleMethodSpec( `ModuleCapability` Protocol 为宿主和新插件提供静态声明入口,但不替换字符串 dispatcher ABI。 - 22 个显式方法进一步登记宿主真实传入的 required parameter 名称,覆盖识别、搜索、媒体服务器、存储、 消息收尾、命令注册和 webhook;dispatcher 仍只输出诊断 warning,不阻断缺少参数的旧插件或未知自定义方法。 +- 契约清单现覆盖静态扫描到的 211 个宿主字符串调用,并保留一个暂未被宿主调用的 `send_message` 公开能力, + 共 212 个显式 V2 spec。原先仅按 prefix 分类或落入默认 legacy 的宿主方法均获得稳定 family、输入合同、 + 结果合同、执行、超时和错误语义;未知第三方自定义方法仍走开放 legacy fallback,不拒绝加载或执行。 #### ARCH-241:Event Contract Registry @@ -658,6 +661,9 @@ ModuleMethodSpec( - 订阅变更、下载添加、整理成功/失败等用户副作用标记为 `durable_required`,只表达完成语义要求; 在 ARCH-251 pilot 完成前不虚构当前已具备持久投递。SystemError 仍沿用既有递归保护和异常通知路径。 - runtime contract baseline 新增稳定 `event_specs`,后续 enum 新增必须同步登记,且不比较源码行号。 +- 53 个事件现已全部绑定 typed payload,原有 28 个 `legacy_dict` 项归零。插件动作/触发等开放事件使用 + “公共字段类型化 + `extra=allow`”模型,Webhook 与 Workflow execution 复用既有 DTO;验证仍只诊断并投递 + 同一个原始 dict/model,因此插件字段、对象引用和链式原地修改语义未改变。 #### ARCH-242:Module/Integration 质量清单 diff --git a/tests/fixtures/architecture/dependency-baseline.json b/tests/fixtures/architecture/dependency-baseline.json index a90584564..aeb144b97 100644 --- a/tests/fixtures/architecture/dependency-baseline.json +++ b/tests/fixtures/architecture/dependency-baseline.json @@ -13,8 +13,8 @@ "runtime_to_db": [], "workflow_to_db": [] }, - "edge_count": 6367, - "edge_sha256": "62c413857cd12dbaf4d31e4fad4c6b6c80f7dc747d0d5a74ecb61c44b4996822", + "edge_count": 6369, + "edge_sha256": "62638f6e334e7deb05902ca1e50cdcd03245a85c207dd2b4efaa03306cd28187", "edges": [ "app -> app.runtime", "app -> app.runtime.compat", @@ -5436,7 +5436,9 @@ "app.runtime.event.binding -> app.runtime.log", "app.runtime.event.contracts -> app.schemas", "app.runtime.event.contracts -> app.schemas.event", + "app.runtime.event.contracts -> app.schemas.mediaserver", "app.runtime.event.contracts -> app.schemas.types", + "app.runtime.event.contracts -> app.schemas.workflow", "app.runtime.event.dispatch -> app.runtime", "app.runtime.event.dispatch -> app.runtime.correlation", "app.runtime.event.dispatch -> app.runtime.event", diff --git a/tests/fixtures/architecture/runtime-contract-baseline.json b/tests/fixtures/architecture/runtime-contract-baseline.json index 7c1c7e079..2a7b1eb2a 100644 --- a/tests/fixtures/architecture/runtime-contract-baseline.json +++ b/tests/fixtures/architecture/runtime-contract-baseline.json @@ -1221,10 +1221,10 @@ "ChainEventType.MediaRecognize": { "delivery": "ephemeral", "error_behavior": "stop_chain", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "chain", "ordering": "priority_serial", - "payload_contract": "legacy_dict", + "payload_contract": "MediaRecognizeEventData", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1241,30 +1241,30 @@ "ChainEventType.MusicMediaRecognize": { "delivery": "ephemeral", "error_behavior": "stop_chain", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "chain", "ordering": "priority_serial", - "payload_contract": "legacy_dict", + "payload_contract": "MusicMediaRecognizeEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "ChainEventType.MusicNameRecognize": { "delivery": "ephemeral", "error_behavior": "stop_chain", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "chain", "ordering": "priority_serial", - "payload_contract": "legacy_dict", + "payload_contract": "MusicNameRecognizeEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "ChainEventType.NameRecognize": { "delivery": "ephemeral", "error_behavior": "stop_chain", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "chain", "ordering": "priority_serial", - "payload_contract": "legacy_dict", + "payload_contract": "NameRecognizeEventData", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1381,10 +1381,10 @@ "ChainEventType.WorkflowExecution": { "delivery": "ephemeral", "error_behavior": "stop_chain", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "chain", "ordering": "priority_serial", - "payload_contract": "legacy_dict", + "payload_contract": "ActionContext", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1401,30 +1401,30 @@ "EventType.AudioTransferComplete": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "TransferResultEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.AudioTransferFailed": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "TransferResultEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.CommandExcute": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "CommandExecuteEventData", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1451,130 +1451,130 @@ "EventType.DownloadDeleted": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "DownloadDeletedEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.DownloadFileDeleted": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "DownloadFileDeletedEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.HistoryDeleted": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "HistoryDeletedEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.MessageAction": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "MessageActionEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.MetadataScrape": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "MetadataScrapeEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.ModuleReload": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "EmptyEventData", "sensitive_fields": [], "visibility": "host_only" }, "EventType.NoticeMessage": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "NoticeMessageEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.PluginAction": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "PluginActionEventData", "sensitive_fields": [], "visibility": "target_plugin" }, "EventType.PluginReload": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "PluginReloadEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.PluginTriggered": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "PluginTriggeredEventData", "sensitive_fields": [], "visibility": "target_plugin" }, "EventType.SiteDeleted": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "SiteEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.SiteRefreshed": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "SiteEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.SiteUpdated": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "SiteEventData", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1591,10 +1591,10 @@ "EventType.SubscribeComplete": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "SubscribeCompleteEventData", "sensitive_fields": [], "visibility": "plugin_public" }, @@ -1621,30 +1621,30 @@ "EventType.SubtitleTransferComplete": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "TransferResultEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.SubtitleTransferFailed": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "TransferResultEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.SystemError": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "SystemErrorEventData", "sensitive_fields": [], "visibility": "host_only" }, @@ -1671,30 +1671,30 @@ "EventType.UserMessage": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "UserMessageEventData", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.WebhookMessage": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "WebhookEventInfo", "sensitive_fields": [], "visibility": "plugin_public" }, "EventType.WorkflowExecute": { "delivery": "ephemeral", "error_behavior": "notify", - "legacy_reason": "现有插件 payload 尚未收敛为稳定 model,保留原始 dict ABI", + "legacy_reason": null, "mode": "broadcast", "ordering": "priority_queue", - "payload_contract": "legacy_dict", + "payload_contract": "WorkflowExecuteEventData", "sensitive_fields": [], "visibility": "plugin_public" } @@ -2335,6 +2335,1386 @@ "producer_count": 76 }, "module_method_specs": { + "anilist_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_popular_this_season": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_recommendations": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "anilist_trending": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "any_files": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "storage", + "input_contract": "StorageKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_popular_this_season": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_recommendations": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_anilist_trending": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "anilist", + "input_contract": "AniListKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AniListProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_calendar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_bangumi_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_movie_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_movie_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_tv_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_douban_tv_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_identify_music_by_fingerprint": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_match_doubaninfo": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_match_music_album": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_match_tmdbinfo": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_movie_hot": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_movie_showing": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_movie_top250": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_obtain_images": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_recognize_media": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_refresh_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "integration", + "input_contract": "IntegrationKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "IntegrationProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_search_collections": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_search_medias": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_search_persons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_search_subtitles": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_search_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_collection": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_episodes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_group_seasons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_movie_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_movie_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_movie_similar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_seasons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_trending": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_tv_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_tv_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tmdb_tv_similar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tv_animation": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tv_hot": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tv_weekly_chinese": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_tv_weekly_global": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "async_update_recognize_cache": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_calendar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "bangumi_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "bangumi", + "input_contract": "BangumiKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "BangumiProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "channel_manage": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "clear_cache": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "category", + "input_contract": "CategoryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "CategoryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "create_folder": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "storage", + "input_contract": "StorageKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "delete_file": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "storage", + "input_contract": "StorageKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "delete_message": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_movie_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_movie_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_tv_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "douban_tv_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "douban", + "input_contract": "DoubanKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DoubanProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_added": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_discord_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_feishu_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_feishu_image_to_data_url": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "download_file": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2353,6 +3733,201 @@ "timeout_policy": "caller_budget", "version": 1 }, + "download_qq_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_slack_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_slack_file_to_data_url": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_synologychat_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_telegram_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_telegram_file_to_base64": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_vocechat_file_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_vocechat_image_to_data_url": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_wechat_image_to_data_url": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "download_wechat_media_bytes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "downloader_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "edit_message": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "filter_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "finalize_message": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2423,6 +3998,51 @@ "timeout_policy": "caller_budget", "version": 1 }, + "get_search_page_size": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "site", + "input_contract": "SiteKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "SiteProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "get_torrent_trackers": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "identify_music_by_fingerprint": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "list_files": { "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", @@ -2441,6 +4061,111 @@ "timeout_policy": "caller_budget", "version": 1 }, + "list_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "load_category_config": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "category", + "input_contract": "CategoryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "CategoryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mark_message_processing_finished": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mark_message_processing_started": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "match_doubaninfo": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "match_music_album": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "match_tmdbinfo": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "media_category": { "aggregation": "legacy", "error_policy": "isolate_provider", @@ -2456,6 +4181,66 @@ "timeout_policy": "caller_budget", "version": 1 }, + "media_exists": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "media_files": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "storage", + "input_contract": "StorageKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "media_statistic": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mediaserver_image_cookies": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "mediaserver_iteminfo": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2494,6 +4279,66 @@ "timeout_policy": "caller_budget", "version": 1 }, + "mediaserver_items_count": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mediaserver_latest": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mediaserver_latest_images": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mediaserver_librarys": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "mediaserver_play_url": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2512,6 +4357,36 @@ "timeout_policy": "caller_budget", "version": 1 }, + "mediaserver_playing": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "mediaserver_season_episode_ids": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-server", + "input_contract": "MediaServerKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaServerProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "mediaserver_tv_episodes": { "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", @@ -2530,6 +4405,276 @@ "timeout_policy": "caller_budget", "version": 1 }, + "message_parser": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "metadata_img": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "metadata", + "input_contract": "MetadataKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MetadataProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "metadata_nfo": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "metadata", + "input_contract": "MetadataKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MetadataProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "movie_hot": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "movie_showing": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "movie_top250": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_album": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_album_related": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_artist": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_artist_albums": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_artist_related": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_cache_clear": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_cache_delete": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_cache_items": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_chart": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_fresh_releases": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "music_lyrics": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "obtain_images": { "aggregation": "legacy", "error_policy": "isolate_provider", @@ -2547,6 +4692,21 @@ "timeout_policy": "caller_budget", "version": 1 }, + "obtain_specific_image": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "metadata", + "input_contract": "MetadataKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MetadataProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "recognize_media": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2569,6 +4729,51 @@ "timeout_policy": "caller_budget", "version": 1 }, + "recommend_name": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "metadata", + "input_contract": "MetadataKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MetadataProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "refresh_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "refresh_userdata": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "site", + "input_contract": "SiteKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "SiteProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "register_commands": { "aggregation": "legacy", "error_policy": "isolate_provider", @@ -2586,6 +4791,21 @@ "timeout_policy": "caller_budget", "version": 1 }, + "remove_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "rename_file": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2604,6 +4824,21 @@ "timeout_policy": "caller_budget", "version": 1 }, + "save_category_config": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "category", + "input_contract": "CategoryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "CategoryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "scheduler_job": { "aggregation": "legacy", "error_policy": "isolate_provider", @@ -2619,6 +4854,21 @@ "timeout_policy": "caller_budget", "version": 1 }, + "search_collections": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "search_medias": { "aggregation": "ordered_list_merge", "error_policy": "isolate_provider", @@ -2637,6 +4887,96 @@ "timeout_policy": "caller_budget", "version": 1 }, + "search_music": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "music", + "input_contract": "MusicKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MusicProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "search_persons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "search_subtitles": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "search_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "search_tvdb": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "integration", + "input_contract": "IntegrationKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "IntegrationProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "send_direct_message": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "messaging", + "input_contract": "MessagingKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MessagingProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "send_message": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2652,6 +4992,36 @@ "timeout_policy": "caller_budget", "version": 1 }, + "set_torrents_tag": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "site_subtitle_links": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "site", + "input_contract": "SiteKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "SiteProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "snapshot_storage": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2673,6 +5043,36 @@ "timeout_policy": "caller_budget", "version": 1 }, + "start_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "stop_torrents": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "storage_manage": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", @@ -2685,7 +5085,442 @@ "action", "storage" ], - "result_contract": "Any", + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_cache_clear": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_cache_delete": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_cache_items": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_collection": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_discover": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_episodes": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_group_seasons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_movie_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_movie_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_movie_similar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_person_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_person_detail": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_seasons": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_trending": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_tv_credits": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_tv_recommend": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tmdb_tv_similar": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tmdb", + "input_contract": "TmdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TmdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "torrent_files": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "transfer": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "storage", + "input_contract": "StorageKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "StorageProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "transfer_completed": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tv_animation": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tv_hot": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tv_weekly_chinese": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tv_weekly_global": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-discovery", + "input_contract": "MediaDiscoveryKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaDiscoveryProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tvdb_info": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tvdb", + "input_contract": "TvdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TvdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "tvdb_slug": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "tvdb", + "input_contract": "TvdbKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "TvdbProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "update_recognize_cache": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "media-recognition", + "input_contract": "MediaRecognitionKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "MediaRecognitionProviderResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, + "update_torrent": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "downloader", + "input_contract": "DownloaderKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "DownloaderProviderResult", "supports_async": true, "supports_sync": true, "timeout_policy": "caller_budget", @@ -2710,6 +5545,21 @@ "timeout_policy": "caller_budget", "version": 1 }, + "user_authenticate": { + "aggregation": "legacy", + "error_policy": "isolate_provider", + "execution": "sync_or_async", + "family": "authentication", + "input_contract": "AuthenticationKeywordArguments", + "plugin_short_circuit": true, + "public_to_plugins": true, + "required_parameters": [], + "result_contract": "AuthenticationResult", + "supports_async": true, + "supports_sync": true, + "timeout_policy": "caller_budget", + "version": 1 + }, "webhook_parser": { "aggregation": "first_non_empty", "error_policy": "isolate_provider", diff --git a/tests/test_event_contracts.py b/tests/test_event_contracts.py index 23440ddf0..281ed084e 100644 --- a/tests/test_event_contracts.py +++ b/tests/test_event_contracts.py @@ -18,7 +18,7 @@ from app.schemas.types import ChainEventType, EventType, MediaType def test_every_event_enum_has_complete_contract() -> None: - """53 个广播/链式事件必须全部登记且 legacy 项必须解释原因。""" + """53 个广播/链式事件必须全部登记并绑定 typed payload。""" expected = {*EventType, *ChainEventType} assert set(EVENT_CONTRACTS) == expected @@ -26,8 +26,24 @@ def test_every_event_enum_has_complete_contract() -> None: for contract in EVENT_CONTRACTS.values(): assert contract.mode in {"broadcast", "chain"} assert contract.payload_contract - if contract.payload_contract == "legacy_dict": - assert contract.legacy_reason + assert contract.payload_model is not None + assert contract.payload_contract != "legacy_dict" + assert contract.legacy_reason is None + + +def test_extensible_plugin_payload_accepts_custom_fields_without_shape_change() -> None: + """插件动作 contract 只校验公共字段,插件自定义字段和原始 dict 均保持不变。""" + payload = { + "plugin_id": "DemoPlugin", + "action": "refresh", + "plugin_owned_field": {"value": 1}, + } + + assert validate_event_payload(EventType.PluginAction, payload) == () + event = Event(EventType.PluginAction, payload) + + assert event.event_data is payload + assert event.event_data["plugin_owned_field"] == {"value": 1} def test_typed_payload_is_validated_without_changing_public_shape() -> None: diff --git a/tests/test_module_method_contracts.py b/tests/test_module_method_contracts.py index f3edb054a..a5607ca78 100644 --- a/tests/test_module_method_contracts.py +++ b/tests/test_module_method_contracts.py @@ -19,15 +19,19 @@ RUNTIME_BASELINE = ( ) -def test_all_scanned_module_methods_resolve_a_contract() -> None: - """架构快照中的所有字符串方法都必须能解析到稳定聚合规则。""" +def test_all_scanned_host_module_methods_have_explicit_v2_contracts() -> None: + """架构快照中的全部宿主字符串方法都必须显式登记 V2 契约。""" payload = json.loads(RUNTIME_BASELINE.read_text(encoding="utf-8")) - methods = payload["run_module"]["methods"] + methods = set(payload["run_module"]["methods"]) + contracts = list_explicit_module_contracts() assert methods + assert methods <= contracts.keys() for method in methods: - contract = get_module_method_contract(method) + contract = contracts[method] assert isinstance(contract.aggregation, ModuleResultAggregation) + assert contract.input_contract != "legacy_args" + assert contract.result_contract != "Any" assert contract.plugin_short_circuit is True @@ -59,11 +63,11 @@ def test_unknown_plugin_method_keeps_legacy_compatibility() -> None: assert contract.supports_async is True -def test_contract_v2_freezes_at_least_twenty_high_value_methods() -> None: - """首批能力必须具备可生成文档和诊断的完整 V2 字段。""" +def test_contract_v2_freezes_every_observed_host_method() -> None: + """全部已观察宿主能力必须具备可生成文档和诊断的完整 V2 字段。""" contracts = list_explicit_module_contracts() - assert len(contracts) >= 20 + assert len(contracts) >= 211 for contract in contracts.values(): assert contract.version == 1 assert contract.input_contract != "legacy_args"