"""Provider registry — drives integration UI cards and agent help text.""" from __future__ import annotations PROVIDER_REGISTRY: dict[str, dict] = { # ═══ Device Integrations ═══ "strava": { "name": "Strava", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://www.strava.com/oauth/authorize", "token_url": "https://www.strava.com/oauth/token", "scopes": "read,activity:read_all", "help_url": "https://developers.strava.com/", "help_text": "Create an app at developers.strava.com. Set the callback URL to {BASE_URL}/api/integrations/strava/callback", "warning": "Strava ToS prohibits use of their data for AI/ML. Activity sync works but AI coaching should not reference Strava data.", "has_webhook": False, "sync_service": "strava_sync", }, "polar": { "name": "Polar", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://flow.polar.com/oauth2/authorization", "token_url": "https://polarremote.com/v2/oauth2/token", "help_url": "https://admin.polaraccesslink.com/", "help_text": "Register at admin.polaraccesslink.com", "has_webhook": False, "sync_service": "polar_sync", }, "garmin": { "name": "Garmin Connect", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://connect.garmin.com/oauthConfirm", "token_url": "https://connectapi.garmin.com/oauth-service/oauth/token", "scopes": "HEALTH,ACTIVITY", "help_url": "https://developer.garmin.com/gc-developer-program/", "help_text": "Apply at developer.garmin.com — approval ~2 business days, requires a business entity.", "has_webhook": True, "sync_service": "garmin_sync", }, "whoop": { "name": "WHOOP", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://api.prod.whoop.com/oauth/oauth2/auth", "token_url": "https://api.prod.whoop.com/oauth/oauth2/token", "scopes": "read:workout,read:recovery,read:sleep,read:profile,offline", "help_url": "https://developer.whoop.com/", "help_text": "Self-serve at developer.whoop.com. Requires WHOOP device. <10 users without app approval.", "has_webhook": True, "sync_service": "whoop_sync", }, "oura": { "name": "Oura Ring", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://cloud.ouraring.com/oauth/authorize", "token_url": "https://api.ouraring.com/oauth/token", "scopes": "daily,workout,heartrate,session", "help_url": "https://cloud.ouraring.com/v2/docs", "help_text": "Register at cloud.ouraring.com — self-serve, immediate access.", "has_webhook": True, "sync_service": "oura_sync", }, "coros": { "name": "COROS (via MCP)", "type": "mcp_bridge", "category": "device", "fields": [], "help_url": "https://support.coros.com/hc/en-us/articles/17085887816340", "help_text": "COROS has an official MCP server. Add it alongside Diligence in your AI agent config.", "has_webhook": False, "sync_service": None, }, "fitbit": { "name": "Fitbit", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "auth_url": "https://www.fitbit.com/oauth2/authorize", "token_url": "https://api.fitbit.com/oauth2/token", "help_url": "https://dev.fitbit.com/", "help_text": "Register at dev.fitbit.com via Google Cloud Console.", "has_webhook": True, "sync_service": None, }, "withings": { "name": "Withings", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "help_url": "https://developer.withings.com/", "help_text": "Register at developer.withings.com — body metrics, scales, blood pressure.", "has_webhook": False, "sync_service": None, }, "suunto": { "name": "Suunto", "type": "oauth2", "category": "device", "fields": ["client_id", "client_secret"], "help_url": "https://apizone.suunto.com/", "help_text": "Apply at Suunto developer portal — contract required, ~2 week response.", "has_webhook": True, "sync_service": None, }, # ═══ AI Coaching Providers ═══ "openai": { "name": "OpenAI", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://api.openai.com/v1", "api_format": "openai", "help_url": "https://platform.openai.com/api-keys", "help_text": "Get API key from platform.openai.com. Models: gpt-4o, gpt-4o-mini.", "default_model": "gpt-4o-mini", }, "openrouter": { "name": "OpenRouter", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://openrouter.ai/api/v1", "api_format": "openai", "help_url": "https://openrouter.ai/keys", "help_text": "One key, 300+ models. 26 free models. Pay-as-you-go, no subscription.", "default_model": "openai/gpt-4o-mini", }, "huggingface": { "name": "Hugging Face", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://router.huggingface.co/v1", "api_format": "openai", "help_url": "https://huggingface.co/settings/tokens", "help_text": "Free HF token. Thousands of open-source models via 20+ inference providers.", "default_model": "meta-llama/Llama-3.3-70B-Instruct", }, "groq": { "name": "Groq", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://api.groq.com/openai/v1", "api_format": "openai", "help_url": "https://console.groq.com/keys", "help_text": "Ultra-fast inference. Free tier available. Also used for program research.", "default_model": "llama-3.3-70b-versatile", }, "ollama": { "name": "Ollama (Local)", "type": "endpoint", "category": "ai_provider", "fields": ["endpoint_url"], "base_url": "http://host.docker.internal:11434/v1", "api_format": "openai", "help_url": "https://ollama.com/", "help_text": "Run LLMs locally. No API key, no cost. Default: http://host.docker.internal:11434", "default_model": "llama3.1", }, "claude": { "name": "Anthropic Claude", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://api.anthropic.com/v1", "api_format": "anthropic", "help_url": "https://console.anthropic.com/", "help_text": "Get API key from console.anthropic.com. Models: claude-sonnet-4-6, claude-opus-4-8.", "default_model": "claude-sonnet-4-6", }, "gemini": { "name": "Google Gemini", "type": "api_key", "category": "ai_provider", "fields": ["api_key"], "base_url": "https://generativelanguage.googleapis.com/v1beta", "api_format": "gemini", "help_url": "https://aistudio.google.com/apikey", "help_text": "Get API key from AI Studio. Models: gemini-2.0-flash, gemini-2.5-pro.", "default_model": "gemini-2.0-flash", }, "custom_ai": { "name": "Custom (OpenAI-compatible)", "type": "endpoint", "category": "ai_provider", "fields": ["endpoint_url", "api_key"], "api_format": "openai", "help_url": "", "help_text": "Any server with an OpenAI-compatible /v1/chat/completions endpoint (vLLM, TGI, LiteLLM).", "default_model": "", }, # ═══ Nutrition & Data ═══ "usda": { "name": "USDA FoodData Central", "type": "api_key", "category": "nutrition", "fields": ["api_key"], "help_url": "https://fdc.nal.usda.gov/api-key-signup", "help_text": "Free API key, no approval needed. 400K+ foods with research-grade nutrition data.", }, "nutritionix": { "name": "Nutritionix", "type": "api_key", "category": "nutrition", "fields": ["app_id", "api_key"], "help_url": "https://developer.nutritionix.com/", "help_text": "Free tier: 1K calls/month. Natural language food parsing.", }, # ═══ Notifications ═══ "telegram": { "name": "Telegram Notifications", "type": "api_key", "category": "notifications", "fields": ["bot_token", "chat_id"], "help_url": "https://core.telegram.org/bots#botfather", "help_text": "Create a bot via @BotFather, then get your chat ID.", }, }