Saltar al contenido
AI Workforce OS
ES EN
Crear cuenta

Referencia de configuración

Toda la configuración de AI Workforce OS se lee de variables de entorno. Esta página lista las del backend (Go), el runtime de agentes (Python) y el frontend (Next.js), con el valor por defecto que fija el código. Es para quien instala u opera una instancia propia.

12 min de lectura

En esta página
  1. Cómo se carga la configuración
  2. Servidor y base de datos
  3. Autenticación, CORS y proxy
  4. Presupuesto, costo y límites de ejecución
  5. Recompensas y monedas
  6. Runtime: proveedores de modelo y claves
  7. Conexiones, sandbox, almacenamiento y push
  8. Límites de tasa
  9. Frontend: argumentos de build
  10. Verificación de correo y cuentas de prueba
Volver arriba

Cómo se carga la configuración#

El backend lee el entorno al arrancar y valida la combinación antes de abrir el puerto: si algo es incoherente, el proceso termina con un error que nombra la variable. El runtime lee sus variables cuando las usa. El frontend no lee nada en ejecución: sus valores quedan fijados al compilar.

  • Booleanos: true, false, 1, 0 y el resto de valores que acepta strconv.ParseBool. Un valor inválido aborta el arranque.
  • Enteros y duraciones: un valor ausente, no numérico o menor o igual que cero se sustituye por el valor por defecto. Las duraciones usan la sintaxis de Go (30s, 5m, 1h).
  • Importes en USD: 0 es válido y desactiva el tope correspondiente; un valor negativo o no numérico deja el valor por defecto. La excepción es BUDGET_USD, que necesita un valor mayor que cero.
  • Listas: valores separados por comas; se ignoran los espacios.

Nota

En las tablas, «Condicional» significa que la variable solo es obligatoria en combinación con otra (por ejemplo JWT_SECRET con AUTH_ENABLED=true). «No» significa que hay un valor por defecto o que la función queda desactivada.

Servidor y base de datos#

VariablePor defectoObligatoriaSignificado
PORT8080NoPuerto HTTP del backend.
DATABASE_URLvacíoCondicionalURL de Postgres. Sin ella el backend guarda todo en memoria (solo demos). Obligatoria con AUTH_ENABLED=true.
MIGRATE_DATABASE_URLvacíoNoConexión de propietario (DDL) usada solo para aplicar migraciones. Vacía: se usa DATABASE_URL.
DB_APP_ROLEapp_userNoRol sin privilegios de propietario y sin BYPASSRLS al que cambia cada conexión (SET ROLE); es la base del aislamiento por RLS. Vacío desactiva el cambio.
REDIS_URLvacíoNoURL de Redis, con la contraseña dentro de la URL. Vacía: eventos, bloqueos y límites de tasa en memoria del proceso.
RUNTIME_URLhttp://localhost:8000NoURL interna del runtime de agentes.
RUNTIME_TOKENvacíoNoSecreto compartido entre backend y runtime. Recomendado en producción: el backend avisa en el log si está vacío.
READ_HEADER_TIMEOUT10sNoTiempo máximo para leer las cabeceras de una petición.
READ_TIMEOUT30sNoTiempo máximo para leer una petición completa.
WRITE_TIMEOUT60sNoTiempo máximo por petición REST. No se aplica al WebSocket.
IDLE_TIMEOUT120sNoTiempo de inactividad de las conexiones keep-alive.
MAX_BODY_BYTES1048576NoTamaño máximo del cuerpo de una petición (1 MiB).
APP_ENVvacíoNoCon el valor production, el backend avisa si la KEK de la bóveda procede del entorno.
TRACE_RETENTION_DAYS30NoDías que se conservan las trazas de razonamiento de los agentes; se purgan cada hora.

Consejo

Define RUNTIME_TOKEN con el mismo valor en el backend y en el runtime. Con él definido, el runtime exige Authorization: Bearer <token> en todas las rutas salvo /healthz.

Autenticación, CORS y proxy#

Con AUTH_ENABLED=false el backend funciona en modo demo: una organización fija y sin inicio de sesión. Con AUTH_ENABLED=true activa cuentas, JWT, RBAC y aislamiento por organización, y el org_id sale del token.

