Luxx/luxx/routes/tools.py

84 lines
2.6 KiB
Python

"""Tool routes"""
from typing import Optional, List, Dict, Any
from fastapi import APIRouter, Depends, Body
from pydantic import BaseModel
from luxx.database import get_db
from luxx.models import User
from luxx.routes.auth import get_current_user
from luxx.tools.core import registry, CommandPermission
from luxx.utils.helpers import success_response
router = APIRouter(prefix="/tools", tags=["Tools"])
def _tool_to_detail(tool) -> Dict[str, Any]:
"""Convert tool definition to a detailed dict with permission and category info"""
# to_openai_format returns {"type": "function", "function": {name, description, parameters}}
# Flatten the function properties to top level for easier frontend access
base = tool.to_openai_format()
func = base.get("function", {})
return {
"name": func.get("name", tool.name),
"description": func.get("description", tool.description),
"parameters": func.get("parameters", tool.parameters),
"category": tool.category,
"required_permission": tool.required_permission.name,
"required_permission_level": int(tool.required_permission)
}
@router.get("/", response_model=dict)
def list_tools(
category: Optional[str] = None,
current_user: User = Depends(get_current_user)
):
"""Get available tools list"""
# Get tool definitions directly from registry to access category
if category:
categorized_tools = [t for t in registry._tools.values() if t.category == category]
tools = [_tool_to_detail(t) for t in categorized_tools]
else:
categorized_tools = list(registry._tools.values())
tools = [_tool_to_detail(t) for t in categorized_tools]
categorized = {}
for tool in categorized_tools:
cat = tool.category
if cat not in categorized:
categorized[cat] = []
categorized[cat].append(_tool_to_detail(tool))
return success_response(data={
"tools": tools,
"categorized": categorized,
"total": len(tools)
})
@router.get("/{name}", response_model=dict)
def get_tool(
name: str,
current_user: User = Depends(get_current_user)
):
"""Get tool details"""
tool = registry.get(name)
if not tool:
return {"success": False, "message": "Tool not found", "code": 404}
return success_response(data=_tool_to_detail(tool))
@router.post("/{name}/execute", response_model=dict)
def execute_tool(
name: str,
arguments: Dict[str, Any] = Body(...),
current_user: User = Depends(get_current_user)
):
"""Execute tool manually"""
result = registry.execute(name, arguments)
return result