Media Lab Server
El servidor HTTP local (`127.0.0.1:8765`) para generación de imágenes y música. Arquitectura, API, ciclo de vida e integración con el Coordinator.
GET /api/statusPOST /api/imagePOST /api/musicGET /api/jobs/<id>GET /api/jobsGET /outputs/<file>GET /Ciclo de vida del jobGeneración de imágenesGeneración de músicaGestión de quotaOutput directoryCiclo de vidaLaunchd plist (macOS)Systemd unit (Linux)ConfiguraciónLoggingHealth checksFailure modesIntegración con el CoordinatorSeguridadVer tambiénEstado
Implemented. El servidor es un proceso standalone que el Coordinator llama a través de HTTP. Corre en el host local y no se expone a internet.
Propósito
El Media Lab Server es un pequeño servicio HTTP que expone las capacidades de generación de imágenes y música del lab a través de una web UI y una API HTTP. El Coordinator llama a la API para generar imágenes y música en respuesta a requests del usuario; el usuario también puede visitar la web UI directamente en un navegador.
Esta página documenta la arquitectura del servidor, los endpoints, el ciclo de vida y la integración con el Coordinator.
Por qué un servidor, no una herramienta CLI
Se prefiere un servidor sobre una herramienta CLI para generación porque:
- UI con estado. Una web UI puede mostrar progreso, histórico y descargas.
- Requests de larga duración. La generación puede tardar 30 segundos a 3 minutos; una request HTTP encaja naturalmente.
- Aislamiento del host de modelos. El servidor se puede reiniciar independientemente del Coordinator.
- Múltiples clientes. El usuario puede golpear la UI desde un navegador mientras el Coordinator también llama a la API.
El servidor es el único servidor HTTP del lab que expone capacidades de generación.
Dirección de escucha y puerto
| Campo | Valor | Razón |
|---|---|---|
| Host | 127.0.0.1 | Solo localhost; no se expone a la LAN o WAN. |
| Port | 8765 | Reservado para el Media Lab Server. |
| Protocol | HTTP/1.1 | Simple; no se necesita TLS porque es localhost. |
El servidor está bindeado a localhost solo. No es alcanzable desde la LAN o internet. El usuario puede acceder a la UI en http://127.0.0.1:8765/ en un navegador de la misma máquina.
Arquitectura
El servidor es un proceso Python. La arquitectura:
El servidor tiene:
- Una HTTP API que acepta job requests.
- Una web UI que envía jobs y muestra progreso.
- Un job queue que serializa las requests de generación.
- Un image worker que llama al modelo de imagen.
- Un music worker que llama al modelo de música.
- Un output directory donde se escriben los resultados.
Endpoints
GET /api/status
Devuelve el health del servidor y la carga actual.
Response (200):
POST /api/image
Envía un job de generación de imagen.
Request:
Response (202):
POST /api/music
Envía un job de generación de música.
Request:
Response (202):
GET /api/jobs/<id>
Consulta el status de un job.
Response (200) para un image job completado:
Response (200) para un music job completado:
Response (200) para un job running:
GET /api/jobs
Lista jobs recientes. Paginación mediante ?limit=N&offset=M.
Response:
GET /outputs/<file>
Devuelve el fichero generado. Endpoint estático; la ruta del fichero es el nombre del fichero en el output directory.
GET /
La web UI. Single-page application que envía jobs y muestra progreso.
Ciclo de vida del job
Un job pasa por estos estados:
| Status | Significado |
|---|---|
pending | El job está en la cola; ningún worker lo ha recogido. |
running | Un worker está generando el output. |
completed | El output está listo; el campo outputs está poblado. |
failed | La generación falló; el campo error está poblado. |
La máquina de estados es in-process; la cola es una lista en memoria. Si el servidor se reinicia, la cola se pierde. Los jobs pending los reenvía el cliente.
Generación de imágenes
El image worker llama a la API de imagen del provider de modelos. El modelo por defecto es image-01. Los tamaños soportados:
| Size | Caso de uso |
|---|---|
512x512 | thumbnails, small previews |
1024x1024 | default, square images |
1536x1024 | landscape images |
1024x1536 | portrait images |
2048x2048 | high-resolution images |
La imagen se devuelve en PNG por defecto. El output se escribe en el output directory como img_<job_id>_<index>.png.
La duración media de generación es:
| Size | Duración media |
|---|---|
512x512 | 8-12 s |
1024x1024 | 12-18 s |
1536x1024 | 18-25 s |
2048x2048 | 30-45 s |
La duración depende de la carga del provider.
Generación de música
El music worker llama a la API de música del provider. El modelo por defecto es Music-2.6. Los parámetros soportados:
| Parámetro | Default | Rango | Notas |
|---|---|---|---|
duration_s | 60 | 1 to 300 | El provider cap a 5 min |
instrumental | true | bool | Si false, lyrics requerido |
lyrics | (none) | string | Requerido si instrumental: false |
temperature | 1.0 | 0.0 to 2.0 | Mayor = más creativo |
seed | (none) | integer | Outputs reproducibles |
El output es MP3 por defecto. El output se escribe en el output directory como mus_<job_id>_<index>.mp3.
La duración media de generación:
| Duration | Duración media |
|---|---|
| 30 s | 30-60 s |
| 60 s | 60-120 s |
| 120 s | 120-240 s |
| 300 s | 300-600 s |
Gestión de quota
El servidor trackea la quota diaria para generación de imágenes y música. La quota se resetea a medianoche UTC. Las quotas por defecto son:
| Recurso | Quota diaria | Fuente |
|---|---|---|
| Image | 50 images/day | Plan default |
| Music | 100 songs/day | Plan default |
El servidor rechaza jobs que excederían la quota con 429 Too Many Requests y un body JSON:
El Coordinator comprueba la quota antes de enviar un job para evitar round-trips desperdiciados.
Output directory
El servidor escribe outputs en ~/.openclaw/media/outbound/ por defecto. El Coordinator puede configurar la ruta mediante la variable de entorno MEDIA_LAB_OUTPUT_DIR.
La estructura del directorio:
Los ficheros antiguos los limpia un job de retención que corre diario a las 03:00 hora local. La retención por defecto es 30 días.
Ciclo de vida
El servidor está supervisado por launchd (macOS) o systemd (Linux). Las responsabilidades del supervisor:
- Start on boot. El servidor arranca cuando el usuario hace login.
- Restart on crash. El supervisor reinicia el servidor si crashea.
- Reload on configuration change. El supervisor envía
SIGHUPpara recargar la configuración.
Launchd plist (macOS)
El plist está en {workspace-root}/services/media-lab-server/launchd.plist. El label de launchd es ai.openclaw.media-lab-server. El log del supervisor está en ~/.openclaw/media/logs/launchd.out.log.
Systemd unit (Linux)
La unit está en /etc/systemd/system/openclaw-media-lab.service. El nombre de la unit es openclaw-media-lab. El log de la unit está en /var/log/openclaw/media-lab.log.
Configuración
La configuración del servidor está en {workspace-root}/.openclaw/media-lab-server/config.toml.
| Campo | Default | Propósito |
|---|---|---|
host | 127.0.0.1 | Bind address. |
port | 8765 | Bind port. |
output_dir | ~/.openclaw/media/outbound/ | Output directory. |
retention_days | 30 | Retención de outputs. |
image_model | image-01 | Modelo de imagen por defecto. |
music_model | Music-2.6 | Modelo de música por defecto. |
quota_image | 50 | Quota diaria de imagen. |
quota_music | 100 | Quota diaria de música. |
log_level | INFO | Log level. |
log_format | json | Log format. |
Logging
El servidor registra a ~/.openclaw/media/logs/server.log. El formato es JSON Lines por defecto. Cada entrada de log incluye:
timestamp: ISO 8601 UTC.level:INFO,WARN,ERROR.event: el nombre del evento (p. ej.,job_submitted,job_started,job_completed).job_id: el ID del job.duration_ms: para jobs completados.error: para jobs fallidos.
Ejemplo:
Health checks
El servidor expone GET /api/status para health checks. El Coordinator y los scripts de auditoría consultan este endpoint periódicamente. La response esperada es 200 OK con el status del servidor.
Un health check fallido indica:
- El servidor está caído (reiniciar el supervisor).
- El servidor está sobrecargado (esperar y reintentar).
- El provider de modelos está caído (comprobar la página de status del provider).
Failure modes
| Failure | Resultado |
|---|---|
| El provider de modelos está caído | Devolver failed con el error del provider. |
| Quota exhausted | Devolver 429 con info de quota. |
| Output directory está lleno | Devolver failed con error de disco lleno. |
| Job queue está lleno | Devolver 503 con header retry-after. |
| El servidor crashea | El supervisor lo reinicia. La cola se pierde. |
| Restart durante un job | El job se pierde; el cliente debe reenviarlo. |
Integración con el Coordinator
El Coordinator llama al servidor a través de la API. El flujo típico del Coordinator:
El Coordinator hace polling al job hasta que esté completed o failed. El intervalo de polling es 5 segundos para image jobs, 10 segundos para music jobs.
Seguridad
El servidor está bindeado a localhost. No requiere autenticación porque los únicos clientes son procesos locales. Si el usuario quiere exponer el servidor a la LAN (p. ej., para llamar desde un teléfono), el usuario debe:
- Cambiar el bind address a
0.0.0.0. - Añadir un reverse proxy (p. ej., nginx) con TLS.
- Añadir autenticación (p. ej., un token en el header de la request).
El lab no provee estas features out of the box.