Con la autenticación activa, el arranque falla si JWT_SECRET tiene menos de 32 bytes, si falta DATABASE_URL o si ALLOWED_ORIGINS contiene *.

VariablePor defectoObligatoriaSignificado
AUTH_ENABLEDfalseNoActiva cuentas, JWT, RBAC y multi-tenencia. El compose de producción lo fija a true.
JWT_SECRETvacíoCondicionalClave de firma de los tokens de acceso; mínimo 32 bytes; obligatoria con AUTH_ENABLED=true. Rotarla invalida todas las sesiones.
ALLOWED_ORIGINSvacíoCondicionalOrígenes permitidos para CORS y WebSocket, separados por comas y sin barra final. Vacía sin autenticación equivale a *; vacía con autenticación, solo el mismo origen.
AUTH_COOKIE_SECUREtrueNoAtributo Secure de la cookie del refresh token. Solo se desactiva en desarrollo local con HTTP plano.
AUTH_COOKIE_NAMEwfai_refreshNoNombre de la cookie del refresh token. Cámbialo si varias instalaciones comparten host.
TRUSTED_PROXIESvacíoNoCIDR o IP de los proxies cuyo X-Forwarded-For se respeta (lo usan los límites de tasa). Un valor inválido aborta el arranque.
ENABLE_DEMO_RESETfalseNoRegistra POST /api/v1/demo/reset, que borra los datos de ejecución. Déjala en false en producción.
KILL_SWITCHvacíoNofreeze o lockdown: anulación global que ninguna llamada de API puede levantar. Se relee con SIGHUP.
UI_BASE_URLvacíoNoURL pública del frontend: destino del navegador tras el callback OAuth y base de los enlaces de verificación de correo.

Atención

Con AUTH_ENABLED=false no hay inicio de sesión: cualquiera que alcance la URL controla la organización demo. No expongas ese modo a internet con datos o claves reales.

Presupuesto, costo y límites de ejecución#

Estas variables controlan el gasto y la concurrencia del orquestador. Las ventanas de contexto y los controles de calidad tienen más ajustes internos con valores por defecto razonables; esta tabla recoge los que conviene conocer.

VariablePor defectoObligatoriaSignificado
BUDGET_USD50NoTope de gasto en USD. El compose de producción usa 25 si no la defines.
REQUEST_BUDGET_CAP_USD0NoTope duro de gasto por solicitud. 0 lo desactiva.
AGENT_BUDGET_USD0NoTope mensual de gasto por agente. 0 lo desactiva.
COST_CONFIRM_THRESHOLD_USD1.0NoCosto estimado a partir del cual se pide confirmación antes de ejecutar.
BUDGET_PAUSE_TIMEOUT30mNoTiempo que una solicitud pausada por un tope espera a que alguien decida.
PRICE_IN_PER_M / PRICE_OUT_PER_Mtabla de precios internaNoFuerzan la tarifa en USD por millón de tokens de entrada y salida. Hay que definir las dos; las leen el backend y el runtime.
APPROVAL_ACTIONSsend_proposal,send_contractNoAcciones que siempre exigen aprobación humana.
APPROVAL_TIMEOUT30mNoTiempo de espera de una aprobación dentro de una solicitud.
STANDING_APPROVAL_DAYS30NoVigencia de un permiso permanente por proyecto (máximo 90). También termina con el proyecto.
MAX_PARALLEL / MAX_PARALLEL_PER_ORG4 / 8NoTareas simultáneas en total y llamadas al runtime en vuelo por organización; el resto espera en cola.
MAX_PLAN_DEPTH30NoProfundidad máxima de un plan.
TASK_TIMEOUT120sNoTiempo máximo de una tarea.
TASK_RETRIES / TASK_MAX_ATTEMPTS3 / 2NoReintentos y número máximo de intentos por tarea.
TASK_RETRY_BACKOFF2sNoEspera entre reintentos de una tarea.
PROJECT_MAX_NODES / PROJECT_MAX_CHILDREN_PER_GROUP / PROJECT_MAX_ACTIVE20000 / 200 / 20NoTamaño máximo de un proyecto y número de proyectos activos por organización.
PLANNER_MAX_PHASES / PLANNER_MAX_TASKS_PER_PHASE / PLANNER_CONCURRENCY12 / 40 / 3NoCotas del planificador de proyectos.
DEP_CONTEXT_TOKEN_BUDGET8000NoTokens de contexto que una tarea recibe de las tareas de las que depende.
EMAIL_HOLD_SECONDS60NoVentana para cancelar un correo antes de que salga. Mínimo 60 y máximo 300: los valores fuera de rango se ajustan.

