Files
openswarm/backend/apps/nine_router/connected.py
T

39 lines
1.7 KiB
Python

"""Which subscriptions the app's router actually holds. The settings file still carries three
`*_subscription_token` fields that nothing has written since the OAuth flow moved into 9router, so
anything that answers "is a subscription connected?" from settings says no while the Settings page
says Connected (Chuya, 2026-09-04: the agent told her the Claude subscription serving her chat was
not connected). Every such answer reads from here."""
from __future__ import annotations
from typing import Optional
SUBSCRIPTION_LABELS = {"claude": "Claude Pro/Max", "codex": "ChatGPT Plus/Pro", "gemini-cli": "Gemini Advanced"}
ROUTER_UNKNOWN = "unknown (the app's router is not running)"
async def connected_subscription_providers() -> Optional[list[str]]:
"""Provider ids with a live user-owned subscription, or None when the router cannot say.
None is not "none connected": a router that is down or mid-boot must never read as disconnected."""
from backend.apps.nine_router import NINE_ROUTER_CLAUDE_PRO_NAME, get_providers, is_running
if not is_running():
return None
try:
conns = await get_providers()
except Exception:
return None
seen: list[str] = []
for c in conns:
provider = c.get("provider")
# The managed OpenSwarm Pro node registers as a `claude` connection; it is ours, not the user's.
if c.get("isActive") and provider in SUBSCRIPTION_LABELS and c.get("name") != NINE_ROUTER_CLAUDE_PRO_NAME and provider not in seen:
seen.append(provider)
return seen
def subscription_labels(providers: Optional[list[str]]) -> list[str] | str:
if providers is None:
return ROUTER_UNKNOWN
return [SUBSCRIPTION_LABELS[p] for p in providers if p in SUBSCRIPTION_LABELS]