Repository navigation
Description
Pre-flight checks
- I searched the existing issues and the roadmap: no duplicates or overlap.
- I understand that this proposal requires product review before implementation.
Problem to solve
Quorb supports aggregators such as 9Router and OpenRouter, but it has no integration with CLIProxyAPI (router-for-me/CLIProxyAPI), the local gateway used to unify, balance and manage access to Gemini, Claude, OpenAI and Vertex AI models without the noise of individual OAuth accounts in every client.
Note on naming: CPAMC is the management Web UI of CLIProxyAPI, not the service itself. This issue originally named the provider cpamc, which was wrong — the provider is named cliproxy below.
Proposed solution
A native cliproxy provider (Kind::Api, like the 9Router aggregator), against the versioned Management API v8 of CLIProxyAPI:
- Endpoints (
Authorization: Bearer <management_key>orX-Management-Key):GET /v8/management/credentials→ per-credential health:status,disabled,unavailable. This is the real health/cooldown signal.GET /v8/management/credentials/models?name=<file-or-id>andGET /v8/management/routing/model-definitions/:channel→ model catalogs per credential and per channel.GET /v8/management/plugins/:id/quota?auth_index=…→ quota figures, only when a quota plugin is installed (a base installation exposes no quota numbers).
- Health is per credential, aggregated per channel: cooldown and degradation live on the credential (
auth_index), while models are grouped by channel. The provider therefore watches credentials and rolls their health up into the channels shown in the widget. - The ring needs numbers, so the provider reports two layers:
- Always: credential health as
UsageReport.status+message(Ok/Warning/Error) — state without figures. - When available: the quota numbers from the plugin endpoint, as
percent/used/limit.
Without a quota plugin the widget must be able to render a state-only meter (status + message, no percentage). That is a small change to the meter rendering and is part of this scope.
- Always: credential health as
- Configuration and UI:
- Parameters:
base_url(defaulthttp://127.0.0.1:8317), the management key in the secure store (secrets::CLIPROXY_MANAGEMENT_KEY), and the credentials/channels to watch. - Section in
Settings.tsxwith a live connection test against a read-only endpoint (GET /v8/management/credentials). - HTTPS is required outside loopback: the management key grants full control of the proxy, so a remote
base_urlover plain HTTP is refused, or explicitly warned about in Settings.
- Parameters:
- Assets and tests:
- Vector SVG logo
cliproxy.svgin the asset catalog. - Rust unit tests over fixtures: healthy credential, credential in cooldown, credential disabled, and the state-only case (no quota plugin).
- Vector SVG logo
Affected area
Application behavior
Scope and non-goals
- Scope: Monitoring the health of the credentials —and, when a quota plugin is present, the quota— of a local or remote CLIProxyAPI instance.
- Non-goals: Mutating the proxy. No
PATCH /credentials/status, noPOST /routing/cooldown/reset, no credential management from Quorb.
Open question
The v8 Management API does not exist in CLIProxyAPI v7: on my own instances /v8/management/credentials returns 404, and only v8 serves it. Should the provider detect the version and degrade to an "unsupported" state, or is v8 a hard requirement?
Alternatives considered
- Adapting the 9Router provider: its auth schemes and endpoints differ significantly.
- Scoping the provider to plugin quota only: it would make the integration useless on a base installation, where no quota figures exist.
Activity
egdev6 commentedon Oct 21, 2026
¡Gracias por la propuesta, @Rafaeldelinares! La idea encaja con el hueco real (Quorb ya cubre 9Router y OpenRouter como gateways), pero he verificado la propuesta contra el proyecto de router-for-me y la spec necesita reelaborarse sobre la API actual antes de aprobarse. Detalles:
1. Nomenclatura: CPAMC no es el servicio⚠️
CPAMC (CLI Proxy API Management Center) es la Web UI de administración; el servicio real es CLIProxyAPI (
router-for-me/CLIProxyAPI). El proveedor integraría la Management API de CLIProxyAPI — sugiero nombrar el providercliproxy(o similar) y describirlo así en la ficha para no confundir ambos proyectos.2. El endpoint propuesto no existe en la API vigente⚠️
GET <base_url>/management/api/modelsno aparece en la documentación actual. La Management API actual está versionada bajo/v8/management/…(conAuthorization: Bearer <management_key>oX-Management-Key;/v0/managementestá cerca de su deprecación). Los endpoints reales y relevantes son:GET /v8/management/credentials→ estado de cada credencial (status,disabled,unavailable): es la señal real de salud/cooldown del pool.GET /v8/management/credentials/models?name=<file-or-id>yGET /v8/management/routing/model-definitions/:channel→ catálogos de modelos por credencial/canal.GET /v8/management/plugins/:id/quota?auth_index=…→ cuota, dependiente de plugins (no hay números de cuota en la instalación base).3. La salud es por credencial, no por modelo⚠️
El cooldown y la degradación en CLIProxyAPI son por credencial (
auth_index), y los modelos se agrupan por canal. El monitoreotarget_modelspor modelo concreto, tal como está planteado, no mapea directamente con lo que expone la API. La spec debería decidir entre: (a) monitorizar credenciales y agregar salud por canal, y/o (b) exponer la cuota de plugins cuando exista.4. El anillo necesita números⚠️ (cuestión de producto)
El widget de Quorb se alimenta de medidores numéricos (
percent,used,limitenMeter). Sin plugin de cuota, CLIProxyAPI solo da estado — eso mapea aUsageReport.status+message, pero habría que definir qué muestra el anillo cuando no hay datos numéricos (o acotar el scope a la cuota vía plugins). Este es el punto que más me gustaría ver resuelto en la ficha.5.
Kindℹ️Sugiero
Kind::Apien lugar deKind::Subscription, como el agregador 9Router: el proxy no es una suscripción, enruta cuentas propias.6. Seguridad⚠️
La management key da control total del proxy (puede deshabilitar credenciales, resetear cooldown…). Con
base_urllocal (http://127.0.0.1:8317) es correcto, pero si el usuario apunta a un host remoto el Bearer viajaría en claro: la spec debería exigir HTTPS fuera de loopback (o avisar explícitamente en Ajustes), y el test de conexión debe usar un endpoint de solo lectura.7. Non-goals ✓
Bien trazados: nada de mutaciones (
PATCH /credentials/status,POST /routing/cooldown/resetquedan fuera).Conclusión: prometedora y con demanda real, pero necesita una reespeccificación sobre
/v8/management(puntos 2–4) antes de pasar astatus:approved. Si reescribes la issue con esos matices, la re-reviso con gusto.egdev6 commentedon Oct 21, 2026
@Rafaeldelinares te dejo aquí el resumen accionable de la revisión: la propuesta tiene demanda real, pero antes de poder aprobarla necesita una reescritura de la spec sobre la Management API v8 real de CLIProxyAPI:
GET /management/api/modelspor los endpoints vigentes:GET /v8/management/credentials(salud por credencial),GET /v8/management/credentials/models?name=yGET /v8/management/routing/model-definitions/:channel.target_modelstal cual no mapea)./v8/management/plugins/:id/quota).Kind::Api(precedente 9Router) y exige HTTPS fuera de loopback con test de conexión de solo lectura.Cuando actualices la issue con estos puntos, la re-reviso y, si todo cuadra, pasa a
status:approved. ¡Gracias!Rafaeldelinares commentedon Oct 23, 2026
@egdev6 He reescrito la spec en el cuerpo de la issue con los siete puntos de tu review. Lo que cambia de fondo:
cliproxy, como sugeriste —CPAMC es la Web UI, no el servicio— y el tipo queda enKind::Api.GET /management/api/models→GET /v8/management/credentials(salud por credencial),GET /v8/management/credentials/models?name=yGET /v8/management/routing/model-definitions/:channel. Ninguna mutación:PATCH /credentials/statusyPOST /routing/cooldown/resetquedan fuera de alcance.auth_index) y los modelos se agrupan por canal, así que el provider vigila credenciales y agrega su salud en los canales que muestra el widget.UsageReport.status+message; y cuando existe, la cuota del plugin de cuota comopercent/used/limit. Sin plugin de cuota, el widget tiene que poder pintar un medidor solo de estado (estado + mensaje, sin porcentaje), y eso es un cambio acotado en el render del medidor, dentro del alcance de esta issue.GET /v8/management/plugins/:id/quota?auth_index=…depende de plugins instalados, así que queda como capa opcional, no como parte del anillo principal.GET /v8/management/credentials).Una pregunta de entorno que dejé abierta en la spec: la Management API v8 no existe en la v7.3.3 —en mis instancias
/v8/management/credentialsdevuelve 404 y solo la v8 lo sirve—. ¿El provider debe detectar la versión y degradar a un estado "no soportado", o damos la v8 por supuesto como requisito mínimo?egdev6 commentedon Oct 23, 2026
@Rafaeldelinares revisada la spec reescrita — aprobada sobre lo que queda del issue. Los siete puntos están bien integrados: nomenclatura real (
cliproxy,Kind::Api), endpoints v8 correctos, salud por credencial agregada por canal, anillo de dos capas sin inventar números, quota plugin como capa opcional, sin mutaciones, y HTTPS fuera de loopback. El diseño de dos capas resuelve lo que motivó tu punto 4: un provider de salud no puede pintar un anillo sin números, y estado+mensaje siempre disponible es lo correcto.Decisión sobre la pregunta abierta: detectar y degradar, no v8 como requisito.
GET /v8/management/credentialscomo primer request (es el mismo que usa el test de conexión). Si responde 404, el reporte va conStatus::Warning/mensaje accionable: «tu CLIProxyAPI no expone la Management API v8 — actualiza el proxy para ver el estado».404 en /v8/management/*(versión sin v8) junto a los cuatro que ya listas.Con esto, la spec queda cerrada y la issue elegible para su ODD (fase observar/decidir → plan de tareas) según el flujo de CONTRIBUTING. Recuerda el flujo: abre el ODD del task, lo reviso, y con aprobación arranca implementación. Sin assignee todavía — asígnate cuando empieces, como siempre.