Recompensas y monedas#

El sistema de monedas premia el trabajo completado. REWARDS_RULES acepta un JSON que se aplica encima de las reglas por defecto, así que basta con incluir los campos que quieras cambiar.

Si el JSON tiene un valor inválido, el backend lo registra en el log y usa las reglas por defecto completas: nunca aplica una economía a medias.

Reglas por defecto de REWARDS_RULESJSON
{
  "enabled": true,
  "base": { "S": 5, "M": 10, "L": 20, "XL": 40 },
  "default_complexity": "M",
  "first_try_bonus_pct": 50,
  "rework_pct": 50,
  "project_base": 20,
  "project_per_task": 2,
  "project_max": 100,
  "min_project_tasks": 2
}
VariablePor defectoObligatoriaSignificado
REWARDS_ENABLEDtrueNofalse, 0 u off desactivan por completo la obtención de monedas.
REWARDS_RULESvacíoNoJSON con reglas: enabled, base (S, M, L, XL), default_complexity, first_try_bonus_pct, rework_pct, project_base, project_per_task, project_max, min_project_tasks.
REWARDS_WELCOME_COINS1000NoMonedas de bienvenida que recibe cada organización una sola vez, la primera vez que abre la tienda o la oficina. 0 lo desactiva.

Runtime: proveedores de modelo y claves#

El runtime admite cinco proveedores: deepseek, anthropic, openai, kimi y custom (un endpoint compatible con OpenAI, por ejemplo vLLM u Ollama). Un proveedor cuenta como configurado cuando su clave (y, para custom, su URL base) está en el entorno. Sin ningún proveedor configurado, o con SIMULATION=true, el runtime usa el motor simulado: respuestas guionadas, sin claves y sin costo.

Ante un error transitorio (timeout, límite de tasa, 5xx) reintenta en el mismo proveedor y después pasa al siguiente permitido. ALLOWED_PROVIDERS es el techo del operador: ningún dato llega a un proveedor excluido, ni siquiera como respaldo. Cada organización puede restringirlo más desde sus ajustes, nunca ampliarlo, y puede guardar su propia clave de proveedor, que gana a la del entorno.

VariablePor defectoObligatoriaSignificado
SIMULATIONfalseNotrue fuerza el motor simulado aunque haya claves.
DEEPSEEK_API_KEY / DEEPSEEK_MODELvacío / deepseek/deepseek-chatCondicionalClave y modelo de DeepSeek, el proveedor por defecto de la plataforma.
ANTHROPIC_API_KEY / ANTHROPIC_MODELvacío / anthropic/claude-sonnet-5-5CondicionalClave y modelo de Anthropic.
OPENAI_API_KEY / OPENAI_MODEL / OPENAI_BASE_URLvacío / openai/gpt-4.1 / vacíoCondicionalClave, modelo y URL base opcional de OpenAI.
KIMI_API_KEY / KIMI_MODEL / KIMI_BASE_URLvacío / openai/kimi-k2-0905-preview / https://api.moonshot.ai/v1CondicionalClave, modelo y URL base de Kimi (Moonshot).
CUSTOM_LLM_BASE_URLvacíoCondicionalURL base de un endpoint compatible con OpenAI. Activa el proveedor custom.
CUSTOM_LLM_API_KEY / CUSTOM_LLM_MODELvacíoNoClave opcional (muchos servidores locales no la piden) y nombre del modelo del endpoint custom.
CUSTOM_PRICE_IN_PER_M / CUSTOM_PRICE_OUT_PER_M3 / 15NoUSD por millón de tokens del endpoint custom. Puede ser 0 para un modelo local.
MODELvacíoNoVariable heredada: proveedor/modelo aplica a ese proveedor; un nombre sin prefijo aplica al primario.
MODEL_PROVIDER_ORDERdeepseek,anthropic,openai,kimi,customNoOrden global de respaldo. MODEL_PROVIDER_ORDER_<ROL> lo cambia para un rol de agente o un tipo de llamada (por ejemplo MODEL_PROVIDER_ORDER_PLAN).
ALLOWED_PROVIDERSvacíoNoTecho del operador: solo estos proveedores pueden recibir datos. Vacío significa todos los configurados. Defínela igual en el backend y en el runtime.
PROVIDER_RETRIES1NoReintentos en el mismo proveedor antes de pasar al siguiente.
PROVIDER_RETRY_BACKOFF_S1.0NoEspera entre reintentos, en segundos.
PROVIDER_TIMEOUT_S120NoTimeout por llamada al proveedor, en segundos.
SYNTH_PROMPT_TOKEN_BUDGET24000NoPresupuesto de tokens del prompt de síntesis en el runtime.

