Ctrl K
ComunidadGuías…

utils/providerDashboards.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * Where each provider's own account lives, keyed by the provider id the rest of
 * the runtime already uses (`providers` in `models.ts`, `providerID=` in the
 * opencode log). Both failure surfaces read this one table — the per-run PR
 * comment for its top-up CTA, and the diagnosis agent's link registry — so a
 * host move is fixed in one place. Every catalog provider is here except
 * `openai-compatible`, whose endpoint is the customer's own and has no page.
 *
 * How each path is known (2026-09-14), because "checked" means three different
 * things here. Probed with a discriminating control — the path answers 200 and
 * a junk path on the same host 404s: `platform.claude.com`, `platform.kimi.ai`,
 * `www.kimi.com`, `dev.meta.ai`, `opencode.ai`, the AWS billing host.
 * Taken from the provider's own docs, because the host answers a probe with a
 * Cloudflare challenge or a catch-all login redirect that no junk path can
 * distinguish: OpenAI, xAI, DeepSeek, `claude.ai`, `chatgpt.com`, Google,
 * OpenRouter, Vercel, `grok.com`. Fragment routes (`#…`) never reach a server,
 * so those rest on the docs alone. `console.anthropic.com` and
 * `platform.moonshot.ai` both 301 now, so the entries name the hosts they land
 * on.
 *
 * The subscription rows are not providers in the catalog sense — a Claude,
 * ChatGPT or SuperGrok plan has a usage window and a plan page but no API key —
 * so they carry the `-plan` suffix, no `keys`, and the credential that proves
 * the plan is in play.
 */
export type ProviderDashboard = {
  /** the name a customer knows the account by */
  name: string;
  /** a plan row only: the stored credential whose presence means the plan is in use */
  credential?: string;
  /** the wallet, the card on file, a spend cap, or the plan itself */
  billing: string;
  /** spend to date, or a plan's limit window and its reset time */
  usage?: string;
  /** where an API key is created or rotated */
  keys?: string;
};

export const PROVIDER_DASHBOARDS: Record<string, ProviderDashboard> = {
  anthropic: {
    name: "Anthropic",
    billing: "https://platform.claude.com/settings/billing",
    usage: "https://platform.claude.com/usage",
    keys: "https://platform.claude.com/settings/keys",
  },
  "claude-plan": {
    name: "Claude",
    credential: "CLAUDE_CODE_OAUTH_TOKEN",
    billing: "https://claude.ai/settings/billing",
    usage: "https://claude.ai/settings/usage",
  },
  openai: {
    name: "OpenAI",
    billing: "https://platform.openai.com/settings/organization/billing/overview",
    usage: "https://platform.openai.com/settings/organization/usage",
    keys: "https://platform.openai.com/api-keys",
  },
  "codex-plan": {
    name: "Codex / ChatGPT",
    credential: "CODEX_AUTH_JSON",
    billing: "https://chatgpt.com/#settings/Subscription",
    usage: "https://chatgpt.com/codex/settings/usage",
  },
  google: {
    name: "Google AI Studio",
    // AI Studio's "Usage & billing" page is where the Gemini API plan lives;
    // the Cloud billing console is a level up and needs a project picked.
    billing: "https://aistudio.google.com/usage",
    keys: "https://aistudio.google.com/apikey",
  },
  vertex: {
    name: "Google Vertex AI",
    billing: "https://console.cloud.google.com/billing",
    usage: "https://console.cloud.google.com/vertex-ai",
  },
  xai: {
    name: "xAI",
    billing: "https://console.x.ai/team/default/billing",
    usage: "https://console.x.ai/team/default/usage",
    keys: "https://console.x.ai/team/default/api-keys",
  },
  "grok-plan": {
    name: "SuperGrok",
    credential: "GROK_AUTH_JSON",
    billing: "https://grok.com/?_s=billing",
  },
  deepseek: {
    name: "DeepSeek",
    billing: "https://platform.deepseek.com/top_up",
    usage: "https://platform.deepseek.com/usage",
    keys: "https://platform.deepseek.com/api_keys",
  },
  moonshotai: {
    name: "Moonshot (Kimi API)",
    billing: "https://platform.kimi.ai/console/pay",
    usage: "https://platform.kimi.ai/console/account",
    keys: "https://platform.kimi.ai/console/api-keys",
  },
  "kimi-for-coding": {
    name: "Kimi Code",
    billing: "https://www.kimi.com/membership/pricing",
    keys: "https://www.kimi.com/code/console",
  },
  meta: {
    name: "Meta Model API",
    billing: "https://dev.meta.ai/billing",
    usage: "https://dev.meta.ai/usage",
    keys: "https://dev.meta.ai/api-keys",
  },
  opencode: {
    name: "OpenCode Zen",
    billing: "https://opencode.ai/zen",
    keys: "https://opencode.ai/zen",
  },
  // Go is a separate plan on the same key, with its own usage cap that resets
  // on its own (wiki/opencode-silent-stall.md). Its page is the plan page; no
  // per-window usage page is documented.
  "opencode-go": {
    name: "OpenCode Go",
    billing: "https://opencode.ai/go",
    keys: "https://opencode.ai/zen",
  },
  openrouter: {
    name: "OpenRouter",
    billing: "https://openrouter.ai/settings/credits",
    usage: "https://openrouter.ai/activity",
    keys: "https://openrouter.ai/workspaces/default/keys",
  },
  vercel: {
    name: "Vercel AI Gateway",
    // `/d?to=` resolves `[team]` to whichever team the visitor is signed into.
    billing: "https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai-gateway",
    keys: "https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai-gateway%2Fapi-keys",
  },
  bedrock: {
    name: "Amazon Bedrock",
    billing: "https://console.aws.amazon.com/billing/home",
    keys: "https://us-east-1.console.aws.amazon.com/bedrock/home#/api-keys",
  },
  // Azure OpenAI keys are per-resource, so there is no stable keys page to name.
  azure: {
    name: "Azure OpenAI",
    billing: "https://portal.azure.com/#view/Microsoft_Azure_CostManagement/Menu/~/overview",
  },
};