base_agent/uas/action/registry/action_registry.py

159 lines
6.1 KiB
Python
Raw Normal View History

2026-06-18 03:28:14 +00:00
# -*- coding: utf-8 -*-
"""
Action 工厂注册表
ActionType handler 函数的映射集中管理
支持
- 内置 handler 自动注册
- 运行时动态注册/覆盖 handler
- 通过 create() 工厂方法快速创建 Action 实例
"""
from __future__ import annotations
import logging
import threading
from typing import Callable, Dict, List, Optional, Union
from uas.action.action_model import Action, make_action
from uas.action.action_type import ActionType
logger = logging.getLogger(__name__)
class ActionFactory:
"""
Action 工厂单例
使用方式
factory = ActionFactory.instance()
# 注册自定义 handler
factory.register(ActionType.CAPTURE_PHOTO, my_photo_handler)
# 创建 Action 实例(自动绑定 handler
action = factory.create(
ActionType.CAPTURE_PHOTO,
source = "camera-01",
resolution = "4K",
format = "jpg",
)
"""
_instance = None
_lock = threading.Lock()
@classmethod
def instance(cls) -> "ActionFactory":
if cls._instance is None:
cls._instance = cls()
return cls._instance
def __init__(self):
# { type_key: handler_fn }
self._handlers: Dict[str, Callable] = {}
self._init_builtin()
def _init_builtin(self):
"""自动注册所有内置 handler"""
from uas.action.actions.builtin_actions import BUILTIN_HANDLERS
for action_type, handler in BUILTIN_HANDLERS.items():
self.register(action_type, handler)
logger.info(f"✅ ActionFactory 初始化,内置 handler={len(self._handlers)}")
# ── 注册 ──────────────────────────────────────────────────────
def register(
self,
action_type: Union[ActionType, str],
handler: Callable,
override: bool = True,
) -> None:
"""
注册 Action 处理函数
:param action_type: ActionType 枚举 自定义字符串
:param handler: fn(action: Action, ctx: ActionContext) -> Any
:param override: True=允许覆盖已有 handler
"""
key = action_type.value if isinstance(action_type, ActionType) else str(action_type)
with self._lock:
if key in self._handlers and not override:
logger.warning(f"handler 已存在且 override=False跳过: {key}")
return
self._handlers[key] = handler
logger.info(f"注册 handler: {key} -> {handler.__name__}")
def unregister(self, action_type: Union[ActionType, str]) -> bool:
"""注销 handler"""
key = action_type.value if isinstance(action_type, ActionType) else str(action_type)
with self._lock:
if key in self._handlers:
del self._handlers[key]
logger.info(f"注销 handler: {key}")
return True
return False
def get_handler(self, action_type: Union[ActionType, str]) -> Optional[Callable]:
"""获取指定类型的 handler"""
key = action_type.value if isinstance(action_type, ActionType) else str(action_type)
return self._handlers.get(key)
def has_handler(self, action_type: Union[ActionType, str]) -> bool:
key = action_type.value if isinstance(action_type, ActionType) else str(action_type)
return key in self._handlers
def registered_types(self) -> List[str]:
return list(self._handlers.keys())
# ── 工厂创建 ──────────────────────────────────────────────────
def create(
self,
action_type: Union[ActionType, str],
source: str = "system",
priority: int = 0,
handler: Optional[Callable] = None,
**params
) -> Action:
"""
工厂方法创建并自动绑定 handler Action 实例
:param action_type: 行为类型
:param source: 触发来源
:param priority: 执行优先级
:param handler: 若指定则覆盖注册表中的 handler
:param params: 传递给 Action 的业务参数
:return: Action 实例
"""
resolved_handler = handler or self.get_handler(action_type)
if resolved_handler is None:
logger.warning(f"未找到 handler: {action_type},将使用空处理器")
resolved_handler = _noop_handler
action = make_action(
action_type = action_type,
handler = resolved_handler,
source = source,
priority = priority,
**params,
)
logger.debug(f"创建 Action: {action}")
return action
def create_batch(self, specs: List[dict]) -> List[Action]:
"""
批量创建 Action
:param specs: [{"action_type": ..., "source": ..., **params}, ...]
"""
return [self.create(**spec) for spec in specs]
def _noop_handler(action, ctx):
"""空处理器(未注册 handler 时的占位)"""
logger.warning(f"[noop] Action [{action.type_key}] 无处理器,跳过执行")
return None
# 全局工厂实例
action_factory = ActionFactory.instance()