from typing import Tuple def friendly_mcp_liveboard_error(raw_error: str) -> Tuple[str, str]: """Return a user-facing MCP liveboard error and a coarse failure category.""" raw = (raw_error or "Unknown MCP error").strip() normalized = raw.lower() service_terms = [ "timed out", "timeout", "unresponsive", "gateway", "504", "503", "502", "connection refused", "connection reset", "connection aborted", "connectionerror", "server disconnected", "service unavailable", "bad gateway", "network", "agent.thoughtspot.app", ] auth_terms = [ "401", "403", "unauthorized", "forbidden", "trusted auth", "auth token", "authentication", ] answer_token_terms = [ "failed to get answers for any questions", "no valid answers with thoughtspot session/tokens", "no liveboard-compatible answers", "without session/tokens", "empty-token", "empty token", "visualization_type': 'undefined", '"visualization_type": "undefined', ] if any(term in normalized for term in auth_terms): return ( "Liveboard creation failed because ThoughtSpot MCP could not authenticate. " "Check the ThoughtSpot trusted auth key, username, and environment settings. " f"Raw MCP error: {raw}", "mcp_auth", ) if any(term in normalized for term in answer_token_terms): return ( "Liveboard creation could not retrieve MCP-compatible answer session/tokens. " "The model and data may still have deployed; creating a clearly marked backup liveboard is safe for this failure mode. " f"Raw MCP error: {raw}", "mcp_answer_tokens", ) if any(term in normalized for term in service_terms): return ( "Liveboard creation failed because the ThoughtSpot MCP service appears unavailable or timed out. " "The model and data may still have deployed; create the liveboard from the ThoughtSpot Spotter/Liveboard workflow once MCP is back. " f"Raw MCP error: {raw}", "mcp_service", ) return ( "Liveboard creation failed during the MCP liveboard generation step. " "The run stopped instead of falling back to another liveboard path so we can fix the real issue. " f"Raw MCP error: {raw}", "mcp_generation", )