Tareas asíncronas

7.1 Crear una tarea

Un cliente crea una tarea enviando por POST la solicitud de respuesta que quiere ejecutar, envuelta en un sobre de tarea. Se recomienda una cabecera Idempotency-Key (sección 9.2).

POST /lmsp/v1/tasks
Authorization: Bearer <token>
Idempotency-Key: 01J8M7C4Y3N5P8R2T6V9X1Z4BH
{
  "type": "response",
  "input": {
    "model": "qwen3:14b-q4_k_m",
    "input": [
      {
        "type": "message",
        "role": "user",
        "content": [
          {
            "type": "input_text",
            "text": "Write a long report."
          }
        ]
      }
    ]
  },
  "on_restart": "fail"
}
Campo Obligatorio Significado
type Sí response, el único tipo de tarea en 1.0.
input Sí Una solicitud de respuesta, exactamente igual que para POST /lmsp/v1/responses. Su campo stream se ignora.
on_restart No fail (el valor por defecto), retry o resume. Consulta la sección 7.5.

El servicio DEBE persistir la tarea antes de responder. Después devuelve:

HTTP/1.1 202 Accepted
{
  "id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC",
  "object": "task",
  "type": "response",
  "status": "queued",
  "created_at": 1794200100,
  "updated_at": 1794200100,
  "response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
  "events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events",
  "on_restart": "fail",
  "response": null,
  "error": null
}
Campo de la tarea Significado
id Identificador de la tarea, como task_....
object Siempre "task".
type response.
status El estado actual (sección 7.2).
created_at, updated_at Horas en segundos desde la época Unix.
response_id Id de la respuesta que produce la tarea. Se asigna al crear la tarea.
events_url Ruta del flujo de eventos. Presente cuando la capacidad event_resume es true.
on_restart La política de reinicio de la tarea.
response El objeto de respuesta una vez que status es succeeded; en caso contrario, null.
error Un objeto de problema (sección 9.3) cuando status es failed; en caso contrario, null.

GET /lmsp/v1/tasks/{task_id} devuelve el objeto de tarea. Los clientes que no usan flujos de eventos consultan periódicamente este endpoint. Un id desconocido produce 404 con task_not_found. Una tarea terminada tiene este aspecto:

{
  "id": "task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC",
  "object": "task",
  "type": "response",
  "status": "succeeded",
  "created_at": 1794200100,
  "updated_at": 1794200162,
  "response_id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
  "events_url": "/lmsp/v1/tasks/task_01J8M8R5X3V7B2N4Q9T1W6Y0ZC/events",
  "on_restart": "fail",
  "response": {
    "id": "resp_01J8M8R5X4B9D2F6H1K3N7Q0ZW",
    "object": "response",
    "created_at": 1794200100,
    "status": "completed",
    "model": "qwen3:14b-q4_k_m",
    "output": [
      {
        "id": "msg_01J8M8R6A2C5E8G1J4M7P0S3VY",
        "type": "message",
        "role": "assistant",
        "content": [
          {
            "type": "output_text",
            "text": "Local model services make on-device inference a shared, discoverable utility..."
          }
        ]
      }
    ],
    "usage": {
      "input_tokens": 12,
      "output_tokens": 1480,
      "total_tokens": 1492
    },
    "error": null,
    "incomplete_details": null
  },
  "error": null
}

7.2 Máquina de estados

queued --> loading --> running --> succeeded
  |           |           |
  |           |           +--> failed
  |           |           +--> cancelling --> cancelled
  |           +--------------> failed
  +--------------------------> cancelled
Estado Significado Estados siguientes
queued Aceptada y persistida, a la espera de empezar. loading, cancelled, failed
loading Se está cargando el modelo. running, cancelling, failed
running El modelo está generando. succeeded, failed, cancelling
cancelling Se solicitó la cancelación y el backend aún no se ha detenido. cancelled
succeeded Final. La respuesta está completa. ninguno
failed Final. ninguno
cancelled Final. ninguno

Los estados terminales son succeeded, failed y cancelled. Una tarea en estado terminal NO DEBE volver a cambiar. Una tarea cuya respuesta termina como incomplete, por ejemplo al llegar al límite de tokens, está succeeded.

Todas las transiciones son atómicas, así que una tarea nunca está a la vez cancelada y completada. Gana la transición que se confirme primero.

7.3 Cancelación

POST /lmsp/v1/tasks/{task_id}/cancel

El servicio devuelve 200 OK y el objeto de tarea actual. Una tarea queued pasa a cancelled de inmediato. Una tarea loading o running pasa a cancelling hasta que el backend se haya detenido, y después a cancelled.

La cancelación DEBE ser idempotente. Cancelar una tarea que ya está cancelling o cancelled devuelve la tarea actual y no produce ningún error nuevo.

Cancelar una tarea que ya está succeeded o failed se responde con 409 y task_not_cancelable. Un id desconocido produce 404 con task_not_found.

7.4 Flujos de eventos

GET /lmsp/v1/tasks/{task_id}/events
Accept: text/event-stream

Este endpoint es opcional. Está disponible cuando la capacidad event_resume es true.

  • Los eventos son los eventos de respuesta de la sección 6.3, correspondientes a la respuesta que produce la tarea. La numeración y la reanudación siguen la sección 6.4.
  • El flujo empieza con response.created, que se registra cuando se acepta la tarea. Termina con un único evento final que corresponde al resultado: response.completed, response.incomplete, response.failed o response.cancelled.
  • Un cliente que se conecta tarde recibe primero los eventos que se perdió y después los eventos en vivo. El servicio cierra el flujo después del evento final.
  • Los eventos se conservan durante un período de retención (sección 11.2). Los eventos más antiguos producen 410 Gone con event_history_expired.

7.5 Semántica de reinicio

on_restart indica qué ocurre con una tarea sin terminar cuando el servicio se reinicia:

Valor Comportamiento
fail El valor por defecto. El servicio marca la tarea sin terminar como failed, con el código de error server_restarted.
retry El servicio ejecuta la tarea de nuevo desde el principio.
resume El servicio continúa desde una instantánea. Esto solo se permite cuando el backend admite explícitamente instantáneas reanudables. En caso contrario, la solicitud de creación se rechaza con 400 y unsupported_capability.

Una tarea que está cancelling cuando el servicio se reinicia completa su cancelación y pasa a cancelled, sea cual sea su política.

retry no se recomienda como valor por defecto, porque la tarea puede haber ejecutado ya herramientas o producido efectos secundarios externos. Un cliente que elige retry DEBE combinarlo con un Idempotency-Key y hacer que sus llamadas a herramientas sean idempotentes.