diff --git a/zhenxun/builtin_plugins/hooks/auth_checker.py b/zhenxun/builtin_plugins/hooks/auth_checker.py index 558ac441..5907a7f1 100644 --- a/zhenxun/builtin_plugins/hooks/auth_checker.py +++ b/zhenxun/builtin_plugins/hooks/auth_checker.py @@ -728,6 +728,8 @@ async def _check_matcher_prefilter( if ai_route_modules and module not in ai_route_modules: if not _matcher_matches_ai_route_heads(matcher_cls, ai_route_heads): return True, "route_miss" + elif ai_route_modules: + return False, None if not _ROUTE_INDEX_READY: await _ensure_route_index() @@ -797,6 +799,8 @@ def _check_matcher_prefilter_before_task( if ai_route_modules and module not in ai_route_modules: if not _matcher_matches_ai_route_heads(matcher_cls, ai_route_heads): return True, "route_miss" + elif ai_route_modules: + return False, None if not _ROUTE_INDEX_READY: return False, None diff --git a/zhenxun/builtin_plugins/plugin_store/data_source.py b/zhenxun/builtin_plugins/plugin_store/data_source.py index 27f05e4c..5795e5aa 100644 --- a/zhenxun/builtin_plugins/plugin_store/data_source.py +++ b/zhenxun/builtin_plugins/plugin_store/data_source.py @@ -383,7 +383,7 @@ class StoreManager: requirement_file = target_dir / requirement_path.path if requirement_file.exists(): is_install_req = True - await VirtualEnvPackageManager.add_requirement(requirement_file) + await VirtualEnvPackageManager.install_requirement(requirement_file) if not is_install_req: # 从仓库根目录查找文件 @@ -404,13 +404,13 @@ class StoreManager: f"开始安装插件 {module_path} 依赖文件: {requirement_path}", LOG_COMMAND, ) - await VirtualEnvPackageManager.add_requirement(requirement_path) + await VirtualEnvPackageManager.install_requirement(requirement_path) if requirements_path.exists(): logger.info( f"开始安装插件 {module_path} 依赖文件: {requirements_path}", LOG_COMMAND, ) - await VirtualEnvPackageManager.add_requirement(requirements_path) + await VirtualEnvPackageManager.install_requirement(requirements_path) @classmethod async def remove_plugin(cls, index_or_module: str) -> str: diff --git a/zhenxun/configs/utils/__init__.py b/zhenxun/configs/utils/__init__.py index 5b219e80..51cca3fe 100644 --- a/zhenxun/configs/utils/__init__.py +++ b/zhenxun/configs/utils/__init__.py @@ -256,24 +256,30 @@ class ConfigsManager: return result - def _normalize_config_data(self, value: Any, original_value: Any = None) -> Any: + def _normalize_config_data( + self, + value: Any, + original_value: Any = _MISSING, + ) -> Any: """标准化配置数据,处理BaseModel和字典的情况 参数: value: 要标准化的值 - original_value: 原始值,用于合并字典 + original_value: 原始值/用户配置值,用于保留用户配置并补齐字典默认项 返回: 标准化后的值 """ processed_value = _dump_pydantic_obj(value) - if isinstance(processed_value, dict) and original_value is not None: - processed_original = _dump_pydantic_obj(original_value) - - if isinstance(processed_original, dict): - return self._merge_dicts(processed_value, processed_original) + if original_value is _MISSING: + return processed_value + processed_original = _dump_pydantic_obj(original_value) + if isinstance(processed_value, dict) and isinstance(processed_original, dict): + return self._merge_dicts(processed_value, processed_original) + if processed_original is not None: + return processed_original return processed_value def add_plugin_config( @@ -308,7 +314,7 @@ class ConfigsManager: if not module or not key: raise ValueError("add_plugin_config: module和key不能为为空") - existing_value = None + existing_value = _MISSING if module in self._data and (config := self._data[module].configs.get(key)): existing_value = config.value diff --git a/zhenxun/utils/manager/virtual_env_package_manager.py b/zhenxun/utils/manager/virtual_env_package_manager.py index f520ac02..366cdecf 100644 --- a/zhenxun/utils/manager/virtual_env_package_manager.py +++ b/zhenxun/utils/manager/virtual_env_package_manager.py @@ -8,7 +8,6 @@ from zhenxun.configs.config import Config from zhenxun.services.log import logger LOG_COMMAND = "VirtualEnvPackageManager" -PROJECT_ROOT = Path(__file__).resolve().parents[3] Config.add_plugin_config( "virtualenv", @@ -194,43 +193,8 @@ class VirtualEnvPackageManager: @classmethod async def add_requirement(cls, requirement_file: Path): - """将依赖文件写入项目依赖并同步环境 - - 插件商店安装依赖需要持久化到 pyproject.toml/uv.lock,避免重建环境后丢失。 - """ - if not requirement_file.exists(): - raise FileNotFoundError(f"依赖文件 {requirement_file} 不存在", LOG_COMMAND) - cls._clean_requirements_file(requirement_file) - try: - command = [ - "uv", - "add", - "--requirements", - str(requirement_file.absolute()), - ] - logger.info(f"执行项目依赖添加指令: {command}", LOG_COMMAND) - result = await asyncio.to_thread( - subprocess.run, - command, - cwd=PROJECT_ROOT, - check=True, - capture_output=True, - text=True, - encoding="utf-8", - errors="replace", - ) - logger.debug( - f"项目依赖添加指令执行完成: {result.stdout}", - LOG_COMMAND, - ) - return result.stdout - except (CalledProcessError, FileNotFoundError) as e: - stderr = e.stderr if isinstance(e, CalledProcessError) else str(e) - logger.error( - f"项目依赖添加指令执行失败: {stderr}.", - LOG_COMMAND, - ) - return stderr + """兼容旧调用:安装 requirements 文件到当前虚拟环境。""" + return await cls.install_requirement(requirement_file) @classmethod async def list(cls) -> str: