"""Tool Registry — 도구 실행 디스패처 + 안전장치.""" from __future__ import annotations import logging from tools import calendar_tool, document_tool, email_tool logger = logging.getLogger(__name__) # 에러 메시지 표준화 (내부 에러 노출 안 함) ERROR_MESSAGES = { "calendar": "⚠️ 캘린더 서비스를 사용할 수 없습니다. 잠시 후 다시 시도해주세요.", "email": "⚠️ 메일 서비스를 사용할 수 없습니다. 잠시 후 다시 시도해주세요.", "document": "⚠️ 문서 서비스를 사용할 수 없습니다. 잠시 후 다시 시도해주세요.", } # 허용된 operations ALLOWED_OPS = { "calendar": {"today", "search", "create_draft", "create_confirmed"}, "email": {"search", "read"}, "document": {"search", "read"}, } # payload hard limit MAX_TOOL_PAYLOAD = 2000 async def execute_tool(tool_name: str, operation: str, params: dict) -> dict: """도구 실행 디스패처.""" # 도구 존재 확인 if tool_name not in ALLOWED_OPS: return _error(tool_name, operation, f"알 수 없는 도구: {tool_name}") # operation 허용 확인 if operation not in ALLOWED_OPS[tool_name]: return _error(tool_name, operation, f"허용되지 않은 작업: {tool_name}.{operation}") try: if tool_name == "calendar": result = await _exec_calendar(operation, params) elif tool_name == "email": result = await _exec_email(operation, params) elif tool_name == "document": result = await _exec_document(operation, params) else: result = _error(tool_name, operation, "미구현") if not result["ok"]: logger.warning("Tool %s.%s failed: %s", tool_name, operation, result.get("error")) result["error"] = ERROR_MESSAGES.get(tool_name, "⚠️ 서비스를 사용할 수 없습니다.") return result except Exception: logger.exception("Tool %s.%s exception", tool_name, operation) return _error(tool_name, operation, ERROR_MESSAGES.get(tool_name, "⚠️ 서비스 오류")) async def _exec_calendar(operation: str, params: dict) -> dict: if operation == "today": return await calendar_tool.today() elif operation == "search": return await calendar_tool.search( params.get("date_from", ""), params.get("date_to", ""), ) elif operation == "create_draft": return await calendar_tool.create_draft( params.get("title", ""), params.get("date", ""), params.get("time", "00:00"), params.get("description", ""), ) elif operation == "create_confirmed": return await calendar_tool.create_confirmed(params) return _error("calendar", operation, "미구현") async def _exec_email(operation: str, params: dict) -> dict: if operation == "search": return await email_tool.search( params.get("query", ""), params.get("days", 7), ) elif operation == "read": return await email_tool.read(params.get("uid", "")) return _error("email", operation, "미구현") async def _exec_document(operation: str, params: dict) -> dict: if operation == "search": return await document_tool.search(params.get("query", "")) elif operation == "read": return await document_tool.read(params.get("doc_id", "")) return _error("document", operation, "미구현") def _error(tool: str, operation: str, msg: str) -> dict: return {"ok": False, "tool": tool, "operation": operation, "data": [], "summary": "", "error": msg}