refactor: type routed module contracts

This commit is contained in:
jxxghp
2026-08-24 01:55:27 +08:00
parent 9712803b8d
commit 3e4e182ff9
3 changed files with 153 additions and 53 deletions
+105 -53
View File
@@ -3108,16 +3108,22 @@
"version": 1
},
"async_refresh_torrents": {
"aggregation": "legacy",
"aggregation": "ordered_list_merge",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "integration",
"input_contract": "IntegrationKeywordArguments",
"family": "downloader",
"input_contract": "TorrentRefreshRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "IntegrationProviderResult",
"result_shape": "any",
"required_parameters": [
"cat",
"keyword",
"mtype",
"page",
"site"
],
"result_contract": "list[TorrentInfo]",
"result_shape": "list",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -3722,16 +3728,19 @@
"version": 1
},
"channel_manage": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "ChannelManageRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"result_shape": "any",
"required_parameters": [
"action",
"channel"
],
"result_contract": "dict[str, Any] | None",
"result_shape": "mapping",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -3791,16 +3800,21 @@
"version": 1
},
"delete_message": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "MessageDeleteRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"result_shape": "any",
"required_parameters": [
"channel",
"chat_id",
"message_id",
"source"
],
"result_contract": "bool | None",
"result_shape": "boolean",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -4282,16 +4296,25 @@
"version": 1
},
"edit_message": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "MessageEditRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"result_shape": "any",
"required_parameters": [
"buttons",
"channel",
"chat_id",
"message_id",
"metadata",
"source",
"text",
"title"
],
"result_contract": "bool | None",
"result_shape": "boolean",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -4500,32 +4523,46 @@
"version": 1
},
"mark_message_processing_finished": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "MessageProcessingFinishRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"result_shape": "any",
"required_parameters": [
"channel",
"chat_id",
"message_id",
"source",
"status",
"userid"
],
"result_contract": "bool | None",
"result_shape": "boolean",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
"version": 1
},
"mark_message_processing_started": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "MessageProcessingStartRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"result_shape": "any",
"required_parameters": [
"channel",
"chat_id",
"message_id",
"source",
"text",
"userid"
],
"result_contract": "dict[str, Any] | None",
"result_shape": "mapping",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -4873,15 +4910,20 @@
"version": 1
},
"message_parser": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "MessageParseRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"required_parameters": [
"args",
"body",
"form",
"source"
],
"result_contract": "IncomingMessage | None",
"result_shape": "any",
"supports_async": true,
"supports_sync": true,
@@ -5307,16 +5349,22 @@
"version": 1
},
"refresh_torrents": {
"aggregation": "legacy",
"aggregation": "ordered_list_merge",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "downloader",
"input_contract": "DownloaderKeywordArguments",
"input_contract": "TorrentRefreshRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "DownloaderProviderResult",
"result_shape": "any",
"required_parameters": [
"cat",
"keyword",
"mtype",
"page",
"site"
],
"result_contract": "list[TorrentInfo]",
"result_shape": "list",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
@@ -5568,15 +5616,17 @@
"version": 1
},
"send_direct_message": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "messaging",
"input_contract": "MessagingKeywordArguments",
"input_contract": "DirectMessageSendRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "MessagingProviderResult",
"required_parameters": [
"message"
],
"result_contract": "MessageResponse | None",
"result_shape": "any",
"supports_async": true,
"supports_sync": true,
@@ -5733,32 +5783,34 @@
"version": 1
},
"tmdb_cache_delete": {
"aggregation": "legacy",
"aggregation": "first_non_empty",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "tmdb",
"input_contract": "TmdbKeywordArguments",
"input_contract": "TmdbCacheDeleteRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "TmdbProviderResult",
"result_shape": "any",
"required_parameters": [
"cache_key"
],
"result_contract": "dict[str, Any] | None",
"result_shape": "mapping",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
"version": 1
},
"tmdb_cache_items": {
"aggregation": "legacy",
"aggregation": "ordered_list_merge",
"error_policy": "isolate_provider",
"execution": "sync_or_async",
"family": "tmdb",
"input_contract": "TmdbKeywordArguments",
"input_contract": "TmdbCacheListRequest",
"plugin_short_circuit": true,
"public_to_plugins": true,
"required_parameters": [],
"result_contract": "TmdbProviderResult",
"result_shape": "any",
"result_contract": "list[dict[str, Any]]",
"result_shape": "list",
"supports_async": true,
"supports_sync": true,
"timeout_policy": "caller_budget",
+37
View File
@@ -150,6 +150,43 @@ def test_message_attachment_contracts_use_messaging_family() -> None:
assert contract.required_parameters == parameters
def test_message_route_contracts_use_first_matching_provider() -> None:
"""消息路由能力应保留渠道筛选语义,并停止依赖 legacy 结果接力。"""
expected_shapes = {
"channel_manage": ModuleResultShape.MAPPING,
"delete_message": ModuleResultShape.BOOLEAN,
"edit_message": ModuleResultShape.BOOLEAN,
"mark_message_processing_started": ModuleResultShape.MAPPING,
"mark_message_processing_finished": ModuleResultShape.BOOLEAN,
"message_parser": ModuleResultShape.ANY,
"send_direct_message": ModuleResultShape.ANY,
}
for method, result_shape in expected_shapes.items():
contract = get_module_method_contract(method)
assert contract.family == "messaging"
assert contract.aggregation is ModuleResultAggregation.FIRST_NON_EMPTY
assert contract.result_shape is result_shape
assert contract.required_parameters
def test_refresh_and_tmdb_cache_contracts_match_host_result_shapes() -> None:
"""刷新种子与 TMDB 缓存入口应声明列表合并或目标值路由语义。"""
refresh = get_module_method_contract("refresh_torrents")
async_refresh = get_module_method_contract("async_refresh_torrents")
cache_items = get_module_method_contract("tmdb_cache_items")
cache_delete = get_module_method_contract("tmdb_cache_delete")
assert refresh is async_refresh
assert refresh.family == "downloader"
assert refresh.aggregation is ModuleResultAggregation.ORDERED_LIST_MERGE
assert refresh.result_shape is ModuleResultShape.LIST
assert cache_items.aggregation is ModuleResultAggregation.ORDERED_LIST_MERGE
assert cache_items.result_shape is ModuleResultShape.LIST
assert cache_delete.aggregation is ModuleResultAggregation.FIRST_NON_EMPTY
assert cache_delete.result_shape is ModuleResultShape.MAPPING
def test_downloader_query_contracts_merge_provider_lists() -> None:
"""下载器查询能力应显式合并各 provider 的有序列表结果。"""
for method in ("list_torrents", "downloader_info"):