{"repo": "anjieyang/iykyk", "files": {"uncommon_route/providers.py": {"563bb76bc8515bfaf872edb3864275a644f45ca9": {"t": 1785674102.2637587, "n": 10304, "h": "cc4a3f5dbf035074", "c": "\"\"\"BYOK (Bring Your Own Key) provider management.\n\nUsers configure their own API keys and subscription plans.\nWhen routing, models backed by a user-provided key are prioritized\nsince the user already pays for them.\n\nConfig stored at ~/.uncommon-route/providers.json\n\nExample (providers.json):\n {\n \"providers\": {\n \"minimax\": {\n \"api_key\": \"eyJ...\",\n \"base_url\": \"https://api.minimax.io/v1\",\n \"models\": [\"minimax/minimax-m2.5\"],\n \"plan\": \"coding-plan\"\n },\n \"deepseek\": {\n \"api_key\": \"sk-...\",\n \"base_url\": \"https://api.deepseek.com/v1\",\n \"models\": [\"deepseek/deepseek-chat\", \"deepseek/deepseek-reasoner\"]\n }\n }\n }\n\"\"\"\n\nfrom __future__ import annotations\n\nimport json\nimport sys\nfrom dataclasses import dataclass, field\nfrom pathlib import Path\n\nfrom uncommon_route.paths import data_dir\n\n_DATA_DIR = data_dir()\n_PROVIDERS_FILE = _DATA_DIR / \"providers.json\"\n\nKNOWN_BASE_URLS: dict[str, str] = {\n \"commonstack\": \"https://api.commonstack.ai/v1\",\n \"minimax\": \"https://api.minimax.io/v1\",\n \"deepseek\": \"https://api.deepseek.com/v1\",\n \"openai\": \"https://api.openai.com/v1\",\n \"anthropic\": \"https://api.anthropic.com/v1\",\n \"google\": \"https://generativelanguage.googleapis.com/v1beta\",\n \"xai\": \"https://api.x.ai/v1\",\n \"moonshot\": \"https://api.moonshot.cn/v1\",\n}\n\nPROVIDER_MODELS: dict[str, list[str]] = {\n \"minimax\": [\"minimax/minimax-m2.5\"],\n \"deepseek\": [\"deepseek/deepseek-chat\", \"deepseek/deepseek-reasoner\"],\n \"openai\": [\n \"openai/gpt-4o-mini\",\n \"openai/gpt-4o\",\n \"openai/gpt-5.2\",\n \"openai/gpt-5.2-codex\",\n \"openai/o1-mini\",\n \"openai/o3\",\n \"openai/o4-mini\",\n ],\n \"anthropic\": [\"anthropic/claude-haiku-4.5\", \"anthropic/claude-sonnet-4.6\", \"anthropic/claude-opus-4.6\"],\n \"google\": [\n \"google/gemini-2.5-flash-lite\",\n \"google/gemini-2.5-flash\",\n \"google/gemini-2.5-pro\",\n \"google/gemini-3-pro-preview\",\n \"google/gemini-3.1-pro\",\n ],\n \"xai\": [\n \"xai/grok-4-1-fast-reasoning\",\n \"xai/grok-4-1-fast-non-reasoning\",\n \"xai/grok-4-0709\",\n \"xai/grok-code-fast-1\",\n ],\n \"moonshot\": [\"moonshot/kimi-k2.5\"],\n}\n\n\n@dataclass\nclass ProviderEntry:\n name: str\n api_key: str\n base_url: str\n models: list[str] = field(default_factory=list)\n plan: str = \"\"\n\n\n@dataclass\nclass ProvidersConfig:\n providers: dict[str, ProviderEntry] = field(default_factory=dict)\n\n def keyed_models(self) -> set[str]:\n \"\"\"All model IDs backed by a user-provided key.\"\"\"\n result: set[str] = set()\n for entry in self.providers.values():\n result.update(entry.models)\n return result\n\n def get_for_model(self, model_id: str) -> ProviderEntry | None:\n \"\"\"Find the provider entry that covers a given model.\"\"\"\n for entry in self.providers.values():\n if model_id in entry.models:\n return entry\n return None\n\n def provider_names(self) -> list[str]:\n return list(self.providers.keys())\n\n\ndef load_providers(path: Path | None = None) -> ProvidersConfig:\n \"\"\"Load provider config from disk.\"\"\"\n filepath = path or _PROVIDERS_FILE\n if not filepath.exists():\n return ProvidersConfig()\n try:\n raw = json.loads(filepath.read_text())\n config = ProvidersConfig()\n for name, data in raw.get(\"providers\", {}).items():\n if not isinstance(data, dict) or not data.get(\"api_key\"):\n continue\n config.providers[name] = ProviderEntry(\n name=name,\n api_key=data[\"api_key\"],\n base_url=data.get(\"base_url\", KNOWN_BASE_URLS.get(name, \"\")),\n models=data.get(\"models\", PROVIDER_MODELS.get(name, [])),\n plan=data.get(\"plan\", \"\"),\n )\n return config\n except Exception:\n return ProvidersConfig()\n\n\ndef save_providers(config: ProvidersConfig, path: Path | None = None) -> None:\n \"\"\"Save provider config to disk.\"\"\"\n filepath = path or _PROVIDERS_FILE\n filepath.parent.mkdir(parents=True, exist_ok=True, mode=0o700)\n data = {\n \"providers\": {\n name: {\n \"api_key\": entry.api_key,\n \"base_url\": entry.base_url,\n \"models\": entry.models,\n **({\"plan\": entry.plan} if entry.plan else {}),\n }\n for name, entry in config.providers.items()\n }\n }\n filepath.write_text(json.dumps(data, indent=2))\n filepath.chmod(0o600)\n\n\ndef add_provider(\n name: str,\n api_key: str,\n base_url: str | None = None,\n models: list[str] | None = None,\n plan: str = \"\",\n config: ProvidersConfig | None = None,\n) -> ProvidersConfig:\n \"\"\"Add or update a provider. Returns updated config (also saves to disk).\"\"\"\n cfg = config or load_providers()\n resolved_url = base_url or KNOWN_BASE_URLS.get(name, \"\")\n resolved_models = models or PROVIDER_MODELS.get(name, [])\n\n cfg.providers[name] = ProviderEntry(\n name=name,\n api_key=api_key,\n base_url=resolved_url,\n models=resolved_models,\n plan=plan,\n )\n save_providers(cfg)\n return cfg\n\n\ndef remove_provider(name: str, config: ProvidersConfig | None = None) -> bool:\n \"\"\"Remove a provider. Returns True if removed.\"\"\"\n cfg = config or load_providers()\n if name not in cfg.providers:\n return False\n del cfg.providers[name]\n save_providers(cfg)\n return True\n\n\ndef select_preferred_model(\n tier_models: list[str],\n user_config: ProvidersConfig,\n) -> tuple[str | None, ProviderEntry | None]:\n \"\"\"Given a list of candidate models for a tier, return the first one backed by a user key.\n\n Returns (model_id, provider_entry) or (None, None) if no match.\n \"\"\"\n keyed = user_config.keyed_models()\n for model in tier_models:\n if model in keyed:\n return model, user_config.get_for_model(model)\n return None, None\n\n\ndef verify_key(base_url: str, api_key: str) -> tuple[bool, str]:\n \"\"\"Ping ``/v1/models`` to check if an API key is valid.\n\n Returns ``(ok, detail)`` — *detail* is a human-readable status string.\n \"\"\"\n import httpx\n\n url = f\"{base_url.rstrip('/')}/models\"\n try:\n resp = httpx.get(\n url,\n headers={\"authorization\": f\"Bearer {api_key}\"},\n timeout=httpx.Timeout(8.0, connect=4.0),\n )\n if resp.status_code == 200:\n data = resp.json()\n count = len(data.get(\"data\", []))\n return True, f\"{count} models available\"\n if resp.status_code == 401:\n return False, \"invalid or expired API key (HTTP 401)\"\n if resp.status_code == 403:\n return False, \"access denied (HTTP 403)\"\n return False, f\"unexpected HTTP {resp.status_code}\"\n except httpx.ConnectError:\n return False, f\"cannot connect to {url}\"\n except httpx.TimeoutException:\n return False, f\"timeout connecting to {url}\"\n except Exception as exc: # noqa: BLE001\n return False, str(exc)\n\n\ndef cmd_provider(args: list[str]) -> None:\n \"\"\"Handle `uncommon-route provider `.\"\"\"\n if not args:\n args = [\"list\"]\n\n sub = args[0]\n\n if sub == \"list\":\n cfg = load_providers()\n if not cfg.providers:\n print(\" No providers configured\")\n print()\n print(\" Add one: uncommon-route provider add \")\n print(\" Example: uncommon-route provider add deepseek sk-...\")\n return\n print(f\" Configured providers ({len(cfg.providers)}):\")\n for name, entry in cfg.providers.items():\n key_preview = entry.api_key[:8] + \"...\" if len(entry.api_key) > 8 else \"***\"\n plan_str = f\" [{entry.plan}]\" if entry.plan else \"\"\n print(f\" {name}: {key_preview}{plan_str}\")\n print(f\" URL: {entry.base_url}\")\n print(f\" Models: {', '.join(entry.models)}\")\n\n elif sub == \"add\":\n if len(args) < 3:\n print(\"Usage: uncommon-route provider add [--plan ]\", file=sys.stderr)\n print(f\" Known providers: {', '.join(KNOWN_BASE_URLS.keys())}\", file=sys.stderr)\n sys.exit(1)\n name = args[1]\n api_key = args[2]\n plan = \"\"\n if \"--plan\" in args:\n idx = args.index(\"--plan\")\n if idx + 1 < len(args):\n plan = args[idx + 1]\n base_url = None\n if \"--url\" in args:\n idx = args.index(\"--url\")\n if idx + 1 < len(args):\n base_url = args[idx + 1]\n\n add_provider(name, api_key, base_url=base_url, plan=plan)\n models = PROVIDER_MODELS.get(name, [])\n print(f\" Added provider: {name}\")\n if models:\n print(f\" Models: {', '.join(models)}\")\n\n resolved_url = base_url or KNOWN_BASE_URLS.get(name, \"\")\n if resolved_url:\n ok, detail = verify_key(resolved_url, api_key)\n if ok:\n print(f\" Key verified: {detail}\")\n else:\n print(f\" Warning: key verification failed — {detail}\")\n print(\" The key was saved but may not work. Check with: uncommon-route doctor\")\n print(\" These models will be prioritized when routing to their tier\")\n\n elif sub == \"remove\":\n if len(args) < 2:\n print(\"Usage: uncommon-route provider remove \", file=sys.stderr)\n sys.exit(1)\n removed = remove_provider(args[1])\n print(f\" {'Removed' if removed else 'Not found'}: {args[1]}\")\n\n elif sub == \"models\":\n cfg = load_providers()\n keyed = cfg.keyed_models()\n if not keyed:\n print(\" No user-keyed models\")\n return\n print(f\" User-keyed models ({len(keyed)}):\")\n for m in sorted(keyed):\n provider = cfg.get_for_model(m)\n print(f\" {m} (via {provider.name})\" if provider else f\" {m}\")\n\n else:\n print(f\"Unknown provider subcommand: {sub}\", file=sys.stderr)\n print(\" Available: list, add, remove, models\", file=sys.stderr)\n sys.exit(1)\n"}}}}