wangzhibo
10 天以前 220e4fab27b7f419b3e89e2f2d28ae789aac09d7
xiaozhi-esp32-server/main/xiaozhi-server/core/app_runtime/registry.py
@@ -18,6 +18,8 @@
_REGISTRY: Optional[Dict[str, Any]] = None
_VOICE_INDEX: Optional[list] = None
_REGISTRY_PATH: Optional[str] = None
_REGISTRY_MTIME: Optional[float] = None
_BUNDLED_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "apps.json")
_MENU_PRIO = 0
@@ -27,22 +29,37 @@
_RESERVED_PRIO = 4
def _load_registry() -> Dict[str, Any]:
    candidates = [
def _registry_candidates() -> list:
    return [
        os.path.join(get_project_dir(), "data", "apps.json"),
        _BUNDLED_PATH,
    ]
    for path in candidates:
def _file_mtime(path: str) -> Optional[float]:
    try:
        return os.path.getmtime(path)
    except OSError:
        return None
def _load_registry() -> Dict[str, Any]:
    global _REGISTRY_PATH, _REGISTRY_MTIME
    for path in _registry_candidates():
        if not os.path.isfile(path):
            continue
        try:
            with open(path, "r", encoding="utf-8") as f:
                data = json.load(f)
            if isinstance(data, dict) and data.get("apps"):
                _REGISTRY_PATH = path
                _REGISTRY_MTIME = _file_mtime(path)
                logger.bind(tag=TAG).info(f"已加载 App 注册表: {path}")
                return data
        except Exception as e:
            logger.bind(tag=TAG).error(f"加载 App 注册表失败 {path}: {e}")
    _REGISTRY_PATH = None
    _REGISTRY_MTIME = None
    logger.bind(tag=TAG).warning("未找到 apps.json,使用内置最小注册表")
    return {
        "default_app_id": "chat",
@@ -60,9 +77,16 @@
def get_registry() -> Dict[str, Any]:
    global _REGISTRY
    global _REGISTRY, _VOICE_INDEX
    if _REGISTRY is None:
        _REGISTRY = _load_registry()
        return _REGISTRY
    if _REGISTRY_PATH:
        top = next((item for item in _registry_candidates() if os.path.isfile(item)), None)
        mtime = _file_mtime(_REGISTRY_PATH)
        if top != _REGISTRY_PATH or (mtime is not None and mtime != _REGISTRY_MTIME):
            _REGISTRY = _load_registry()
            _VOICE_INDEX = None
    return _REGISTRY