75 lines
2.4 KiB
Python
75 lines
2.4 KiB
Python
|
|
"""Plugin marketplace/registry: discover, install, and manage custom heads."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from typing import Any
|
||
|
|
|
||
|
|
from fastapi import APIRouter
|
||
|
|
|
||
|
|
from fusionagi._logger import logger
|
||
|
|
|
||
|
|
router = APIRouter()
|
||
|
|
|
||
|
|
# In-memory plugin registry (in production, back with DB)
|
||
|
|
_registry: dict[str, dict[str, Any]] = {}
|
||
|
|
|
||
|
|
|
||
|
|
@router.get("/plugins")
|
||
|
|
def list_plugins(category: str | None = None) -> dict[str, Any]:
|
||
|
|
"""List available and installed plugins (custom heads)."""
|
||
|
|
from fusionagi.agents.head_registry import HeadRegistry
|
||
|
|
|
||
|
|
registry = HeadRegistry()
|
||
|
|
installed = registry.list_heads()
|
||
|
|
|
||
|
|
plugins = list(_registry.values())
|
||
|
|
if category:
|
||
|
|
plugins = [p for p in plugins if p.get("category") == category]
|
||
|
|
|
||
|
|
return {
|
||
|
|
"available": plugins,
|
||
|
|
"installed": [{"name": name, "status": "active"} for name in installed],
|
||
|
|
"categories": ["reasoning", "creativity", "research", "safety", "custom"],
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/plugins")
|
||
|
|
def register_plugin(body: dict[str, Any]) -> dict[str, Any]:
|
||
|
|
"""Register a plugin in the marketplace."""
|
||
|
|
plugin_id = body.get("id", "")
|
||
|
|
if not plugin_id:
|
||
|
|
return {"error": "Plugin ID required"}
|
||
|
|
|
||
|
|
entry = {
|
||
|
|
"id": plugin_id,
|
||
|
|
"name": body.get("name", plugin_id),
|
||
|
|
"description": body.get("description", ""),
|
||
|
|
"version": body.get("version", "0.1.0"),
|
||
|
|
"author": body.get("author", ""),
|
||
|
|
"category": body.get("category", "custom"),
|
||
|
|
"entry_point": body.get("entry_point", ""),
|
||
|
|
"status": "available",
|
||
|
|
}
|
||
|
|
_registry[plugin_id] = entry
|
||
|
|
logger.info("Plugin registered", extra={"plugin_id": plugin_id})
|
||
|
|
return entry
|
||
|
|
|
||
|
|
|
||
|
|
@router.post("/plugins/{plugin_id}/install")
|
||
|
|
def install_plugin(plugin_id: str) -> dict[str, Any]:
|
||
|
|
"""Install a plugin from the registry."""
|
||
|
|
if plugin_id not in _registry:
|
||
|
|
return {"error": f"Plugin not found: {plugin_id}"}
|
||
|
|
_registry[plugin_id]["status"] = "installed"
|
||
|
|
logger.info("Plugin installed", extra={"plugin_id": plugin_id})
|
||
|
|
return {"plugin_id": plugin_id, "status": "installed"}
|
||
|
|
|
||
|
|
|
||
|
|
@router.delete("/plugins/{plugin_id}")
|
||
|
|
def uninstall_plugin(plugin_id: str) -> dict[str, Any]:
|
||
|
|
"""Uninstall a plugin."""
|
||
|
|
if plugin_id in _registry:
|
||
|
|
_registry[plugin_id]["status"] = "available"
|
||
|
|
logger.info("Plugin uninstalled", extra={"plugin_id": plugin_id})
|
||
|
|
return {"plugin_id": plugin_id, "status": "uninstalled"}
|