Asynchrone Aufgaben
- Normativ
- Entwurf 1.0
- Aktualisiert
- Als Markdown anzeigen
7.1 Eine Aufgabe erstellen
Ein Client erstellt eine Aufgabe, indem er die Antwortanfrage, die er ausführen möchte, in einen Aufgaben-Umschlag verpackt per POST sendet. Ein Idempotency-Key-Header wird empfohlen (Abschnitt 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"
}
| Feld | Erforderlich | Bedeutung |
|---|---|---|
type |
Ja | response, der einzige Aufgabentyp in 1.0. |
input |
Ja | Eine Antwortanfrage, genau wie für POST /lmsp/v1/responses. Ihr Feld stream wird ignoriert. |
on_restart |
Nein | fail (der Standard), retry oder resume. Siehe Abschnitt 7.5. |
Der Dienst MUSS die Aufgabe persistieren, bevor er antwortet. Danach gibt er zurück:
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
}
| Aufgabenfeld | Bedeutung |
|---|---|
id |
Aufgabenkennung, etwa task_.... |
object |
Immer "task". |
type |
response. |
status |
Der aktuelle Zustand (Abschnitt 7.2). |
created_at, updated_at |
Zeiten in Sekunden seit der Unix-Epoche. |
response_id |
ID der Antwort, die die Aufgabe erzeugt. Sie wird bei der Erstellung der Aufgabe vergeben. |
events_url |
Pfad des Ereignisstroms. Vorhanden, wenn die Fähigkeit event_resume true ist. |
on_restart |
Die Neustartrichtlinie der Aufgabe. |
response |
Das Antwortobjekt, sobald status succeeded ist, sonst null. |
error |
Ein Problemobjekt (Abschnitt 9.3), wenn status failed ist, sonst null. |
GET /lmsp/v1/tasks/{task_id} gibt das Aufgabenobjekt zurück. Clients, die keine Ereignisströme nutzen, fragen diesen Endpunkt regelmäßig ab. Eine unbekannte ID ergibt 404 mit task_not_found. Eine abgeschlossene Aufgabe sieht so aus:
{
"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 Zustandsautomat
queued --> loading --> running --> succeeded
| | |
| | +--> failed
| | +--> cancelling --> cancelled
| +--------------> failed
+--------------------------> cancelled
| Zustand | Bedeutung | Folgezustände |
|---|---|---|
queued |
Angenommen und persistiert, wartet auf den Start. | loading, cancelled, failed |
loading |
Das Modell wird geladen. | running, cancelling, failed |
running |
Das Modell generiert. | succeeded, failed, cancelling |
cancelling |
Der Abbruch wurde angefordert, und das Backend hat noch nicht angehalten. | cancelled |
succeeded |
Endzustand. Die Antwort ist vollständig. | keine |
failed |
Endzustand. | keine |
cancelled |
Endzustand. | keine |
Die Endzustände sind succeeded, failed und cancelled. Eine Aufgabe in einem Endzustand DARF NICHT mehr wechseln. Eine Aufgabe, deren Antwort als incomplete endet, zum Beispiel am Token-Limit, ist succeeded.
Jeder Übergang ist atomar, sodass eine Aufgabe nie zugleich abgebrochen und abgeschlossen ist. Es gewinnt der Übergang, der zuerst festgeschrieben wird.
7.3 Abbruch
POST /lmsp/v1/tasks/{task_id}/cancel
Der Dienst gibt 200 OK und das aktuelle Aufgabenobjekt zurück. Eine queued-Aufgabe wird sofort cancelled. Eine loading- oder running-Aufgabe wird cancelling, bis das Backend angehalten hat, und danach cancelled.
Der Abbruch MUSS idempotent sein. Der Abbruch einer Aufgabe, die bereits cancelling oder cancelled ist, gibt die aktuelle Aufgabe zurück und erzeugt keinen neuen Fehler.
Der Abbruch einer Aufgabe, die bereits succeeded oder failed ist, wird mit 409 und task_not_cancelable beantwortet. Eine unbekannte ID ergibt 404 mit task_not_found.
7.4 Ereignisströme
GET /lmsp/v1/tasks/{task_id}/events
Accept: text/event-stream
Dieser Endpunkt ist optional. Er ist verfügbar, wenn die Fähigkeit event_resume true ist.
- Die Ereignisse sind die Antwortereignisse aus Abschnitt 6.3, für die Antwort, die die Aufgabe erzeugt. Nummerierung und Fortsetzung folgen Abschnitt 6.4.
- Der Stream beginnt mit
response.created, das bei der Annahme der Aufgabe aufgezeichnet wird. Er endet mit genau einem letzten Ereignis, das zum Ergebnis passt:response.completed,response.incomplete,response.failedoderresponse.cancelled. - Ein Client, der sich spät verbindet, erhält zuerst die verpassten Ereignisse und danach Live-Ereignisse. Der Dienst schließt den Stream nach dem letzten Ereignis.
- Ereignisse werden für eine Aufbewahrungsdauer vorgehalten (Abschnitt 11.2). Ältere Ereignisse ergeben
410 Gonemitevent_history_expired.
7.5 Neustartverhalten
on_restart legt fest, was mit einer unfertigen Aufgabe geschieht, wenn der Dienst neu startet:
| Wert | Verhalten |
|---|---|
fail |
Der Standard. Der Dienst markiert die unfertige Aufgabe als failed, mit dem Fehlercode server_restarted. |
retry |
Der Dienst führt die Aufgabe von vorn erneut aus. |
resume |
Der Dienst setzt von einem Snapshot aus fort. Das ist nur erlaubt, wenn das Backend fortsetzbare Snapshots ausdrücklich unterstützt. Andernfalls wird die Erstellungsanfrage mit 400 und unsupported_capability abgelehnt. |
Eine Aufgabe, die beim Neustart des Dienstes cancelling ist, schließt ihren Abbruch ab und wird cancelled, unabhängig von ihrer Richtlinie.
retry wird als Standard nicht empfohlen, weil die Aufgabe möglicherweise schon Tools ausgeführt oder externe Nebeneffekte erzeugt hat. Ein Client, der retry wählt, MUSS es mit einem Idempotency-Key kombinieren und seine Tool-Aufrufe idempotent machen.