"""Mini-App registry for plugin-provided interactive chat components.""" from __future__ import annotations import logging from typing import Any, Callable, Awaitable from pydantic import BaseModel, Field logger = logging.getLogger(__name__) class MiniAppDef(BaseModel): """Definition of a mini-app that plugins can register.""" app_id: str = Field(..., description="Unique app identifier") name: str = Field(..., description="Display name") icon: str = Field(default="app", description="Icon name") description: str = Field(default="", description="App description") plugin_name: str = Field(..., description="Plugin that registered this app") render_schema: dict[str, Any] = Field( default_factory=dict, description="JSON schema for frontend rendering" ) class MiniAppRegistry: """Registry for mini-apps that plugins provide for chat embedding.""" def __init__(self) -> None: self._apps: dict[str, MiniAppDef] = {} def register( self, app_id: str, name: str, icon: str, description: str, plugin_name: str, render_schema: dict[str, Any] | None = None, ) -> None: """Register a mini-app.""" app = MiniAppDef( app_id=app_id, name=name, icon=icon, description=description, plugin_name=plugin_name, render_schema=render_schema or {}, ) self._apps[app_id] = app logger.info(f"Mini-app registered: {app_id} by {plugin_name}") def unregister(self, app_id: str) -> None: """Unregister a mini-app.""" app = self._apps.pop(app_id, None) if app: logger.info(f"Mini-app unregistered: {app_id}") def unregister_plugin(self, plugin_name: str) -> None: """Unregister all mini-apps from a specific plugin.""" to_remove = [app_id for app_id, app in self._apps.items() if app.plugin_name == plugin_name] for app_id in to_remove: self._apps.pop(app_id, None) if to_remove: logger.info(f"Unregistered {len(to_remove)} mini-apps from plugin {plugin_name}") def list_apps(self) -> list[dict[str, Any]]: """List all available mini-apps for frontend.""" return [app.model_dump() for app in self._apps.values()] def get_app(self, app_id: str) -> MiniAppDef | None: """Get a specific mini-app definition.""" return self._apps.get(app_id)