Saltar al contenido
theus.pe ↗

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, el catálogo de las organizaciones Atlas, 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 sesión web u OAuth con ámbito de perfil y un rol administrativo efectivo. Los emails de THEUS_ADMIN_EMAILS son propietarios por compatibilidad; los demás operadores entran solo si están registrados en rbac_members. Una API key permanente nunca administra. Cualquier otra credencial recibe 403 forbidden.

Esta página es para operadores de la plataforma. Si eres suscriptor, tu superficie es el dashboard de cuenta y la API /v1.

Roles por workspace (RBAC). Sobre el acceso base, el gateway resuelve un rol por email y aplica permisos acotados a cada endpoint de gestión. Los emails de THEUS_ADMIN_EMAILS son owner (acceso total). A los demás miembros se les asigna un rol con el alcance justo:

  • owner — todo, incluida la gestión de miembros.
  • admin — operación completa (proveedores, rutas, TITAN, guardián, mantenimiento, enforcement), sin gestión de miembros.
  • billing — suscripciones, packs y saldo; nada de infraestructura.
  • auditor — solo lectura de auditoría, métricas y resumen.
  • support — ver usuarios y acreditar saldo, nada más.

Así, por ejemplo, quien lleva facturación no puede tocar los proveedores upstream, y un auditor externo solo lee. Los miembros se gestionan en /api/admin/members; el sistema impide dejar el workspace sin ningún owner (anti-lockout).

Planes y créditos de clientes

La ficha del cliente permite cambiar su plan efectivo y agregar créditos sin tocar manualmente el store. Ambas operaciones requieren confirmación, motivo cerrado, nota interna opcional y una clave idempotente; el gateway rechaza con 409 reutilizar esa clave para una intención distinta.

  • POST /api/admin/subscriptions/plan crea un ajuste administrativo separado de la suscripción Stripe. El plan cobrado y sus identificadores nunca se falsean. Enviar plan: "inherit" retira el ajuste y vuelve al plan real de facturación.
  • POST /api/admin/wallet/credit agrega créditos enteros con categorías como gracia, donación, recarga, compensación, promoción, reembolso, SLA, soporte o migración. Motivo, nota y actor quedan en el ledger y en la auditoría.
  • Si una cuenta pierde un plan con Enterprise, el mismo cambio revoca pases, correlación y credenciales de consumo. Si vuelve a Omnipotente, la organización se reactiva sin duplicarse en el próximo acceso.
  • POST /api/admin/atlas/override concede una cortesía del plan Atlas: el espejo del anterior sobre el producto Atlas. Se guarda aparte de la suscripción cobrada y de sus identificadores, así que no falsea lo que el cliente paga; compite por rango con la suscripción Atlas directa y con el plan Atlas que incluye su plan Theus, y gana el escalón mayor — una cortesía nunca degrada una suscripción pagada. Toda cortesía caduca: dias (o expires_at) es obligatorio al conceder y no puede pasar de 366 días; vencida, deja de existir sola. Enviar plan: "inherit" la retira antes de tiempo. Exige motivo cerrado e idempotency_key, igual que el resto.

Catálogo de las organizaciones Atlas

Cada organización de Atlas by Theus se da de alta en el motor con una credencial propia y el catálogo de modelos del release: sus ids, su ventana de contexto, su techo de salida y si el modelo admite modo pensamiento. Ese alta lleva una huella del catálogo con el que se hizo; cuando un despliegue cambia el catálogo, las organizaciones ya aprovisionadas quedan con la huella vieja.

Hasta ahora esa puesta al día era perezosa: cada organización se re-aprovisionaba en la siguiente visita de su cliente, y ese trabajo —rotar la credencial y volver a registrar los ~40 modelos río arriba— corría dentro de la propia petición de su navegador. Un cambio de catálogo llegaba a los clientes nuevos y a ninguno de los que ya pagaban, en silencio.