Atención

Las claves de proveedor son secretos que cuestan dinero si se filtran. Pásalas por el entorno del servicio, nunca en una imagen ni en el repositorio.

Conexiones, sandbox, almacenamiento y push#

Sin CONNECTIONS_KEK no se puede guardar ninguna credencial real: la bóveda falla cerrada y solo funcionan las conexiones simuladas. La KEK es base64 de 32 bytes aleatorios; guárdala aparte de la base de datos, porque sin ella los secretos cifrados son irrecuperables.

El sandbox de código es opcional y necesita el servicio sandbox-runner, que recibe acceso al socket de Docker. Lee antes la página del modelo de seguridad.

Generar una KEKBash
openssl rand -base64 32
VariablePor defectoObligatoriaSignificado
CONNECTIONS_KEKvacíoNoClave de cifrado de claves de la bóveda (base64 de 32 bytes). La necesitan las conexiones reales y las claves de modelo propias de cada organización.
CONNECTIONS_KEK_PREVIOUSvacíoNoKEK anterior, solo mientras dura una rotación.
CUSTOM_API_ALLOW_PRIVATEfalseNoSi es true, las fuentes de API genéricas (custom_api) pueden llegar a direcciones privadas, como un ERP en tu red local. Solo para instalaciones propias en una red de confianza; nunca cambia la regla de solo GET.
GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRETvacíoNoTu propia aplicación OAuth de Google para las conexiones.
LINKEDIN_OAUTH_CLIENT_ID / LINKEDIN_OAUTH_CLIENT_SECRETvacíoNoTu propia aplicación OAuth de LinkedIn.
OAUTH_REDIRECT_URLhttp://localhost:8080/api/v1/connections/oauth/callbackNoURL pública del callback OAuth; debe coincidir con la registrada en el proveedor.
GITHUB_API_URLvacío (api.github.com)NoBase de la API de GitHub, por ejemplo para GitHub Enterprise.
SANDBOX_URL / SANDBOX_TOKENvacíoNoDirección y token del sandbox-runner. Sin las dos, los agentes no pueden ejecutar código.
SANDBOX_IMAGE / SANDBOX_RUNTIME / SANDBOX_SECCOMP_PROFILEvacíoNoLas lee el sandbox-runner: imagen de ejecución, runtime de contenedor (por ejemplo runsc de gVisor) y perfil seccomp.
S3_ENDPOINT / S3_BUCKET / S3_REGION / S3_PREFIX / S3_USE_PATH_STYLEvacío (S3_USE_PATH_STYLE: true)NoAlmacenamiento compatible con S3 para los archivos del Drive. Sin endpoint y bucket se usa Postgres, o memoria si no hay base de datos.
S3_ACCESS_KEY / S3_SECRET_KEYvacíoNoCredenciales S3.
DRIVE_MAX_FILE_MB / DRIVE_QUOTA_MB25 / 5120NoTamaño máximo por archivo y cuota por organización, en MB.
VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECTvacíoNoLas tres juntas activan las notificaciones Web Push; sin ellas quedan desactivadas.
PUSH_ALLOWED_HOSTSvacíoNoHosts de servicios push que se añaden a la lista permitida por defecto.

