"""Error envelope standard per tutti i tool MCP.""" from __future__ import annotations import uuid from datetime import UTC, datetime from typing import Any def error_envelope( *, type_: str, code: str, message: str, retryable: bool, suggested_fix: str | None = None, details: dict | None = None, request_id: str | None = None, ) -> dict: env: dict[str, Any] = { "error": { "type": type_, "code": code, "message": message, "retryable": retryable, }, "request_id": request_id or uuid.uuid4().hex, "data_timestamp": datetime.now(UTC).isoformat(), } if suggested_fix: env["error"]["suggested_fix"] = suggested_fix if details: env["error"]["details"] = details return env HTTP_CODE_MAP = { 400: "BAD_REQUEST", 401: "UNAUTHORIZED", 403: "FORBIDDEN", 404: "NOT_FOUND", 408: "TIMEOUT", 409: "CONFLICT", 422: "VALIDATION_ERROR", 429: "RATE_LIMIT", 500: "INTERNAL_ERROR", 502: "UPSTREAM_ERROR", 503: "UNAVAILABLE", 504: "GATEWAY_TIMEOUT", } RETRYABLE_STATUSES = frozenset({408, 429, 502, 503, 504})