POST /api/admin/enterprise/reconciliar   → 202 { ok, estado, en_proceso[], al_dia[], omitidas[] }
GET  /api/admin/enterprise/reconciliar   → { estado, pendientes, resultados[] }
  • Se dispara una vez tras el despliegue y devuelve al instante (202): recorre las organizaciones desfasadas en segundo plano, en un hilo propio, sin ocupar el pool que despacha avisos.
  • Una sola pasada viva: un segundo disparo con otra en curso recibe 409 reconciliacion_en_curso. Dos pasadas a la vez no rompen nada, pero duplicarían rotaciones de credencial sin ganar nada.
  • Cortacircuitos: tras 3 fallos seguidos la pasada se aborta en vez de recorrer el resto del padrón. Un re-alta fallido deja las filas de modelos apuntando a una credencial retirada; con el motor caído, seguir sería hacérselo a todas las organizaciones de una sentada.
  • El GET es solo lectura y devuelve el avance de la última pasada, con una fila por organización y su veredicto: re_aprovisionada, al_dia, error, revocada, sin_plan o no_intentada (las que quedaron sin tocar cuando el cortacircuitos abortó la pasada; el estado global de esa pasada es abortado). Es un snapshot en memoria: un reinicio del servicio lo borra y la siguiente pasada lo recalcula entero desde el store.
  • Permisos: POST exige providers:write; GET, providers:read. El disparo queda en la auditoría como enterprise.gateway.reconcile.
Ejecútalo como último paso de todo despliegue que cambie el catálogo Enterprise (modo pensamiento, techo de salida, alta o baja de modelos). Si no, el catálogo del release solo alcanza a las organizaciones nuevas.

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:

Pones la key en la consola → funciona al instante en el CLI, sin reiniciar nada. La key completa vive solo en el store del servidor (permisos 0600); en cualquier respuesta del API viaja enmascarada (p. ej. sk-p…abc4) y jamás se loguea en claro.
CampoQué es
nameNombre visible del proveedor (obligatorio).
base_urlURL http(s) del API upstream, p. ej. https://api.proveedor.com/v1.
api_keyCredencial upstream. Solo en el store; enmascarada en toda respuesta.
api_formatopenai (default, compatible OpenAI) o anthropic (API nativa /v1/messages).
enabledUn proveedor deshabilitado no sirve tráfico.
priorityEntero (menor = primero). El primer proveedor habilitado y completo es el transporte por defecto cuando no hay entorno THEUS_UPSTREAM_*.
notesNotas 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, la gestión de miembros…), sobre qué (target) y cuándo, con el detalle del cambio. El detalle nunca contiene secretos completos: las keys van enmascaradas también aquí.

A prueba de manipulación (hash-chain). Cada entrada queda encadenada al hash de la anterior: alterar o borrar un evento pasado rompe la cadena, y eso se detecta. GET /api/admin/audit/verify recorre la bitácora, recomputa cada hash y confirma el encadenado, devolviendo {ok, verified_count, break_at_seq, …}. Es la evidencia de integridad que pide una due-diligence o una auditoría de seguridad: no solo hay registro, sino que se puede probar que no se tocó.

Métricas y vistas de solo lectura

EndpointQué devuelve
GET /api/admin/overviewPanel 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/usersUsuarios con plan efectivo, número de keys y uso del periodo.
GET /api/admin/modelsEl catálogo completo en formato de API.
GET /api/admin/providersVista heredada: el upstream por entorno + los proveedores gestionados, con estado.

Referencia de endpoints de gestión

Método y rutaAcción
POST /api/admin/subscriptions/planAjusta o retira el plan administrativo de un cliente, sin sobrescribir Stripe.
POST /api/admin/wallet/creditAbona créditos con motivo, nota, actor e idempotencia auditados.
POST /api/admin/atlas/overrideConcede o retira la cortesía del plan Atlas. Caduca siempre (dias o expires_at, máximo 366).
POST /api/admin/enterprise/reconciliarEmpuja el catálogo del release a las organizaciones Atlas desfasadas, en segundo plano (202; 409 si ya hay una pasada en curso).
GET /api/admin/enterprise/reconciliarAvance y veredicto por organización de la última pasada.
GET /api/admin/model-providersLista proveedores (keys enmascaradas) + estado del fallback env.
POST /api/admin/model-providersCrea 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}/testPrueba de conexión real con la key guardada.
GET /api/admin/model-routesRutas actuales + catálogo + mapa env de referencia.
PUT /api/admin/model-routesReemplaza el mapa completo modelo → proveedor.
GET /api/admin/titan-configConfig del cerebro: guardada, efectiva y del entorno.
PATCH /api/admin/titan-configActualiza enabled, provider_id, model, max_subtasks.
GET /api/admin/auditBitá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.

Ante un store corrupto el gateway aborta en vez de sobrescribir (fail-closed): restaura el export JSON o un backup .bak y reinicia el servicio. Nunca se pierde estado en silencio.
    ↑↓ navegar · ↵ abrir · esc cerrarDocumentación de Theus