From e7b1e2c6e17a229d3d180efe48e7da609ec9a68e Mon Sep 17 00:00:00 2001 From: jxxghp Date: Fri, 11 Sep 2026 11:36:35 +0800 Subject: [PATCH] fix(architecture): close module endpoint type ratchet --- app/api/endpoints/module.py | 27 +++++++++++++------ app/api/endpoints/storage.py | 2 +- app/schemas/storage.py | 2 +- app/schemas/system.py | 8 +++--- docs/agent-evaluation.md | 2 +- docs/refactor/optimization-checklist.md | 2 +- .../fixtures/architecture/mypy-baseline.json | 4 +-- 7 files changed, 29 insertions(+), 18 deletions(-) diff --git a/app/api/endpoints/module.py b/app/api/endpoints/module.py index 8bbd0ac6b..690c627e4 100644 --- a/app/api/endpoints/module.py +++ b/app/api/endpoints/module.py @@ -45,8 +45,10 @@ def _module_description(module_id: str, name: str, module_type: str) -> str: "/modulelist", summary="查询已启用的模块ID列表", response_model=_SchemaResponse[_SchemaSystemModuleListData], -) -def modulelist(_: _SchemaTokenPayload = Depends(verify_token)): +) # type: ignore[misc] +def modulelist( + _: _SchemaTokenPayload = Depends(verify_token), +) -> _SchemaResponse[_SchemaSystemModuleListData]: """查询当前配置下应参与健康检查的模块 ID 列表。""" modules = [] for spec in get_module_manager().list_enabled_specs(): @@ -70,8 +72,10 @@ def modulelist(_: _SchemaTokenPayload = Depends(verify_token)): "/module-catalog", summary="查询宿主模块目录", response_model=_SchemaResponse[_SchemaSystemModuleCatalogListData], -) -def module_catalog(_: _SchemaTokenPayload = Depends(verify_token)): +) # type: ignore[misc] +def module_catalog( + _: _SchemaTokenPayload = Depends(verify_token), +) -> _SchemaResponse[_SchemaSystemModuleCatalogListData]: """返回模块及其服务类型目录,供前端选择器统一构造选项。""" manager = get_module_manager() specs = manager.list_specs() @@ -112,10 +116,10 @@ def module_catalog(_: _SchemaTokenPayload = Depends(verify_token)): "/module-settings", summary="查询可手动开关的内置模块", response_model=_SchemaResponse[_SchemaSystemModuleSettingListData], -) +) # type: ignore[misc] async def module_settings( _: ApiPrincipal = Depends(get_current_active_superuser_async), -): +) -> _SchemaResponse[_SchemaSystemModuleSettingListData]: """查询没有其它激活配置、可由用户统一控制的内置模块。""" configured = get_runtime_settings().get("MODULE_ENABLE", {}) if not isinstance(configured, dict): @@ -146,8 +150,15 @@ async def module_settings( return _SchemaResponse(success=True, data={"modules": modules}) -@router.get("/moduletest/{moduleid}", summary="模块可用性测试", response_model=_SchemaResponse[None]) -def moduletest(moduleid: str, _: _SchemaTokenPayload = Depends(verify_token)): +@router.get( # type: ignore[misc] + "/moduletest/{moduleid}", + summary="模块可用性测试", + response_model=_SchemaResponse[None], +) +def moduletest( + moduleid: str, + _: _SchemaTokenPayload = Depends(verify_token), +) -> _SchemaResponse[None]: """运行指定模块的内置可用性测试。""" state, errmsg = get_module_manager().test(moduleid) return _SchemaResponse(success=state, message=errmsg) diff --git a/app/api/endpoints/storage.py b/app/api/endpoints/storage.py index 7d62b8b77..a98565a5b 100644 --- a/app/api/endpoints/storage.py +++ b/app/api/endpoints/storage.py @@ -135,7 +135,7 @@ def storage_options( "/catalog", summary="查询存储类型目录", response_model=List[_SchemaStorageCatalogOption], -) +) # type: ignore[misc] def storage_catalog( _: ApiPrincipal = Depends(get_current_active_user), page: CompatiblePageParam = None, diff --git a/app/schemas/storage.py b/app/schemas/storage.py index a8f9f74e8..37bdbdb74 100644 --- a/app/schemas/storage.py +++ b/app/schemas/storage.py @@ -33,7 +33,7 @@ class StorageOption(BaseModel): # type: ignore[misc] type: str = Field(description="存储类型标识") -class StorageCatalogOption(BaseModel): +class StorageCatalogOption(BaseModel): # type: ignore[misc] """前端新增存储和路径选择器可消费的存储类型目录项。""" type: str = Field(description="存储类型标识") diff --git a/app/schemas/system.py b/app/schemas/system.py index a92d517ea..e051daf72 100644 --- a/app/schemas/system.py +++ b/app/schemas/system.py @@ -328,7 +328,7 @@ class SystemModuleListData(BaseModel): modules: list[SystemModuleInfo] = Field(default_factory=list) -class SystemModuleSettingInfo(BaseModel): +class SystemModuleSettingInfo(BaseModel): # type: ignore[misc] """可由用户统一开关的内置模块设置摘要。""" id: str @@ -340,13 +340,13 @@ class SystemModuleSettingInfo(BaseModel): enabled: bool -class SystemModuleSettingListData(BaseModel): +class SystemModuleSettingListData(BaseModel): # type: ignore[misc] """可由用户统一开关的内置模块设置列表。""" modules: list[SystemModuleSettingInfo] = Field(default_factory=list) -class SystemModuleCatalogInfo(BaseModel): +class SystemModuleCatalogInfo(BaseModel): # type: ignore[misc] """前端服务选择器可消费的宿主模块目录项。""" id: str @@ -362,7 +362,7 @@ class SystemModuleCatalogInfo(BaseModel): active: bool = False -class SystemModuleCatalogListData(BaseModel): +class SystemModuleCatalogListData(BaseModel): # type: ignore[misc] """宿主模块及其服务类型目录。""" modules: list[SystemModuleCatalogInfo] = Field(default_factory=list) diff --git a/docs/agent-evaluation.md b/docs/agent-evaluation.md index 71a179cf4..0ebc1b94e 100644 --- a/docs/agent-evaluation.md +++ b/docs/agent-evaluation.md @@ -85,7 +85,7 @@ uv run --locked --no-sync python -m scripts.evaluation --live \ `command_execution` 场景按场景显式开启原生 CLI 的 `shell_tool`、`unified_exec` 和 `shell_snapshot`,代理保留 `functions.exec_command` 与 `functions.write_stdin`;MoviePilot 侧注入生产 `ExecuteCommandTool`,仅允许任务给定的固定命令和临时工作目录。配对报告 `/tmp/moviepilot-agent-round-luna-oauth-command-pair-final.json` 的 `pair_valid=true`、`both_passed=true`,harness 指纹为 `c409ee1ca7899ccfcefd38832d6a343f024f8fc67fb65f14c3eec08552203257`:两侧均以退出码 0 得到 `MOVIEPILOT_COMMAND_OK`,没有业务副作用。 -`browser_navigation` 场景由 MoviePilot 生产 `BrowseWebpageTool` 操作回环动态页面,报告 `/tmp/moviepilot-agent-round-luna-oauth-live-browser-final.json` 通过,3 次浏览器回执在点击后观察到 `BROWSER_OK`。`codex exec 0.153.4` 在探针 `/tmp/moviepilot-agent-round-luna-oauth-native-probe-browser-final.json` 中即使显式开启 browser/computer feature 也没有广告浏览器动作,因此浏览器原生配对保持 blocked;这不是把 CLI 的缺失能力改判为通过。 +`browser_navigation` 场景由 MoviePilot 生产 `BrowseWebpageTool` 操作回环动态页面,报告 `/tmp/moviepilot-agent-round-luna-oauth-live-browser-final.json` 通过,4 次浏览器回执在点击后观察到 `BROWSER_OK`。`codex exec 0.153.4` 在探针 `/tmp/moviepilot-agent-round-luna-oauth-native-probe-browser-final.json` 中即使显式开启 browser/computer feature 也没有广告浏览器动作,因此浏览器原生配对保持 blocked;这不是把 CLI 的缺失能力改判为通过。 因此当前真实 Gemini 结果证明了工具合同读取和未知结果诚实边界已经能被实测,但不能宣称达到 Codex 的整体智能水平。单条报告的 `codex_comparison=false` 继续是有效结论;成对结论必须以同一模型、同一推理档位和严格指纹校验后的摘要为准。 diff --git a/docs/refactor/optimization-checklist.md b/docs/refactor/optimization-checklist.md index 020f0d895..1ab399cf8 100644 --- a/docs/refactor/optimization-checklist.md +++ b/docs/refactor/optimization-checklist.md @@ -102,7 +102,7 @@ ARCH-201 至 ARCH-204 均达到实现、验证、提交、推送和远端门禁 | Event Contract | 53 | 均已有 payload model,但当前全部是 diagnostic enforcement | | Python 源码量 | 305,884 行 | 排除 `app/plugins/**`;61 个文件超过 1,000 行,11 个超过 2,000 行 | | 长方法 | 290 个超过 80 行 | AST 统计排除 `app/plugins/**`;65 个超过 150 行,21 个超过 250 行 | -| 全量 mypy 历史债务 | 9,396 / 509 文件 | Agent API 重构后的现状基线;canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降 | +| 全量 mypy 历史债务 | 9,392 / 509 文件 | Agent API 重构后的现状基线;canonical Facade 与 endpoint 类型边界已补齐,低水位只允许继续下降 | | Ruff 历史诊断 | 524 | 低水位门禁通过,但规则集只覆盖 `E4/E7/E9/F/I` | | 覆盖率固定基线 | Application 80.00%,Domain 80.00% | Chain、Runtime、Agent、Adapter、Startup 未进入包级覆盖率门禁 | diff --git a/tests/fixtures/architecture/mypy-baseline.json b/tests/fixtures/architecture/mypy-baseline.json index 58d5946ee..c4caf46cc 100644 --- a/tests/fixtures/architecture/mypy-baseline.json +++ b/tests/fixtures/architecture/mypy-baseline.json @@ -544,9 +544,9 @@ "app/api/endpoints/system.py": { "arg-type": 1, "attr-defined": 4, - "misc": 34, + "misc": 32, "no-untyped-call": 6, - "no-untyped-def": 27, + "no-untyped-def": 25, "type-arg": 9 }, "app/api/endpoints/tmdb.py": {