Panel de administración
La consola de administración (theus.pe/console) es donde el equipo operador gestiona el gateway sin tocar el servidor: proveedores upstream y sus keys, rutas de modelos, el cerebro de TITAN, auditoría y métricas. Todo cambio aplica al instante, porque el gateway lee su configuración por request.
Acceso
Los endpoints /api/admin/* exigen una credencial con ámbito de perfil cuyo email figure en THEUS_ADMIN_EMAILS (lista separada por comas en el entorno del gateway). Cualquier otra credencial recibe 403 forbidden. Si la variable está vacía, nadie es admin: el panel queda cerrado por defecto.
Proveedores upstream
Un proveedor es un upstream de inferencia con base_url, api_key, formato de API, prioridad y estado. La regla central del diseño:
0600); en cualquier respuesta del API viaja enmascarada (p. ej. sk-p…abc4) y jamás se loguea en claro.| Campo | Qué es |
|---|---|
name | Nombre visible del proveedor (obligatorio). |
base_url | URL http(s) del API upstream, p. ej. https://api.proveedor.com/v1. |
api_key | Credencial upstream. Solo en el store; enmascarada en toda respuesta. |
api_format | openai (default, compatible OpenAI) o anthropic (API nativa /v1/messages). |
enabled | Un proveedor deshabilitado no sirve tráfico. |
priority | Entero (menor = primero). El primer proveedor habilitado y completo es el transporte por defecto cuando no hay entorno THEUS_UPSTREAM_*. |
notes | Notas operativas libres. |
Formato anthropic con caching nativo
Cuando un proveedor declara api_format: "anthropic", el gateway traduce cada request canónico al API nativo /v1/messages (headers x-api-key + anthropic-version) y devuelve la respuesta —y el stream— en formato chat.completion. La pieza crítica es el prompt caching explícito: el adaptador marca los breakpoints de cache_control (última tool, último bloque system y último bloque del último mensaje) para que los ~20K tokens fijos de system+tools del CLI se cobren a precio de cache-read en cada turno.
Prueba de conexión real
POST /api/admin/model-providers/{id}/test prueba la key guardada contra el proveedor de verdad: primero GET /models (o GET /v1/models nativo) y, si el upstream no lo expone o pide otra auth, un chat mínimo de 1 token con un modelo de sondeo (el que indiques en el body, el de la primera ruta que apunte al proveedor, o el default). El resultado (ok, HTTP, latencia, detalle) queda guardado en last_test y en la auditoría.
Rutas de modelos
Las rutas mapean cada id del catálogo (o un alias propio) a {provider_id, upstream_model}. Es la versión administrable de THEUS_MODEL_MAP, que queda como fallback por entorno. PUT /api/admin/model-routes reemplaza el mapa completo y valida cada entrada: el modelo debe ser del catálogo, del mapa env o un alias válido, y el provider_id debe existir.
PUT /api/admin/model-routes
{
"routes": {
"glm-4-6": {"provider_id": "prov_…", "upstream_model": "glm-4.6"},
"theus-embed": {"provider_id": "prov_…", "upstream_model": "text-embedding-…"}
}
}
- Un modelo con ruta usa el
base_url+ key de su proveedor: multi-proveedor real, modelo por modelo. - Al borrar un proveedor, sus rutas se eliminan y esos modelos vuelven al fallback env; si el cerebro TITAN apuntaba a él, se desacopla. Todo queda auditado.
- TITAN solo reparte subtareas a modelos con ruta a proveedor operativo (ver TITAN).
Cerebro TITAN
GET/PATCH /api/admin/titan-config gestiona el cerebro orquestador: enabled, provider_id (un proveedor del panel), model y max_subtasks (1–6). El GET devuelve tres vistas: config (lo guardado en el panel), effective (lo que realmente rige, con su source: store, env o default) y env (los valores TITAN_* del entorno). La prioridad efectiva es panel > entorno > transporte por defecto del gateway.
Auditoría
GET /api/admin/audit devuelve la bitácora de acciones admin (últimos 200 eventos): quién (actor), qué (action: provider.create, provider.update, provider.delete, provider.test, routes.replace, titan.update), sobre qué (target) y cuándo, con el detalle del cambio. El detalle nunca contiene secretos completos: las keys van enmascaradas también aquí.
Métricas y vistas de solo lectura
| Endpoint | Qué devuelve |
|---|---|
GET /api/admin/overview | Panel general: usuarios, API keys (activas/revocadas/expiradas), suscripciones activas por plan, tokens del periodo y totales, proveedores y rutas, estado efectivo de TITAN y del gateway. |
GET /api/admin/users | Usuarios con plan efectivo, número de keys y uso del periodo. |
GET /api/admin/models | El catálogo completo en formato de API. |
GET /api/admin/providers | Vista heredada: el upstream por entorno + los proveedores gestionados, con estado. |
Referencia de endpoints de gestión
| Método y ruta | Acción |
|---|---|
GET /api/admin/model-providers | Lista proveedores (keys enmascaradas) + estado del fallback env. |
POST /api/admin/model-providers | Crea un proveedor (name, base_url, api_key, api_format, enabled, priority, notes). |
PATCH /api/admin/model-providers/{id} | Actualiza cualquiera de esos campos. |
DELETE /api/admin/model-providers/{id} | Elimina el proveedor, sus rutas dependientes y lo desacopla de TITAN. |
POST /api/admin/model-providers/{id}/test | Prueba de conexión real con la key guardada. |
GET /api/admin/model-routes | Rutas actuales + catálogo + mapa env de referencia. |
PUT /api/admin/model-routes | Reemplaza el mapa completo modelo → proveedor. |
GET /api/admin/titan-config | Config del cerebro: guardada, efectiva y del entorno. |
PATCH /api/admin/titan-config | Actualiza enabled, provider_id, model, max_subtasks. |
GET /api/admin/audit | Bitácora de acciones admin (últimos 200 eventos). |
Dónde vive el estado
El gateway persiste todo (usuarios, keys, billing, proveedores, rutas, config de TITAN, auditoría) en un store SQLite en modo WAL (oauth-store.sqlite3, permisos 0600): escrituras atómicas por transacción y lecturas con snapshot. Periódicamente exporta un oauth-store.json de paridad (mismo formato histórico, con backups rotados) para respaldo y restauración. La migración desde el store JSON histórico es automática y única al arrancar; para volver al backend JSON: THEUS_STORE_BACKEND=json. Mantenimiento manual: python theus_oauth_server.py --migrate | --export-json | --backend-info.
.bak y reinicia el servicio. Nunca se pierde estado en silencio.