Work: espacios de trabajo aislados
Work es la superficie nativa de agente de programación de Libre WebUI. Cada tarea
combina una conversación duradera, una ruta explícita de proveedor y un sistema de
archivos dedicado en /workspace. El modelo puede inspeccionar y editar archivos,
ejecutar comandos en un contenedor Docker o Pod de Kubernetes por tarea e iniciar
una vista previa en el navegador.
Work está implementado directamente en Libre WebUI. No necesita Libre Claw ni otro daemon de agentes.
Cada API de Work exige una cuenta autenticada con acceso. De forma predeterminada solo los administradores lo tienen; uno puede abrirlo a todos los usuarios activos desde la pestaña Gestión de usuarios en Configuración (los espacios vinculados a carpetas del host siguen siendo solo administrativos porque montan rutas del servidor). Work permite deliberadamente que un modelo ejecute comandos shell arbitrarios dentro de un entorno aislado. Las tareas tienen salida de red salvo que la política de ejecución nombrada seleccionada la desactive. Trata a toda persona con acceso como operador de ejecución de confianza, no solo como usuario de chat.
Novedades de la versión
Esta versión presenta Work como un flujo de tareas completo:
- Acciones Work y Chat separadas en la barra lateral, con el modo activo claramente seleccionado.
- Tareas de Work en la barra normal, no en un segundo carril. Las posiciones se mantienen mientras se actualizan las ejecuciones y la tarea seleccionada se puede eliminar directamente.
- Identidad de entorno dedicada y volumen Docker persistente o PVC de Kubernetes para cada tarea. Los entornos pueden detenerse o recrearse sin borrar archivos.
- Conversación, estado de ejecución, actividad de herramientas, selección del modelo y propiedad duraderos en la base de Libre WebUI.
- Flujo de ejecución autenticado y en directo para texto del asistente, razonamiento expuesto por el proveedor, herramientas y resultados, uso, habilidades del worker y cambios de estado.
- Habilidades del worker propiedad del servidor que enseñan al modelo a inspeccionar, editar, verificar y previsualizar con eficacia sin escribir archivos de control.
- Modelos Ollama locales con herramientas, modelos Ollama Cloud y plugins de chat o completado configurados.
- División adaptable entre Conversación y Espacio de trabajo, redimensionable con ratón y teclado en escritorio, y selector de superficie en pantallas pequeñas.
- Vistas integradas de Archivos, Actividad, Git, Terminal, Vista previa y Pantalla; Pantalla es el escritorio Work Computer observable y enseñable.
- Resaltado de sintaxis claro y oscuro, formato en el navegador, detección de conflictos y borradores temporales.
- Aviso descartable por usuario cuando se selecciona un proveedor remoto.
- Traducción completa de Work en los 25 idiomas admitidos, incluido el diseño árabe nativo de derecha a izquierda, mientras código, rutas, ID y salidas permanecen de izquierda a derecha.
La unidad persistente es el espacio de la tarea, no un contenedor continuamente activo. Libre WebUI inicia, detiene y puede recrear el contenedor conservando su volumen con nombre.
Arquitectura
Libre WebUI, no el modelo ni el navegador, elige nombres, imagen, montaje, usuario, límites, modo de red y puerto. El modelo solo recibe estas herramientas:
list_filesread_filewrite_filedelete_filemove_filesearch_filesrun_commandstart_previewstop_preview
delete_file y move_file protegen las rutas como las demás: se niegan a salir del
espacio, nunca atraviesan enlaces simbólicos, exigen una opción recursiva para borrar
directorios y nunca sobrescriben un destino. Como pasan por el asistente de archivos
y no por shell, funcionan mientras hay una vista previa y run_command está bloqueado.
Las solicitudes al modelo proceden del backend. No se originan en el contenedor ni dependen de su política de red.
Requisitos
Work necesita un backend de aislamiento configurado:
- El predeterminado requiere Docker instalado, un daemon accesible y permiso para
que el backend invoque
docker(o el ejecutable definido porWORK_DOCKER_COMMAND). - Kubernetes requiere credenciales de API, Role, RoleBinding, espacio de nombres y
NetworkPolicies creados por Helm cuando
work.enabled=true.
Todos los backends también necesitan:
- Un modelo con herramientas expuesto mediante:
- un servicio Ollama sano, incluidos modelos de Ollama Cloud; o
- un plugin activo de completado/chat con el modelo exacto y credenciales del administrador actual.
- Almacenamiento suficiente para imagen, proyectos y dependencias locales.
- Una cuenta autenticada con acceso. Work es administrativo por defecto; un administrador puede abrirlo a todos los usuarios activos.
Libre WebUI comprueba las capacidades anunciadas por Ollama antes de crear una
ejecución y rechaza un modelo que no anuncie tools. Los modelos de plugins deben
admitir el protocolo de herramientas de su proveedor. Si el modelo remoto las
rechaza, la ejecución falla; Work no cambia silenciosamente a otro.
Iniciar localmente
Para la configuración compatible más sencilla, ejecuta Libre WebUI y Docker en el mismo equipo que el navegador:
docker info
npx libre-webui@latest
Abre http://localhost:8080, inicia sesión como administrador, selecciona Work,
elige un modelo compatible y describe el proyecto o cambio.
Si Docker falta, está detenido o no es accesible, Work muestra Entorno no disponible con la causa y desactiva el redactor. Libre WebUI nunca ejecuta los comandos directamente en el host como alternativa.
La imagen se inspecciona en el primer uso y se descarga si falta, por lo que la primera operación puede tardar más.
Usar la interfaz de Work
Crear y volver a visitar tareas
Selecciona Work junto a Chat. Introduce una instrucción, elige un modelo y pulsa Ejecutar. El primer mensaje crea la tarea, su primera ejecución, la ruta de proveedor y el espacio persistente.
Cada tarea permanece en la barra lateral. Al abrirla se restauran conversación reciente, Archivos, proveedor/modelo y espacio. Los mensajes anteriores se cargan por páginas. Puedes cambiar el nombre y eliminarla permanentemente desde el menú o la barra.
Solo una ejecución puede estar activa. Una instrucción posterior crea otra sobre la misma conversación y sistema de archivos.
El editor admite dictado: un botón de micrófono utiliza la API de voz del navegador cuando está disponible o, como alternativa, un modelo de proveedor de voz a texto configurado, y añade la transcripción a lo que ya se había escrito. En la conversación, los archivos que una ejecución crea o mueve aparecen como fichas en las actividades de herramienta que los produjeron. Al pulsar una, se abre el archivo en el editor Archivos del espacio de trabajo (y se cambia a la superficie del espacio en pantallas estrechas). Las fichas solo proceden de herramientas que modifican, por lo que una ejecución que lea veinte archivos pero escriba uno muestra exactamente ese artefacto.
Contratar a un agente
La vista inicial ofrece Contratar como agente cuando tienes personas: elige una y la tarea creada se convierte en un agente persistente con nombre en lugar de una tarea puntual. El agente conserva su persona entre ejecuciones. El nombre y el prompt de sistema de la persona se anteponen al prompt de sistema de Work (el contrato de la zona aislada siempre tiene prioridad), y la barra lateral fija los agentes en su propio grupo Agentes por encima de las tareas ad hoc. Cada uno muestra el avatar de la persona, un indicador de actividad y una línea de estado. Cuando la barra lateral está compacta, solo quedan en el raíl esos avatares de agentes fijados; las tareas de Work puntuales vuelven al expandir la barra lateral.
La línea de estado tiene dos niveles. En los agentes contratados, una solicitud
económica al modelo y sin herramientas pide al final de la ejecución un estado de
unas 8 palabras ("Inbox at zero. 2 replies ready."). La respuesta se limita a una
única línea de 90 caracteres; si falla o agota el tiempo, se usa el nivel
determinista: la primera línea del mensaje final del asistente. Las tareas ad hoc y
las ejecuciones fallidas solo usan el nivel determinista, y
WORK_STATUS_BLURB_MODEL=0 desactiva por completo la solicitud al modelo. Los
agentes también tienen un indicador de elementos no leídos: abrir la tarea avanza
un marcador visto por tarea (monótono y sincronizado entre dispositivos), y la barra
muestra un punto cuando una ejecución alcanza un estado final después del marcador.
Los agentes también informan de su actividad mediante las
notificaciones, tanto dentro de la aplicación como, si está
activado, mediante web push: work-run-finished cuando termina una ejecución,
work-run-attention cuando se detiene para pedir entrada o falla, y work-takeover
en el momento en que solicita que una persona tome el control de la pantalla (el
aviso en pantalla solo es visible con la pestaña Pantalla abierta, por lo que la
notificación push te alcanza en otros lugares). Cada notificación enlaza directamente
al agente.
Puedes contratar con una persona propia o compartida contigo; la vista compartida
nunca expone los recuerdos de la persona de su propietario. Si la persona se elimina
después, el agente continúa sin ella y se registra una advertencia. La API acepta
personaId e isAgent al crear una tarea; una tarea creada con persona se convierte
automáticamente en agente.
La pestaña Agente
El panel del espacio de un agente se abre con una primera pestaña adicional, Agente, que es su propia página:
- Identidad: avatar y nombre de la persona, indicador de actividad y última línea de estado.
- Pantalla: cuando la política concede Work Computer, una miniatura compacta y en directo de solo lectura de la pantalla. Es un visor real (cuenta para el límite de visores por tarea); al pulsarlo se abre la pestaña Pantalla completa, donde están el control humano, la enseñanza y el audio.
- Rutinas: automatizaciones vinculadas a esta tarea. Cada
activación se ejecuta en el espacio y conversación propios del agente, con su
modelo y entorno, no en una tarea nueva. Así, una rutina de resumen matinal se
acumula en un único lugar. Las filas describen el horario e incluyen un control
para pausar o reanudar; el formulario + Rutina ya está vinculado al agente. Una
ejecución que se activa mientras el agente está ocupado falla honestamente como
work-task-busyen lugar de ponerse en cola. - Revisión automática: el interruptor de aprobaciones del agente y las reglas de «permitir siempre» que ha acumulado; al quitar una regla se vuelve a cerrar su alcance. Si la política de la tarea obliga a revisar, el interruptor queda fijo.
- Habilidades enseñadas: procedimientos demostrados en modo de enseñanza, con un interruptor para activar o desactivar cada habilidad.
Herramientas conectadas (servidores MCP y OpenAPI)
Los agentes de Work pueden llamar a los mismos servidores de herramientas
configurados para el chat: MCP u OpenAPI, registrados por un administrador en Ajustes →
Herramientas. Las herramientas aparecen ante el agente con su nombre con espacio de
nombres (server__tool) y las llamadas salen del backend de Libre WebUI por la pasarela
de herramientas reforzada (salida protegida contra SSRF, credenciales por usuario,
límites de tamaño y de tiempo), nunca desde dentro del entorno aislado.
La oferta es honesta sobre lo que una ejecución autónoma puede usar de verdad:
- Una tarea sin red no ofrece ninguna: pase o no la salida por el backend, una tarea
sin acceso a la red sigue estando desconectada, por la misma razón que
web_search. - Un servidor que exige una credencial personal que el usuario no ha guardado se descarta al ofrecerlo, porque una ejecución autónoma no puede detenerse a pedirla. Añade la credencial en Ajustes → Herramientas y la siguiente ejecución ya ofrece ese servidor.
- El modo de acceso a herramientas (solo administradores o todos los usuarios) y la visibilidad por servidor se aplican igual que en el chat, y los servidores vinculados a una persona limitan cuáles ve el agente contratado con ella.
- Cuando las aprobaciones están activas, las herramientas conectadas que el servidor clasifica como con efectos esperan tu decisión como cualquier acción sujeta a control; las de solo lectura se ejecutan sin preguntar.
Delegación entre agentes (menciones con @)
Los agentes contratados pueden pasarse trabajo. Escribe @ en el redactor de Work para
mencionar a otro de tus agentes: el agente actual ve en sus instrucciones la lista de sus
compañeros, con nombres y líneas de estado, y delega las peticiones que correspondan con
la herramienta message_agent. La delegación coordina mediante mensajes y
deliberadamente no mediante ordenadores compartidos: cada agente conserva su espacio y su
entorno aislados, y el destino no ve la conversación de origen, así que la petición debe
llevar su propio contexto.
La delegación es asíncrona. La herramienta responde de inmediato, el agente de destino se
ejecuta en su propia tarea (su conversación muestra la petición con la etiqueta
Delegado por quien la envía) y, cuando termina —completado, con necesidad de entrada,
fallido o cancelado—, su respuesta final se entrega en la conversación del agente que
delegó como un mensaje con la etiqueta Informe de ese agente. Si quien delegó sigue en
marcha, el informe llega a su modelo en la ronda siguiente; si está inactivo, el informe
simplemente espera en la conversación, porque un informe nunca inicia una ejecución por su
cuenta: así dos agentes no pueden entrar en un ida y vuelta infinito. Una ejecución
delegada no puede delegar a su vez, un destino ocupado hace fallar honestamente el intento
en lugar de ponerlo en cola y, con las aprobaciones activas, message_agent se detiene
para revisión como cualquier otra acción con efectos (la regla de «permitir siempre» queda
limitada a ese único agente de destino).
Aprobación de acciones (Revisión automática)
Las acciones con efectos pueden detenerse a esperar tu decisión antes de ejecutarse.
Cuando las aprobaciones están activas para una tarea —porque su política de Work marca
Exigir aprobación para acciones con efectos o porque el interruptor Revisión
automática del agente está encendido—, la ejecución se detiene antes de ejecutar
run_command, computer_act, delete_file, move_file o message_agent y muestra una
tarjeta de decisión en la conversación: Permitir una vez, Permitir siempre o
Denegar.
- Permitir una vez ejecuta exactamente esa llamada y vuelve a preguntar la próxima vez.
- Permitir siempre ejecuta la llamada y guarda una regla en la tarea: para toda la
herramienta en las acciones de archivos y de ordenador, limitada al programa del comando
(su primera palabra) en
run_command—aprobarnpm run buildpreaprueba futuros comandosnpm, no el intérprete entero— y limitada al único agente de destino enmessage_agent. Las reglas se enumeran en la sección Revisión automática de la pestaña Agente y se pueden quitar allí. - Denegar rechaza la llamada. Al modelo se le indica que el usuario denegó la acción y que no debe reintentarla tal cual; la ejecución continúa con esa respuesta.
Una aprobación pendiente también genera una notificación (en la aplicación y, si está activada, por web push), porque la ejecución puede llevar minutos trabajando sin supervisión cuando llega a ese control. Si nadie decide en cinco minutos, la solicitud caduca, la acción no se ejecuta y la ejecución termina en Necesita entrada con un traspaso normal en lugar de agotar su presupuesto.
Las aprobaciones controlan acciones, no visibilidad: write_file y las herramientas de
solo lectura quedan fuera del control, y cada decisión llega al registro de auditoría de
seguridad.
Comprender el estado
La interfaz asigna estados duraderos a un conjunto más sencillo:
| Estado de interfaz | Estado del backend | Color |
|---|---|---|
| Inactivo | idle | rgb(255, 255, 255) |
| Pensando | preparing o running | rgb(48, 121, 255) |
| Completado | completed | rgb(76, 212, 117) |
| Necesita entrada | needs_input o cancelled | rgb(255, 204, 0) |
| Error | failed | rgb(255, 61, 129) |
Detener una ejecución la cambia a Necesita entrada y conserva archivos. Agotar el presupuesto de rondas o herramientas también termina así tras la entrega final sin herramientas, por lo que el trabajo incompleto nunca se llama Completado.
Una ejecución activa no bloquea la conversación: un mensaje enviado mientras trabaja se incorpora de inmediato y llega al modelo en la ronda siguiente, para que puedas orientar, corregir o añadir contexto sin detenerlo. El botón de parada sigue junto a enviar.
Redimensionar el espacio
En el punto xl, Conversación y Espacio comparten una división arrastrable:
- El ancho predeterminado de la conversación es 45%.
- El intervalo preferido es 30%–70%, sujeto a anchos mínimos.
- La proporción guardada pertenece al usuario en ese navegador.
- Las flechas mueven el separador 2%; Mayús, 10%.
- Inicio y Fin eligen mínimo y máximo.
- Intro o doble clic restablecen la división.
Los controles siguen la dirección activa. En árabe, Conversación queda a la derecha y Espacio a la izquierda, y el redimensionamiento sigue la dirección visual.
En pantallas pequeñas, usa el control Conversación/Espacio de la cabecera.
Archivos
La pestaña explora hijos directos de /workspace, abre únicamente texto UTF-8
estrictamente válido y guarda en el volumen. Las secuencias inválidas se rechazan en
vez de sustituirse con pérdida.
El editor proporciona:
- resaltado claro y oscuro para lenguajes web, de sistemas, scripts, datos y marcado;
Cmd/Ctrl+Spara guardar;Shift+Alt+Fpara aplicar formato compatible;- detección optimista de conflictos, para que una vista antigua no sobrescriba un archivo cambiado;
- borradores por tarea y ruta en el almacenamiento de sesión; y
- avisos de navegación con cambios sin guardar.
El resaltado se pausa por encima de 8,000 caracteres o 400 líneas. El formato admite hasta 100,000 caracteres y 4,000 líneas para JavaScript/JSX, TypeScript/TSX, JSON, CSS/SCSS/Less, HTML, Markdown/MDX y YAML.
Cuando el modelo cambia un archivo abierto, Archivos muestra una vista roja/verde de
los cambios desde el inicio del turno, con tramos largos sin cambios plegados. Un
botón alterna diff y editor, y +added −removed resume el turno. La base es el último
contenido visto antes del turno, por lo que un archivo abierto después no tiene diff.
Los borradores son comodidad, no copia de seguridad. Se eliminan tras guardar o borrar la tarea y suelen desaparecer al terminar la sesión.
Actividad
Actividad muestra llamadas, resultados, operaciones de archivos, salida y errores. Los metadatos se expanden en la conversación. Las salidas se presentan de izquierda a derecha incluso dentro de una interfaz RTL.
Durante una ejecución, Libre WebUI abre un flujo autenticado de eventos enviados por el servidor y muestra el progreso. Puede transportar:
- un
snapshotinicial y cambiosrun_state; reasoning_deltasi el proveedor expone razonamiento;- texto
assistant_delta; - actividad
tool_callytool_result; - mediciones
usage; - avisos
skill_loadedpara orientación del worker; y - eventos terminales
errorodone.
La disponibilidad y detalle del razonamiento dependen del modelo y proveedor. Libre WebUI solo muestra lo que devuelve su API; no recupera cadenas de pensamiento ocultas y algunos modelos no ofrecen flujo. El texto y las herramientas siguen transmitiéndose cuando son compatibles independientemente.
La salida está acotada. Un resultado truncado no demuestra que no haya más; pide una inspección más estrecha o un comando más centrado.
Git
La pestaña Git ofrece operaciones locales sobre /workspace:
- inicializar un repositorio con rama
main; - inspeccionar estado porcelain, avance/retraso y hasta 20 commits recientes;
- inspeccionar un diff textual acotado;
- preparar hasta 200 rutas explícitas a la vez;
- confirmar cambios con el nombre y correo del administrador, o una dirección local sin respuesta si no hay correo;
- crear una rama local tras el primer commit; y
- cambiar a una rama local existente con el árbol limpio.
Es solo local. No hay clone, fetch, pull, push, gestión de remotos, comandos
arbitrarios, tokens, claves SSH ni pull requests. Esas operaciones necesitan un
intermediario de credenciales de confianza, preferiblemente una GitHub App o token
equivalente limitado a un repositorio y operación. No guardes credenciales duraderas
en /workspace, el entorno de la tarea ni su configuración.
Las lecturas pueden ejecutarse con la tarea inactiva o activa. Las escrituras se rechazan cuando una ejecución, terminal o vista previa posee el contenedor. Cambiar de rama también exige un árbol limpio. Así se evitan carreras con el modelo.
Cada comando de la interfaz es un array fijo ejecutado como UID/GID 1000:1000; la
entrada nunca se evalúa en shell. Se desactivan configuración global y del sistema,
prompts, hooks, asistentes de credenciales, firma, submódulos, diff externos,
textconv y protocolos de red. Se rechazan repositorios cuyo árbol no sea exactamente
/workspace o cuyo directorio Git/común quede fuera. Las escrituras que podrían
procesar contenido también se bloquean si hay filtros clean, smudge o process
ejecutables.
Estos controles protegen la API Git. Un administrador aún puede usar Terminal y el
modelo run_command para ejecutar Git normal. El aislamiento y el despliegue siguen
siendo los límites para comandos arbitrarios.
Habilidades integradas del worker
Cada ejecución recibe una guía propiedad del servidor. Explica el límite persistente
de /workspace, la raíz de solo lectura, el estado temporal de procesos y /tmp,
la política de red, límites y ciclo de la vista previa. Sus habilidades indican:
- inspeccionar instrucciones, manifiestos, bloqueos, scripts y estado antes de editar;
- conservar trabajo ajeno y agrupar lecturas independientes;
- continuar con la implementación, no detenerse tras un plan;
- verificar de forma centrada antes de comprobaciones amplias;
- diagnosticar fallos, no reintentar a ciegas; y
- verificar la aplicación antes de iniciar la vista como último proceso duradero.
La guía solo existe en el contexto. Libre WebUI no crea AGENTS.md, directorios de
habilidades ni controles en el espacio. Las instrucciones del proyecto no pueden
anular la seguridad del contenedor o las herramientas.
Terminal
Terminal conecta un shell interactivo al mismo contenedor aislado para inspeccionar, compilar manualmente o depurar sin salir del navegador.
El shell usa la misma política: usuario sin privilegios 1000:1000, directorio
/workspace, contenedor reforzado y sin capacidades. No concede privilegios que
run_command no tenga; es una interfaz humana al mismo límite.
Comportamiento operativo:
- Autenticación: el navegador intercambia Authorization por un ticket efímero y
de un uso, vinculado al protocolo y tarea. Solo ticket e ID aparecen en
/ws/work-terminal. Antes de cada entrada, Libre vuelve a comprobar cuenta, acceso, existencia y propiedad. La revocación cierra el shell y libera el arrendamiento. - Comprobación de origen: si se configura
CORS_ORIGINoBASE_URL, las actualizaciones del navegador deben coincidir. Configura al menos una en remoto. Las actualizaciones sin origen siguen disponibles para Electron y otros clientes, pero requieren el mismo ticket y controles; usa TLS, cortafuegos y proxy. - Admisión: una terminal toma un arrendamiento y cuenta en
WORK_MAX_ACTIVE_RUNTIMES_*. - Vida del contenedor: una terminal conectada lo mantiene activo y evita que se detenga por inactividad.
- Concurrencia:
WORK_TERMINAL_MAX_SESSIONS_PER_TASK(2 por defecto) limita los shells simultáneos. - Tiempo de inactividad:
WORK_TERMINAL_IDLE_TIMEOUT_MS(15 minutos por defecto) cierra una sesión sin uso. - Durante una ejecución: la pestaña explica que el modelo posee el contenedor y abre el shell cuando termina.
Terminal habla directamente con Docker Engine porque un TTY exige un flujo
bidireccional secuestrado. Usa WORK_DOCKER_SOCKET, luego DOCKER_HOST —socket
unix:// o endpoint tcp:// HTTP, como un proxy que transporta el flujo por
Connection: Upgrade— y finalmente /var/run/docker.sock. Un DOCKER_HOST no
compatible (ssh:// o tcp:// con DOCKER_TLS_VERIFY) informa del motivo sin
conectarse a otro lugar. En Kubernetes, la misma sesión usa el subrecurso exec como
TTY WebSocket mediante el servidor de API, con redimensionado y sin Docker.
Las sesiones son interactivas y no se graban. Los comandos no aparecen en Actividad.
Vista previa
Vista previa inicia, detiene, integra y abre la aplicación generada. Con el campo de comando vacío, Libre WebUI inspecciona el espacio y:
- ejecuta un script
devdepackage.jsonraíz con host y puerto requeridos; - sirve un
index.htmlraíz con un servidor estático integrado sin dependencias; o - aplica las mismas reglas a una única aplicación anidada.
Las aplicaciones raíz tienen prioridad. Si hay varias anidadas igual de probables o
ningún punto compatible, Work devuelve un error útil en vez de intentar un comando
npm ajeno. Introduce un comando personalizado para otros diseños. Empiezan en
/workspace, así que incluye el directorio relativo, por ejemplo
cd apps/web && npm run dev -- --host 0.0.0.0 --port 4173. Debe escuchar en
0.0.0.0 y WORK_PREVIEW_PORT. Work espera hasta 15 segundos.
El modelo también puede iniciar mediante start_preview. Es la única forma
compatible de dejar un proceso activo. Las llamadas run_command limpian los
descendientes al terminar.
Pantalla (Work Computer)
Mira la demostración completa: una ejecución real sin editar (30x y después en tiempo real) de un agente de Work que explora las galerías de NASA en su propia pantalla, elige fotografías y crea y prueba una galería Three.js interactiva, todo a partir de un prompt.
Una tarea cuya política activa Work Computer obtiene una pestaña Pantalla: una ventana en directo a un escritorio virtual dentro del mismo entorno, con gestor de ventanas, dock y Chromium en una pantalla 1280×800. Puedes observar al agente, tomar el control de ratón y teclado, escuchar el audio y enseñarle mediante demostración. Abrir la pestaña inicia la sesión gráfica bajo demanda (nada se ejecuta hasta que alguien mira) y conecta un visor VNC por WebSocket.
Un administrador lo activa con un clic: la página inicial muestra una tarjeta
Work Computer y Activar. El botón compila la imagen gráfica integrada en el
daemon Docker del despliegue (la primera vez tarda unos minutos) y crea una política
lista, sin docker build ni campos manuales. Tras un proxy filtrado, el endpoint de
compilación se deniega deliberadamente; descarga la imagen publicada en el host
(ghcr.io/libre-webui/libre-work-computer, etiquetada
libre-work-computer:latest) o compílala allí desde deploy/work-computer/; entonces
Activar omite la compilación y solo crea la política. Sus tareas deben tener red:
la pantalla se alcanza por un puerto de contenedor publicado en loopback, como la
vista previa.
Modelo de seguridad: el servidor VNC se enlaza a localhost tras dos contraseñas por
sesión: una de solo lectura para todo observador autorizado y otra de control total
solo para quien tenga el arrendamiento de control. El propio servidor mantiene
inactivas las entradas del resto. El puente WebSocket es la única superficie
accesible, publicada en loopback y nunca directamente. Cada visor se autentica con
un ticket de un uso vinculado a sesión y tarea, igual que Terminal, y se vuelve a
comprobar el acceso en cada conexión; revocar acceso corta las pantallas de inmediato.
Hasta cuatro visores pueden observar una pantalla, y observar cuenta como actividad
para el barrido de inactividad. Observar y ejecutar no compiten: abrir durante una
ejecución se conecta a su entorno, observar no bloquea la siguiente ejecución y la
sesión sobrevive al final, incluso en equipo con un worker separado. El perfil del
navegador persiste en /workspace/.browser-profile, por lo que los inicios de sesión
sobreviven a recreaciones.
Control del agente: la tarea ofrece dos herramientas adicionales.
computer_observe devuelve una captura completa, posición del cursor, ventana activa,
URL actual, si la página (frente a la interfaz del navegador) tiene el foco,
descriptor del elemento enfocado y hash de la captura. Las señales proceden de un
endpoint DevTools en loopback y no aparecen en imágenes gráficas antiguas.
computer_act ejecuta hasta 24 acciones (mover, clic, doble clic, clic derecho,
escribir, combinaciones, desplazar, esperar) y devuelve la captura estabilizada.
Tres guardas mantienen la honestidad: acciones type/key pueden declarar focus
y fallan cerradas si el campo no tiene foco (para que el texto no vaya al omnibox);
el lote se detiene si aparece una ventana, cambia el título o se mueve el foco porque
las coordenadas restantes pertenecían a la pantalla anterior; y puede declarar un
resultado esperado (título, URL o región cambiada) que el entorno comprueba con un
plazo adaptable: «pending» significa aún no observado, nunca éxito supuesto. La
pantalla se estabiliza mediante consultas, no un retraso fijo. Cada resultado lleva
pruebas: los clics devuelven si cambiaron píxeles próximos, scroll_until desplaza
hacia texto o borde e informa si se hizo visible, y cada observación se compara con
la anterior. Un lote puede declarar un subgoal de una línea, conservado como punto
de control y repetido en prompts de recuperación. El bucle detecta estancamiento
(tres acciones iguales sin cambios generan un aviso; repetir termina solicitando
entrada) y ambigüedad acumulada (expectativas consecutivas no verificadas generan
reorientación). La telemetría —rondas, latencia, capturas, guardas y veredictos— se
guarda en cada registro y se resume al final. Las capturas llegan como imágenes
reales por todas las rutas —Ollama, Anthropic, Gemini y plugins compatibles con
OpenAI, Chat y Responses—, por lo que debe usarse un modelo de visión. Si el
proveedor rechaza la entrada de imágenes (un modelo de solo texto), la ejecución no
falla: las capturas se descartan durante el resto de la ejecución, se indica al
modelo que dependa de las observaciones de texto y una nota de la transcripción
explica la degradación. Sin embargo, un modelo que no ve la pantalla verifica mucho
menos, así que da preferencia a uno de visión para tareas informáticas. Solo las más
recientes permanecen en contexto; las transcripciones guardan texto, nunca bytes de
imagen. El navegador incorpora bloqueo de contenido: uBlock Origin Lite para
anuncios y rastreadores (fijado y verificado mediante suma de comprobación al crear
la imagen, con el modo de filtrado fijado por una política administrada) y un cierre
automático de avisos de consentimiento de cookies, porque los anuncios y esos avisos
desperdician capturas, tokens y clics. Las solicitudes de anuncios se neutralizan al
estilo de uBlock: los scripts publicitarios conocidos se resuelven a sustitutos
locales inocuos para que las páginas sigan funcionando. Se indica al agente que no
introduzca credenciales ni complete CAPTCHA/2FA;
informa del bloqueo. Para tareas no fiables, combina la política con DNS filtrado:
un navegador hace más importante la salida de red.
Audio: la pantalla está silenciada por defecto (el navegador exige un clic); el
botón de altavoz transmite el sonido. PulseAudio reproduce en un sumidero nulo cuyo
monitor se captura como PCM y sirve por otro puente WebSocket autenticado en
loopback, con el mismo ticket, comprobación y límite de visores. Requiere una imagen
de deploy/work-computer/ de esta versión o posterior.
Control humano: Tomar el control entrega ratón y teclado para iniciar sesión,
resolver un CAPTCHA o realizar un paso prohibido al agente; He terminado los
devuelve. Una sesión VNC sirve ambos roles: el servidor guarda contraseñas de control
y lectura generadas por sesión y no registradas; los observadores solo reciben la de
lectura y el titular del arrendamiento, la de control. El arrendamiento tiene TTL
(caduca en dos minutos si se abandona), se renueva con la interfaz abierta y no puede
arrebatarse. Una política puede desactivar Permitir tomar el control: oculta los
controles de control y enseñanza, el endpoint se niega y request_takeover informa
de que nadie puede tomarlo; observar sigue disponible. Mientras una persona
controla, computer_observe y computer_act están bloqueadas, para que el agente no
interfiera ni capture lo escrito. El agente puede solicitarte: request_takeover
muestra un aviso con el motivo y espera hasta que tomes y devuelvas el control. Las
credenciales van directamente del teclado a la página, nunca al modelo o
transcripción. Requiere una imagen actual; las antiguas siguen visibles pero solo en
lectura.
Modo de enseñanza: Enseñar una tarea graba una demostración. Conduces la pantalla
(toma el control con indicador de grabación) y se capturan puntero, teclado y
desplazamiento en coordenadas. Cada clic se ancla: una sonda de lectura resuelve el
elemento (etiqueta, ID y texto visible) y la URL, de modo que los pasos nombran sus
objetivos —"Click "button#submit (Place order)""— y las coordenadas quedan como
pista. Guardar construye un procedimiento determinista, sin modelo en el bucle:
agrupa teclas en texto, distingue clic y arrastre con 8 píxeles, convierte pausas en
esperas y censura texto con vocabulario secreto o forma de credencial (8+ caracteres
con tres clases), sustituyéndolo por request_takeover. El procedimiento en lenguaje
natural contiene cuándo usarlo, entradas, pasos, verificación, un ámbito permitido
derivado de los hosts visitados (debe detenerse antes de abandonarlos; nunca hereda
más autoridad), límites de aprobación y tratamiento de fallos. Se guarda como una
habilidad normal (prefijo taught-) con versiones, edición y uso compartido. Las
ejecuciones cargan las habilidades enseñadas y activadas del propietario y las
muestran en su lista; repetir una tarea es una ejecución cuyo encargo coincide. Tras
terminar, las etiquetas permiten registrar con un clic si funcionó o falló,
añadiendo una línea fechada a Historial de resultados (más reciente primero,
acotado, cada una como versión). No escribas contraseñas reales durante la grabación:
demuestra hasta el inicio, guarda y deja que request_takeover gestione credenciales.
Proveedores, enrutamiento y divulgación de datos
Rutas compatibles
| Ruta | Validación y comportamiento |
|---|---|
| Ollama local | Ollama debe estar sano y el modelo exacto debe anunciar herramientas. |
| Ollama Cloud | Se enruta expresamente mediante Ollama; los sufijos cloud muestran el aviso remoto. |
| Plugin de completado/chat | Debe estar activo, enumerar el modelo exacto y tener credencial del administrador actual. |
| Plugin Anthropic | Usa el adaptador de mensajes y herramientas de Anthropic. |
| Plugin Gemini | Usa el adaptador de contenidos y llamadas a funciones de Gemini. |
| Otros plugins compatibles | Usan mensajes, herramientas y elección al estilo de OpenAI. |
El tipo y el ID del plugin se guardan en tarea y ejecución. El nombre del modelo nunca elige la ruta por sí solo. Un plugin con el mismo nombre que Ollama no puede interceptar una tarea existente.
Qué recibe el proveedor
En cada ronda puede recibir:
- el prompt de sistema de Work;
- habilidades integradas y límites actuales;
- hasta los últimos 30 mensajes, acotados a 256 KB;
- definiciones de herramientas;
- historial de llamadas; y
- resultados, incluidos listados, contenido solicitado, búsquedas, salidas y errores.
El volumen no se sube entero. Sin embargo, cualquier contenido o salida devuelto por una herramienta entra en la conversación y se envía al proveedor. Revisa sus políticas de conservación, entrenamiento, precios y uso antes de usar código sensible.
Las credenciales permanecen en el backend, tanto globales como por usuario. Se usan para solicitudes del backend y nunca se montan en el contenedor.
El cifrado de credenciales no cifra toda la tarea. Conversaciones, resultados, salidas y metadatos son contenido ordinario de la base, mientras que archivos y dependencias son archivos ordinarios del volumen o PVC. Usa controles del host y cifrado de disco si el modelo de amenazas lo exige.
Aviso de proveedor remoto
Work considera remotos los plugins y nombres Ollama terminados en :cloud o
-cloud. Seleccionarlos abre un aviso descartable sobre flujo de datos y varias
llamadas facturables. La preferencia se recuerda por usuario.
Todas las rutas usan WORK_MAX_AGENT_ROUNDS, 48 rondas por defecto. No hay límite
separado de 12 para plugins. El presupuesto de herramientas es el mayor entre 128
llamadas u ocho por ronda configurada. Al agotarse, Libre WebUI pide una entrega
final sin herramientas que describa trabajo, comprobaciones, bloqueos y pasos. La
ejecución queda como Necesita entrada, no como excepción ni trabajo completado.
Otra ejecución continúa en el mismo espacio. Una ejecución puede seguir haciendo
muchas solicitudes facturables.
Espacios vinculados a carpetas del host (opcional)
Con Docker, /workspace suele ser un volumen exclusivo, por lo que el modelo no
alcanza archivos reales. Un despliegue puede permitir vincular una tarea a una
carpeta del host. Kubernetes lo rechaza y usa un PVC de la tarea.
Define ambas variables y reinicia:
WORK_HOST_WORKSPACES_ENABLED=true
WORK_HOST_WORKSPACE_ROOTS=/Users/you/Projects
WORK_HOST_WORKSPACE_ROOTS es una lista separada por :; por defecto es el
directorio personal del usuario del servidor. Al activarlo aparece Carpeta del
espacio de trabajo. Déjalo vacío para usar un volumen aislado normal.
Una ruta debe ser absoluta, existir, ser un directorio y resolverse —también a
través de enlaces— dentro de una raíz. Se rechazan .ssh, .gnupg, .aws,
.config, .kube, .docker, .claude, .libre-webui y node_modules. La ruta
resuelta se guarda y muestra en la cabecera.
Una carpeta del host significa que el modelo lee y escribe archivos reales, y las demás protecciones —usuario sin root, capacidades retiradas y límites— ya no lo separan de ese directorio. Mantén la función desactivada salvo necesidad, usa raíces estrechas y prefiere directorios bajo control de versiones.
Persistencia y ciclo del entorno
Libre WebUI separa estado duradero y ejecución:
| Estado | Almacenamiento | Duración |
|---|---|---|
| Propiedad, título, proveedor y estado | Base de datos de Libre WebUI | Hasta eliminar la tarea o al propietario |
| Ejecuciones, errores, mensajes y actividad | Base de datos de Libre WebUI | Hasta eliminar la tarea |
| Archivos | Volumen Docker o PVC K8s de la tarea | Sobreviven a cancelación, parada, reinicio del entorno y de la aplicación |
| Raíz y archivos temporales | Contenedor o Pod de la tarea | Desechables; pueden detenerse o recrearse |
| Proceso de vista previa | Entorno activo de la tarea | Efímero; solo mientras se verifica sano |
| Borrador sin guardar | Sesión del navegador | Estado temporal de comodidad |
Cada tarea recibe un UUID del servidor. Los nombres se derivan en el backend y no se aceptan del navegador. Los recursos llevan etiquetas de gestión y propiedad. Antes de reutilizar o borrar, Libre WebUI comprueba la propiedad y rechaza un recurso de otra tarea.
Los entornos se preparan bajo demanda. Los asistentes de archivos detienen uno inactivo, los comandos lo detienen al terminar y una vista sana puede mantenerlo activo. El espacio duradero vuelve a montarse al iniciar o recrear.
Los administradores pueden definir políticas de entorno con nombre en la pestaña Gestión de usuarios en Configuración: imagen, límites de memoria/CPU/PID, tamaño del espacio (Kubernetes), tiempo de inactividad, red predeterminada y dos capacidades: Work Computer (GUI + navegador), que añade escritorio y Pantalla, y Permitir tomar el control, que decide si una persona puede controlar y, por tanto, enseñar. Una tarea usa la configuración de su política; los campos vacíos heredan valores globales y eliminar la política los restaura en la siguiente recreación. Las políticas solo ajustan recursos y capacidades; el perfil de seguridad no puede debilitarse por política.
WORK_RUNTIME_IDLE_TIMEOUT_MS limita la gracia: si está definido, un barrido detiene
un entorno sin actividad —comandos, terminal o solicitudes de vista mediante proxy—
durante esos milisegundos y libera su plaza. El espacio persiste y se reinicia al
usarse. El valor 0 predeterminado conserva la vista hasta detenerla expresamente.
Al iniciar el backend, las ejecuciones activas se marcan fallidas y se borra el estado de vistas: el bucle y el proxy murieron y no se reanudan. El controlador enumera recursos gestionados en una consulta. Detiene los activos de tareas conocidas porque un comando podría seguir sin supervisor, deja los ya detenidos y elimina los huérfanos sin fila. La propiedad procede de la etiqueta, no del nombre. Se supone que una sola instancia posee el daemon o espacio de nombres. No apuntes dos instancias a los mismos recursos. Si no se puede demostrar la limpieza, Work queda cerrado, reintenta cada 10 segundos y bloquea cambios hasta recuperar el acceso.
Comportamiento de red
Las tareas sin política con nombre empiezan con red. Un administrador puede crear una política cuyo valor predeterminado sea sin red y el creador elegirla. No hay un interruptor independiente por tarea; cambiar la política requiere recrear el entorno.
En Docker, las tareas con red se conectan a un bridge dedicado
(libre-webui-work por defecto, WORK_NETWORK_NAME) creado con comunicación entre
contenedores desactivada (com.docker.network.bridge.enable_icc=false). Por tanto:
- un entorno no puede conectarse a otro; y
- no puede alcanzar contenedores del despliegue en el bridge predeterminado, como una base u Ollama que no se haya publicado expresamente.
Libre WebUI se niega a iniciar si existe una red con el nombre configurado que no es la gestionada, en vez de conectarse silenciosamente.
En Kubernetes, el Pod lleva la misma etiqueta. Helm instala NetworkPolicy de
denegación, entrada solo para vista previa y salida a internet solo para Pods con red,
excluyendo work.networkPolicy.blockedEgressCidrs. Solo es efectiva si el CNI la
aplica; consulta Kubernetes.
La salida exterior sigue permitida porque descargas, Git remoto y API hacen útil Work. No es un cortafuegos saliente. El código puede alcanzar:
- servicios del host Docker;
- sistemas de la red local;
- servicios de internet; y
- endpoints de metadatos de infraestructura, según el despliegue.
Puntos de integración de políticas de salida
Para un límite más estricto, combina:
WORK_RUNTIME_DNS(Docker): direcciones IPv4/IPv6 separadas por comas impuestas con--dns. Un resolutor filtrado proporciona listas por nombre sin modificar Libre WebUI. Las entradas que no son direcciones se rechazan para que no inyecten opciones.- Reglas de cortafuegos del host o superiores (Docker) en la subred estable del bridge gestionado.
WORK_NETWORK_NAME(Docker) apuntando a una red creada previamente con tus opciones. Libre WebUI comprueba la etiqueta de gestión y que ICC esté desactivado.
DNS limita la resolución, no IP directas. Para garantizar que no haya salida directa se necesitan reglas en host, clúster o red superior.
No supongas que Work impide transmitir datos. Concédelo solo a usuarios de confianza. Usa una política sin red cuando una tarea deba empezar desconectada; no hay una variable global que cambie el valor predeterminado.
La red no añade credenciales. Libre WebUI no monta claves SSH, credenciales de nube,
perfiles, directorio personal ni socket Docker. El código sí puede transmitir
cualquier secreto escrito en /workspace.
Este tráfico es independiente del tráfico del modelo. Ollama y plugins siempre son llamados por el backend a la ruta seleccionada.
Límite de seguridad del entorno aislado
Un contenedor Docker de Work:
- se ejecuta sin root como UID/GID
1000:1000; - usa
/workspacecomo directorio de trabajo; - solo monta el volumen de la tarea en
/workspace; - usa raíz de solo lectura y un
/tmpacotado; - retira todas las capacidades Linux;
- activa
no-new-privileges; - no es privilegiado y usa init;
- aplica límites de CPU, memoria, procesos, tiempo y salida;
- fija swap al límite (
--memory-swapigual a--memory); - se conecta a la red gestionada con comunicación desactivada o no tiene red; y
- solo publica el puerto de vista en un puerto loopback asignado por Docker.
Todo se vuelve a verificar con docker inspect antes de reutilizar y se resume en la
etiqueta ai.libre-webui.policy. Un contenedor cuya política sea anterior a una
actualización se destruye y recrea, para que el refuerzo alcance tareas existentes.
Kubernetes aplica un contexto equivalente: UID/GID sin root, raíz de solo lectura,
seccomp RuntimeDefault, sin elevación, capacidades retiradas, almacenamiento
efímero y recursos acotados, sin token ServiceAccount y PVC de la tarea en
/workspace. Verifica etiquetas y huella antes de reutilizar o borrar Pod o PVC.
La validación rechaza rutas absolutas, traversal, barras inversas, NUL y rutas demasiado largas. Los asistentes resuelven rutas reales y rechazan escapes por enlaces. Las escrituras usan archivo temporal y renombrado atómico.
Estos controles reducen exposición accidental; no convierten Work en una máquina virtual ni un entorno seguro para malware. Los contenedores comparten el kernel. Una vulnerabilidad de Docker, Kubernetes, ejecución, imagen, dependencia o kernel puede cruzar el límite.
Los volúmenes Docker no tienen cuota independiente. Un proyecto o instalación puede agotar el almacenamiento: supervisa el crecimiento y aplica límites en el host. Kubernetes solicita tamaño de PVC; la aplicación real depende del provisionador.
Lista de refuerzo de Docker en producción
Esta lista es específica de Docker. Los operadores de Kubernetes también deben validar RBAC por espacio, contexto de seguridad, clase de almacenamiento y aplicación de NetworkPolicy por CNI según la guía de Kubernetes.
La aplicación puede definir opciones, validar rutas y proteger su API. No puede imponer el cortafuegos del host, cuotas del controlador ni privilegios del daemon. Trátalos como trabajo explícito de despliegue.
1. Aislar el control de Docker
El contenedor principal necesita controlar el daemon para crear e inspeccionar. Un socket montado es una credencial del plano de control, no datos: comprometer la aplicación puede comprometer el host.
La primera mitigación está en el repositorio: docker-compose.socket-proxy.yml
mantiene el socket fuera. Un proxy interno conserva /var/run/docker.sock y solo
remite contenedores, imágenes, volúmenes, redes, exec e información; deniega swarm,
secretos, configs, build, commit y sistema antes del daemon. Libre WebUI usa
DOCKER_HOST=tcp://docker-socket-proxy:2375 sin montaje ni grupo; CLI, terminal y
diagnóstico siguen el mismo endpoint. Reduce la superficie, no el daño de lo que
permite: quien crea contenedores puede montar rutas, por lo que el límite inferior
sigue importando.
Para mayor seguridad, ejecuta Libre WebUI y su daemon Work en una VM dedicada. Mejor aún, usa un daemon rootless dedicado u otro host y expón solo ese daemon. Verifica propiedad, vistas, limpieza y terminal antes de desplegar. Montar el mismo socket rootful como solo lectura no hace la API de solo lectura.
2. Bloquear el acceso desde el entorno a la gestión del host
Desactivar comunicación entre contenedores no impide alcanzar servicios enlazados al host. Inspecciona el bridge y la subred reales:
docker network inspect libre-webui-work \
--format 'id={{.Id}} subnets={{range .IPAM.Config}}{{.Subnet}} {{end}}'
ss -lntup
Usa el cortafuegos persistente para rechazar tráfico del bridge hacia SSH, API
Docker, bases y puertos administrativos. Prueba desde un contenedor desechable,
prueba descargas permitidas y haz persistente la regla. DOCKER-USER controla
tráfico reenviado; el destinado al propio host puede necesitar INPUT en la interfaz.
3. Restringir destinos salientes
Bloquea metadatos de nube, rangos privados y LAN del cliente salvo necesidad. Combina
WORK_RUNTIME_DNS con cortafuegos. DNS se elude con IP literal; un proxy HTTP tampoco
basta mientras los comandos abran conexiones directas. Impón la política fuera.
Mantén políticas nombradas distintas: sin red, solo registro de paquetes y salida abierta. La política decide si se conecta la red; cortafuegos y proxy restringen destinos.
4. Aplicar cuotas reales de almacenamiento
Los límites de CPU, memoria, swap y PID no limitan el volumen. Elige almacenamiento
con cuotas por espacio: XFS, volúmenes lógicos o controlador de volumen/PVC con
tamaño. El controlador local de Docker sobre ext4 no obtiene una cuota fiable por
documentar un tamaño.
Supervisa volúmenes ai.libre-webui.managed=true y la raíz de Docker, alerta antes
de llenarse y prueba el fallo. Un contador o du periódico avisa, pero no impone un
límite porque un contenedor puede consumir el disco entre comprobaciones.
5. Verificar la política desplegada
Tras cada cambio, crea una tarea desechable y comprueba con docker inspect: UID sin
root, raíz de solo lectura, capacidades retiradas, no-new-privileges, límites de
memoria/swap/CPU/PID, solo el volumen de la tarea y red esperada. Comprueba también
los montajes del contenedor principal y que el acceso público pase por proxy
autenticado, no por un puerto publicado por error.
Seguridad y acceso de la vista previa
En Docker, el controlador publica el puerto a otro asignado dinámicamente en
loopback. En Kubernetes, el backend del clúster apunta directamente a la IP del Pod.
Modelo y navegador no eligen el upstream. Libre WebUI firma una URL de capacidad
para tarea y endpoint, comprueba que siga activa y representa HTTP y WebSocket por
/api/work/previews. Detener o reiniciar revoca la URL antigua.
Las respuestas eliminan credenciales y cookies superiores. HTML se restringe por sandbox de iframe y CSP que permiten scripts, formularios, modales y descargas sin acceso de mismo origen. CSP protege también otra pestaña. El código sigue sin ser fiable y puede transmitir lo que lea. Trata la URL como secreto efímero.
Como el navegador carga el proxy en el origen público de Libre WebUI, funcionan
navegadores remotos y proxies HTTPS sin exponer puertos ni contenido mixto. El proxy
debe conservar WebSocket en /api/work/previews/; la configuración Nginx lo hace.
La aplicación principal solo permite su origen y Cloudflare Turnstile como fuentes de marcos. Las respuestas de vista omiten Helmet para transmitir cuerpos y aplicar la política estrecha. La política de integración cruzada sigue desactivada porque los servidores generados no suelen emitir cabeceras compatibles.
Matriz de despliegue
La disponibilidad depende de la máquina y proceso del backend, no solo del navegador.
| Despliegue | Ejecuciones y archivos de Work | Vista previa integrada |
|---|---|---|
npx libre-webui local | Compatible si Docker está instalado, activo y accesible al usuario del backend. | Compatible mediante el proxy firmado del origen. |
| Desarrollo desde código local | Compatible con los mismos requisitos. | Compatible mediante el origen de API de desarrollo en el puerto 3001. |
| Cliente Electron | Condicional. Usa un backend externo y no aporta otro entorno. | Compatible mediante el proxy firmado del backend. |
| Backend bare metal o VM remoto | Ejecuciones, archivos y proveedores funcionan si Docker está disponible. | Compatible si el proxy público conserva HTTP y WebSocket. |
| Docker Compose estándar | Compatible por defecto en Docker Desktop: la imagen incluye CLI, Compose monta el socket y los puertos de Work pasan por host.docker.internal. Docker Engine nativo necesita además un WORK_PREVIEW_BIND no público y alcanzable. | Compatible mediante el mismo origen público. |
| Kubernetes/Helm actual | Compatible con --set work.enabled=true: los entornos son Pods con PVC (ejecuciones, archivos, comandos, git, terminales, pantalla y audio de Work Computer en la IP del Pod), Role por espacio y NetworkPolicies de denegación, sin socket. Consulta Kubernetes. | Compatible con backend en el clúster apuntando directamente a la IP del Pod. |
Ejecutar Work cuando Libre WebUI está en Docker
Todos los archivos Compose activan Work: la imagen incluye Docker CLI y se monta
/var/run/docker.sock. Docker Desktop funciona con los valores de enrutamiento
incluidos. Docker Engine nativo necesita además que WORK_PREVIEW_BIND apunte a una
interfaz del host no pública y alcanzable desde contenedores hermanos, como se
describe más abajo.
Work controla el daemon del host; las tareas son hermanas del contenedor, aparecen
en docker ps y siguen las mismas reglas que una instalación nativa.
Montar el socket en una aplicación web concede control equivalente a root. Work no funciona sin él, por lo que se activa en lugar de quedar silenciosamente inútil. La consecuencia: cada administrador es en la práctica administrador del host Docker. Los operadores asumen seguridad, red, ciclo, copias y acceso. Elimina la línea del socket para desactivar Work; nada más depende de ella.
Para conservarlo sin entregar el socket, usa docker-compose.socket-proxy.yml: el
proxy interno lo conserva y remite solo secciones usadas; Libre WebUI accede mediante
DOCKER_HOST. Consulta Aislar el control de Docker.
Deben cumplirse tres condiciones, y el panel nombra la que falle:
- Docker CLI debe existir. Está en la imagen oficial; una personalizada necesita
docker-clioWORK_DOCKER_COMMAND. Si no:The "docker" CLI is not installed…. - Debe montarse el socket. Si no:
No Docker daemon is reachable…. - El usuario debe pertenecer al grupo. La imagen usa
nodejs(uid 1001) y el socket suele ser derootodocker; Compose pasagroup_add: ['${DOCKER_GID:-0}']. El valor sirve para Docker Desktop; Linux necesita su ID. Si no:The Docker socket is mounted but the Libre WebUI user cannot open it….
# Read the socket's group as seen INSIDE a container. A macOS host reports a
# different value, because Docker Desktop proxies the socket through a VM.
echo "DOCKER_GID=$(docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
alpine stat -c '%g' /var/run/docker.sock)" >> .env
docker compose up -d --force-recreate
Los puertos de vista permanecen en loopback. Libre WebUI expone cada vista mediante proxy firmado del mismo origen, incluidos recursos y WebSocket. Funciona con HTTPS y túneles sin abrir puertos. Los documentos reciben una política restrictiva y reiniciar revoca la URL anterior.
Cuando el backend está en Docker, publicar y conectar puede usar direcciones
distintas. Mantén WORK_PREVIEW_BIND=127.0.0.1 y define
WORK_DOCKER_PUBLISHED_HOST como la dirección alcanzable
(host.docker.internal en Docker Desktop). Los perfiles Compose incluidos definen
ambos valores y mapean ese nombre de host. En Linux nativo hay que sustituir
WORK_PREVIEW_BIND por la puerta de enlace del puente de Docker (u otra interfaz del
host no pública y explícitamente alcanzable); mapear el nombre no vuelve accesible un
listener loopback. Nunca vincules estos puertos efímeros a 0.0.0.0.
La concurrencia se limita por separado: WORK_MAX_ACTIVE_RUNTIMES_PER_USER es 2
y WORK_MAX_ACTIVE_RUNTIMES_GLOBAL, 3. Así puede ejecutarse una segunda tarea.
La respuesta muestra límites y ocupación. Auméntalos si hay recursos.
Para Kubernetes, instala con work.enabled=true en vez de exponer un socket. Helm
crea RBAC, espacio, políticas y Pods/PVC descritos en Kubernetes.
Configuración del entorno
Work lee estas variables:
| Variable | Predeterminado | Finalidad |
|---|---|---|
WORK_RUNTIME_BACKEND | docker | Controlador: docker o kubernetes |
WORK_RUNTIME_IMAGE | node:22.22-bookworm@sha256:2d178f2785b96dfbf62a416ca2e40f50e30150b4ff3320d706f0d96e90600eb3 | Imagen de los entornos |
WORK_DOCKER_COMMAND | docker | Ejecutable CLI del backend Docker |
WORK_COMMAND_TIMEOUT_MS | 120000 | Tiempo predeterminado de comando |
WORK_MAX_OUTPUT_CHARS | 50000 | Máximo de salida capturada |
WORK_MAX_AGENT_ROUNDS | 48 | Presupuesto de rondas por ejecución |
WORK_MEMORY_LIMIT | 2g | Memoria por contenedor |
WORK_CPU_LIMIT | 2 | CPU por contenedor |
WORK_PIDS_LIMIT | 256 | Procesos por contenedor |
WORK_PREVIEW_PORT | 4173 | Puerto que debe escuchar la aplicación |
WORK_PREVIEW_BIND | 127.0.0.1 | Interfaz donde se publica |
WORK_DOCKER_PUBLISHED_HOST | igual que WORK_PREVIEW_BIND | Host/IP que llama el backend para puertos publicados |
WORK_COMPUTER_SCREEN_PORT | 6080 | Puerto WebSocket de pantalla |
WORK_COMPUTER_AUDIO_PORT | 6081 | Puerto WebSocket de audio |
WORK_RUN_LEASE_WAIT_MS | 60000 | Espera de un titular transitorio |
WORK_MAX_ACTIVE_RUNTIMES_GLOBAL | 3 | Tareas con contenedor simultáneas por instancia |
WORK_MAX_ACTIVE_RUNTIMES_PER_USER | 2 | Tareas simultáneas por administrador |
WORK_MAX_TASKS_GLOBAL | 500 | Tareas persistentes por instancia |
WORK_MAX_TASKS_PER_USER | 100 | Tareas persistentes por administrador |
WORK_NETWORK_NAME | libre-webui-work | Bridge gestionado para tareas con red |
WORK_RUNTIME_DNS | sin definir | IP de resolutores separadas por comas |
WORK_DOCKER_SOCKET | DOCKER_HOST si es unix:// o tcp://; si no, /var/run/docker.sock | Endpoint Engine para terminales |
WORK_TERMINAL_MAX_SESSIONS_PER_TASK | 2 | Terminales simultáneas por tarea |
WORK_TERMINAL_IDLE_TIMEOUT_MS | 900000 | Tiempo de inactividad |
WORK_RUNTIME_IDLE_TIMEOUT_MS | 0 (desactivado) | Detener entorno tras inactividad, vistas incluidas |
WORK_K8S_NAMESPACE | libre-webui-work | Espacio de Pods/PVC |
WORK_K8S_STORAGE_CLASS | valor predeterminado del clúster | StorageClass de PVC |
WORK_K8S_WORKSPACE_SIZE | 5Gi | Tamaño predeterminado por tarea |
WORK_K8S_POD_READY_TIMEOUT_MS | 900000 | Espera máxima a que Pod esté listo |
WORK_K8S_POD_GONE_TIMEOUT_MS | 60000 | Espera máxima a que desaparezca un Pod eliminado |
Usa una versión o digest fijo en producción. Una etiqueta mutable puede cambiar herramientas y seguridad sin cambiar Libre WebUI.
Ejecución, vista, archivos, comandos y recreación comparten la misma contabilidad. Una operación anidada no cuenta otra tarea. Superar límites devuelve HTTP 429.
Límites fijos de protocolo e interfaz
| Elemento | Límite |
|---|---|
| Mensaje de tarea o ejecución nueva | 65,536 caracteres y bytes UTF-8 |
| ID de modelo al crear/actualizar | 500 caracteres y bytes UTF-8 |
| ID del proveedor plugin | 200 caracteres |
| Ejecuciones activas por tarea | 1 |
| Texto de comando | 20,000 caracteres |
| Tiempo solicitado por herramienta | 1 a 600 segundos |
| Preparación de vista | 15 segundos |
| Lectura/escritura de archivo | 2,000,000 bytes de texto UTF-8 |
| Listado directo | Primeras 1,000 entradas |
| Página de mensajes | Hasta 200 mensajes y 1,000,000 bytes |
| Mensaje individual persistido | 100 KB |
| Contexto enviado al modelo | Últimos 30 mensajes, hasta 256 KB |
| Salida de herramienta persistida | Unos 20,000 caracteres de origen y marcador |
| Resaltado en vivo | 8,000 caracteres y 400 líneas |
| Formato en navegador | 100,000 caracteres y 4,000 líneas |
| Salida de estado Git | 2,000,000 caracteres capturados |
| Salida de diff Git | 600,000 caracteres capturados |
| Historial Git | 20 commits locales |
| Rutas en una preparación Git | 200 |
| Mensaje de commit Git | 4,000 caracteres |
| Bucle del agente, todas las rutas | 48 rondas por defecto, mediante WORK_MAX_AGENT_ROUNDS |
| Presupuesto de herramientas | max(128, configured rounds × 8) llamadas |
El acceso es para texto UTF-8. El editor no abre binarios ni archivos de más de 2 MB mediante la API.
Resumen de la API
Todos los endpoints están bajo /api/work y exigen autenticación y acceso actual.
Work es administrativo por defecto; las operaciones ordinarias pueden abrirse a
usuarios activos. Las carpetas del host y políticas siguen siendo administrativas.
| Método | Ruta | Finalidad |
|---|---|---|
GET | /capabilities | Disponibilidad y límites de entorno/proveedor |
GET | /tasks | Enumerar tareas del administrador actual |
POST | /tasks | Crear tarea y primera ejecución asíncrona |
GET | /tasks/:id | Cargar estado y mensajes recientes |
GET | /tasks/:id/messages | Paginar mensajes antiguos |
PATCH | /tasks/:id | Renombrar o cambiar ruta explícita |
DELETE | /tasks/:id | Eliminar tarea y espacio duradero |
POST | /tasks/:id/runs | Iniciar ejecución posterior |
POST | /tasks/:id/messages | Escribir al agente durante ejecución |
GET | /tasks/:taskId/runs/:runId/events | Transmitir eventos autenticados por SSE |
POST | /tasks/:id/cancel | Cancelar ejecución activa |
GET | /tasks/:id/approvals | Aprobaciones pendientes y estado de Revisión automática |
PUT | /tasks/:id/approvals | Activar o desactivar aprobaciones en la tarea |
POST | /tasks/:id/approvals/:approvalId | Decidir una aprobación pendiente (una vez, siempre, denegar) |
DELETE | /tasks/:id/approval-rules/:ruleId | Quitar una regla de «permitir siempre» |
GET | /computer/setup | Estado de configuración de Work Computer |
POST | /computer/setup | Compilar imagen y crear política |
POST | /tasks/:id/computer/start | Iniciar Work Computer |
GET | /tasks/:id/computer/control | Quién conduce; solicitud del agente |
POST | /tasks/:id/computer/control | Tomar o renovar control |
DELETE | /tasks/:id/computer/control | Devolver pantalla |
POST | /tasks/:id/computer/teach | Guardar demostración como habilidad |
POST | /tasks/:id/computer/anchor | Resolver elemento bajo un clic |
POST | /computer/skills/:slug/trace | Añadir resultado a habilidad enseñada |
GET | /tasks/:id/files | Enumerar directorio |
GET | /tasks/:id/file | Leer archivo de texto |
PUT | /tasks/:id/file | Guardar archivo |
GET | /tasks/:id/git | Leer estado e historial Git |
GET | /tasks/:id/git/diff | Leer diff acotado |
POST | /tasks/:id/git/init | Inicializar Git |
POST | /tasks/:id/git/stage | Preparar rutas explícitas |
POST | /tasks/:id/git/commit | Confirmar cambios preparados |
POST | /tasks/:id/git/branches | Crear rama local |
POST | /tasks/:id/git/switch | Cambiar a rama limpia existente |
POST | /tasks/:id/preview/start | Iniciar vista gestionada |
POST | /tasks/:id/preview/stop | Detener vista |
El ID siempre se comprueba contra el propietario. Estado, rol y acceso se leen en cada solicitud, por lo que revocar surte efecto aunque un JWT antiguo esté obsoleto.
El esquema conserva networkEnabled para compatibilidad interna. No se expone como
control independiente. Elige una política con el valor de red previsto al crear;
no uses el campo bruto como API de configuración duradera.
Eliminación, cambios de cuenta y copias
Eliminar una tarea
La eliminación es deliberadamente destructiva:
- El backend marca la tarea como en retirada para impedir cambios nuevos.
- Cancela la ejecución activa y detiene el entorno.
- Libre WebUI valida las etiquetas de propiedad.
- Elimina contenedor/Pod y volumen/PVC.
- Elimina la tarea de la base, con ejecuciones y mensajes en cascada.
- Borra los borradores del navegador tras el éxito.
Si falla la limpieza, conserva el registro y devuelve un error para reparar el backend y reintentar. No borra metadatos dejando recursos sin seguimiento.
Detener una ejecución o vista solo detiene procesos y conserva volumen y conversación.
Degradación de administrador y eliminación de usuario
Al degradar a un administrador, Libre WebUI guarda la revocación antes de depender de la limpieza. Toda solicitud posterior comprueba rol y acceso. Después suspende las tareas si el rol ya no tiene acceso e intenta abortar y detener. Si falla, el acceso sigue revocado y se informa para restaurar el entorno y reintentar.
Eliminar a otro usuario primero borra sus recursos Work. Si falla la limpieza externa, conserva el usuario para poder reintentar sin perder metadatos de propiedad.
Copiar la tarea completa
Una copia completa necesita:
- la base de Libre WebUI, con propiedad, nombres de recursos, proveedor, ejecuciones, mensajes y actividad; y
- todos los volúmenes o PVC con
ai.libre-webui.managed=true, que contienen archivos.
No hace falta copiar contenedores ni procesos. Para consistencia, detén nueva actividad y el backend antes de capturar base y espacios. Sigue el procedimiento del proveedor de almacenamiento.
Restaura base y espacios juntos. Recrea cada volumen o PVC con el nombre exacto y
metadatos, incluidos ai.libre-webui.task=<task UUID> y
ai.libre-webui.managed=true. Copiar archivos no conserva etiquetas. Solo la base
produce tareas sin archivos; solo el almacenamiento pierde propiedad y nombres.
Si también hay credenciales cifradas, sigue la guía general para directorio de datos y clave.
Localización y árabe RTL
La interfaz completa está traducida a los 25 idiomas compatibles: inglés, árabe, bengalí, checo, danés, alemán, español, francés, hindi, indonesio, islandés, italiano, japonés, coreano, malayo, neerlandés, polaco, portugués, ruso, sueco, tailandés, turco, ucraniano, vietnamita y chino.
El árabe aplica lang="ar" y dir="rtl" antes de React. La barra se mueve a la
derecha, Conversación ocupa la derecha y Espacio la izquierda, los iconos se
reflejan, la navegación sigue RTL y el redimensionado usa semántica visual RTL.
El contenido técnico permanece de izquierda a derecha cuando afecta a la precisión:
- código y resaltado;
- rutas;
- ID de modelos;
- comandos y registros;
- salidas y metadatos; y
- contenido de bloques de código.
Nombres, prompts naturales, errores, nombres de archivo y comandos usan dirección automática cuando corresponde.
Solución de problemas
Entorno no disponible con npx
npx libre-webui ejecuta el backend en el host, pero no instala Docker. Ejecuta
docker info como el mismo usuario. Si falta o no alcanza el daemon, instala/inicia
Docker o corrige permisos y recarga Work.
Confirma también que Ollama esté sano o que un plugin activo tenga modelo y credencial para el administrador.
Entorno no disponible en Docker o Kubernetes
Compose del repositorio no debería mostrarlo: la imagen incluye CLI y monta socket.
Si ocurre, el panel nombra la causa: CLI ausente, montaje eliminado o grupo
incorrecto. En el último caso, define DOCKER_GID y recrea. Consulta
Ejecutar Work cuando Libre WebUI está en Docker.
En Kubernetes, activa con --set work.enabled=true. Libre informa kubernetes,
consulta la API y ejecuta Pods con PVC. No montes el socket del nodo; consulta
Kubernetes.
No hay modelos compatibles
En Ollama, elige uno que anuncie tools. Para un plugin, confirma:
- tipo completado o chat;
- activo;
- modelo exacto en el mapa;
- clave de API utilizable del administrador; y
- herramientas compatibles con el proveedor.
Work nunca recurre a otro proveedor.
Falla instalar un paquete o ejecutar Git remoto
Confirma que la política seleccionada tenga red. No hay interruptor independiente. Inspecciona DNS, proxy, cortafuegos/NetworkPolicy, registro, certificado, entorno y servicio superior. Confirma que la imagen contenga el comando.
Git es solo local. Usa Terminal o comandos del modelo para Git remoto únicamente si la política de red y credenciales lo permite. No pegues tokens duraderos.
La ejecución se detiene por un límite del agente
El modelo quizá agotó rondas o herramientas. Work pide una entrega final sin
herramientas; revisa trabajo y pasos. La tarea queda Necesita entrada, terminal
para esa ejecución pero sin afirmar que terminó. Continúa con otra o eleva
WORK_MAX_AGENT_ROUNDS si recursos y costes lo permiten.
HTTP 429 al iniciar
La instancia o administrador alcanzó un límite de entornos activos o tareas. Espera
a que se detenga otro, elimina tareas antiguas o aumenta WORK_MAX_* deliberadamente.
La vista previa no se prepara
Confirma que el comando siga activo, enlace 0.0.0.0 y escuche
WORK_PREVIEW_PORT en 15 segundos. Con campo vacío, Work detecta package.json
dev o index.html, incluida una aplicación anidada. Si hay varias o ninguna,
introduce un comando. Empiezan en /workspace, así que usa
cd <app-directory> && ... para una anidada.
Funciona en el servidor, pero no en un navegador remoto
Confirma una compilación con proxy firmado y reinicia para sustituir una URL antigua.
Si carga pero no hay recarga en caliente, comprueba WebSocket en
/api/work/previews/. El puerto debe seguir en loopback y no necesita cortafuegos.
Los archivos permanecen, pero la vista se detuvo
Es normal tras cancelación, reinicio, parada explícita o fallo de preparación. El proceso es efímero y el volumen duradero. Vuelve a iniciarlo.
No se puede abrir o guardar un archivo
La API admite texto UTF-8 hasta 2 MB. Si informa de un cambio desde la apertura, recarga antes de editar para no sobrescribir otro cambio.
El resaltado pasa a texto por encima de 8,000 caracteres o 400 líneas. El formato tiene límite de 100,000 caracteres y 4,000 líneas y solo admite familias documentadas.
Work indica que está recuperando entornos
El inicio o desmontaje no pudo demostrar que un entorno se detuvo. Work queda cerrado y reintenta cada 10 segundos. Restaura Docker o Kubernetes y revisa el registro. No borres filas mientras haya recursos etiquetados pendientes.
Falla la eliminación
Comprueba que el entorno sea accesible. Un recurso conflictivo sin la etiqueta
ai.libre-webui.task esperada se rechaza en vez de borrarse. Resuelve propiedad y
reintenta.
Resumen de seguridad
Antes de habilitar Work:
- Es administrativo por defecto; abrirlo a todos convierte cada cuenta en operador. Las carpetas del host siempre son administrativas.
- El backend debe controlar su daemon o espacio Kubernetes.
- Los contenedores reducen exposición, no son máquinas virtuales.
- Sin política sin red, las tareas tienen salida; las restricciones por destino siguen a cargo del operador.
- Los volúmenes no tienen cuota independiente.
- Git es solo local; su API no acepta credenciales remotas.
- Cortafuegos, aislamiento, salida y cuotas reales los impone el operador.
- Los proveedores remotos reciben resultados y pueden generar varias llamadas.
- Los puertos permanecen en loopback y solo se exponen por URL firmadas y revocables.
- Compose proporciona Docker; Kubernetes/Helm proporciona Pods/PVC con
work.enabled=true. - Una copia completa exige base de datos y volúmenes.