Límites de tasa#

Los límites de tasa están integrados en el backend y no tienen variables de ajuste: por ejemplo, 10 intentos de inicio de sesión cada 15 minutos y 120 comandos por minuto. Los de autenticación se guardan en Redis si hay REDIS_URL, y en memoria del proceso si no.

Lo que sí se configura es TRUSTED_PROXIES. Solo la cabecera X-Forwarded-For de esos proxies sirve para identificar al cliente. Detrás de Caddy, indica la red del proxy: sin ella, todos los clientes comparten la IP del proxy y el mismo contador.

Frontend: argumentos de build#

El frontend se compila con salida standalone. Las variables NEXT_PUBLIC_* se incorporan al compilar como argumentos del Dockerfile (ARG); cambiarlas exige reconstruir la imagen.

Dejarlas vacías da el comportamiento recomendado para un solo dominio: la API en la ruta relativa /api/v1 y el WebSocket derivado de window.location.

Build con dominios separadosBash
docker build \
  --build-arg NEXT_PUBLIC_API_URL=https://app.example.com/api/v1 \
  --build-arg NEXT_PUBLIC_WS_URL=wss://app.example.com/ws \
  -t aiworkforce-frontend ./frontend
Argumento de buildPor defectoObligatoriaSignificado
NEXT_PUBLIC_API_URLvacíoNoURL base absoluta de la API, por ejemplo https://app.example.com/api/v1. Vacía: ruta relativa.
NEXT_PUBLIC_WS_URLvacíoNoURL absoluta del WebSocket, por ejemplo wss://app.example.com/ws. Vacía: se deriva de window.location.
NEXT_PUBLIC_MOCKvacíoNoCon el valor true, el frontend funciona con datos simulados, sin backend.

Verificación de correo y cuentas de prueba#

Dos funciones opcionales de acceso, las dos requieren AUTH_ENABLED=true. La verificación de correo exige un SMTP que funcione: con EMAIL_VERIFICATION=true y sin SMTP válido el backend se niega a arrancar, de modo que un servidor a medio configurar no deja a nadie fuera.

Las cuentas de prueba permiten usar la app sin registrarse; cada una tiene su propia organización y deja de funcionar sola.

VariablePor defectoSignificado
EMAIL_VERIFICATIONfalseLas cuentas nuevas deben abrir un enlace de un solo uso enviado a su correo antes de entrar. Requiere AUTH_ENABLED, UI_BASE_URL y SMTP_* (o EMAIL_DEV_LOG).
EMAIL_DEV_LOGfalseSolo desarrollo: los enlaces de verificación se escriben en el log en lugar de enviarse.
SMTP_HOSTvacíoServidor SMTP. Obligatorio con EMAIL_VERIFICATION, salvo que EMAIL_DEV_LOG esté activo.
SMTP_PORT465465 usa TLS implícito; 587 usa STARTTLS.
SMTP_TLStls con el puerto 465; starttls con otrotls, starttls o none (none solo para un relay local).
SMTP_USER / SMTP_PASSvacíoCredenciales del servidor SMTP; define las dos o ninguna.
SMTP_FROMvacíoRemitente, por ejemplo AI Workforce OS <no-reply@example.com>. Obligatorio con verificación por SMTP.
TRIAL_ENABLEDfalseActiva POST /api/v1/auth/trial: cuentas desechables con su propia organización.
TRIAL_TTL_HOURS24Horas que funciona una cuenta de prueba.
TRIAL_PER_IP_PER_DAY3Cuentas de prueba que una misma dirección IP puede crear al día.
TRIAL_GLOBAL_PER_DAY300Cuentas de prueba creadas al día entre todas las direcciones.
TRIAL_EMAIL_DOMAINprueba.invalidDominio de las direcciones generadas para las pruebas (sin buzón detrás).