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.
Estado
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 loguea 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.