异步任务

7.1 创建任务

客户端通过发送它想要运行的响应请求来创建任务,请求要包在任务信封中。建议携带 Idempotency-Key 请求头(第 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"
}
字段 必需 含义
type 是 response,1.0 中唯一的任务类型。
input 是 一个响应请求,与 POST /lmsp/v1/responses 的请求相同。其中的 stream 字段会被忽略。
on_restart 否 fail(默认)、retry 或 resume。参见第 7.5 节。

服务必须先持久化任务,再作出应答。随后返回:

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
}
任务字段 含义
id 任务标识符,例如 task_...。
object 始终为 "task"。
type response。
status 当前状态(第 7.2 节)。
created_at、updated_at 时间,自 Unix 纪元起的秒数。
response_id 该任务所产生的响应的 id,在创建任务时分配。
events_url 事件流的路径。event_resume 能力为 true 时存在。
on_restart 该任务的重启策略。
response status 为 succeeded 后是响应对象,否则为 null。
error status 为 failed 时是一个 problem 对象(第 9.3 节),否则为 null。

GET /lmsp/v1/tasks/{task_id} 返回任务对象。不使用事件流的客户端轮询该接口。未知的 id 返回 404 和 task_not_found。已结束的任务如下所示:

{
  "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 状态机

queued --> loading --> running --> succeeded
  |           |           |
  |           |           +--> failed
  |           |           +--> cancelling --> cancelled
  |           +--------------> failed
  +--------------------------> cancelled
状态 含义 后续状态
queued 已接受并持久化,等待开始。 loading、cancelled、failed
loading 正在加载模型。 running、cancelling、failed
running 模型正在生成。 succeeded、failed、cancelling
cancelling 已请求取消,后端尚未停止。 cancelled
succeeded 终态。响应已完成。 无
failed 终态。 无
cancelled 终态。 无

终态只有 succeeded、failed 和 cancelled。处于终态的任务不得再发生变化。响应以 incomplete 结束的任务(例如达到 token 上限)是 succeeded。

每次状态转换都是原子的,因此任务不会既被取消又已完成,先提交的转换生效。

7.3 取消

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

服务返回 200 OK 和当前任务对象。queued 任务立即变为 cancelled;loading 或 running 任务先变为 cancelling,直到后端停止后再变为 cancelled。

取消操作必须幂等:重复取消已处于 cancelling 或 cancelled 的任务,仍返回当前任务,不产生新错误。

取消已经 succeeded 或 failed 的任务,返回 409 和 task_not_cancelable。未知的 id 返回 404 和 task_not_found。

7.4 事件流

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

该接口是可选的,在 event_resume 能力为 true 时可用。

  • 事件是第 6.3 节中的响应事件,对应该任务所产生的响应。序号与恢复规则遵循第 6.4 节。
  • 事件流以 response.created 开始,它在任务被接受时记录。流以与结果相符的一个最终事件结束:response.completed、response.incomplete、response.failed 或 response.cancelled。
  • 较晚连接的客户端先收到自己错过的事件,再收到实时事件。服务在最终事件之后关闭流。
  • 事件会保留一段保留期(第 11.2 节)。更早的事件返回 410 Gone 和 event_history_expired。

7.5 重启语义

on_restart 规定服务重启时对未完成任务如何处理:

取值 行为
fail 默认值。服务把未完成的任务标记为 failed,错误码为 server_restarted。
retry 服务从头重新执行该任务。
resume 服务从快照继续执行。仅当后端明确支持可恢复快照时才允许,否则创建请求会被拒绝,返回 400 和 unsupported_capability。

服务重启时处于 cancelling 的任务,无论其策略如何,都会完成取消并变为 cancelled。

不建议把 retry 作为默认值,因为任务可能已经执行了工具或产生了外部副作用。选择 retry 的客户端必须同时使用 Idempotency-Key,并使其工具调用幂等。