# Allgemeine Regeln

> Regeln, die für jeden LMSP-Endpunkt gelten, mit Versions-Headern und Erweiterungen, Idempotenzschlüsseln, dem Fehlerformat problem+json samt Fehlercodes und der Zustandsprüfung.

Source: https://madeforagent.com/de/lmsp/1.0/common-rules/
Language: de
Specification: LMSP 1.0 (draft)
Updated: 2026-11-08

## 9.1 Versionen und Erweiterungen {#versioning}

Jede LMSP-Anfrage **KANN** diese Header tragen:

```http
LMSP-Version: 1.0
LMSP-Client: example-client/1.2.0
```

`LMSP-Version` ist die Protokollversion, auf die der Client abzielt. `LMSP-Client` kennzeichnet die Client-Software für Diagnosezwecke als `name/version`. Das Protokollverhalten eines Dienstes **DARF NICHT** davon abhängen.

Regeln:

- Das `v1` im Pfad bezeichnet die Hauptversion.
- Eine Anfrage, die eine unbekannte Hauptversion nennt, wird mit `426 Upgrade Required` und dem Fehlercode `unsupported_protocol_version` beantwortet.
- Neue optionale Felder **DÜRFEN NICHT** die 1.x-Kompatibilität brechen.
- Dienste und Clients **MÜSSEN** Felder ignorieren, die sie nicht kennen.
- Private Erweiterungen kommen in ein `extensions`-Objekt und werden in umgekehrter Domain-Notation benannt:

```json
{
  "extensions": {
    "com.example.cache": {
      "enabled": true
    }
  }
}
```

## 9.2 Idempotenz {#idempotency}

Anfragen, die etwas erzeugen, etwa das Erstellen einer Antwort, das Erstellen einer Aufgabe oder das Laden eines Modells, akzeptieren einen Idempotenzschlüssel:

```http
Idempotency-Key: <client-generated-unique-value>
```

Der Dienst speichert den Schlüssel zusammen mit einem Digest des Anfrage-Bodys und dem Ergebnis:

- Derselbe Schlüssel mit demselben Body liefert das ursprüngliche Ergebnis zurück.
- Derselbe Schlüssel mit einem anderen Body wird mit `409 Conflict` und `idempotency_conflict` beantwortet.

Ein Schlüssel gilt für den Client und den Endpunkt. Er **SOLLTE** ein eindeutiger Wert mit höchstens 255 Zeichen sein, etwa eine ULID oder eine UUID. Ein Dienst **SOLLTE** Schlüssel mindestens 24 Stunden aufbewahren.

Ein Dienst **KANN** den Schlüssel bei Streaming-Anfragen ignorieren. Ein Client, der sichere Wiederholungen braucht, verwendet eine [Aufgabe](https://madeforagent.com/de/lmsp/1.0/tasks.md).

## 9.3 Fehler {#errors}

Jeder Fehler der LMSP-Schnittstelle verwendet `application/problem+json` ([RFC 9457](https://www.rfc-editor.org/rfc/rfc9457)):

```json
{
  "type": "urn:lmsp:error:model-not-found",
  "title": "Model not found",
  "status": 404,
  "code": "model_not_found",
  "detail": "No local model with id 'qwen3:14b-q4_k_m'",
  "request_id": "req_01J8M9S6Y4W8C3P5R1V7Z2A0DH",
  "retryable": false
}
```

| Feld | Erforderlich | Bedeutung |
| --- | --- | --- |
| `type` | Ja | URI, die die Art des Fehlers kennzeichnet. LMSP verwendet `urn:lmsp:error:` gefolgt vom Code mit Bindestrichen statt Unterstrichen. |
| `title` | Ja | Kurze, menschenlesbare Zusammenfassung. |
| `status` | Ja | Der HTTP-Statuscode. |
| `code` | Ja | Maschinenlesbarer Fehlercode aus der folgenden Liste. |
| `detail` | Nein | Menschenlesbare Erläuterung dieses Auftretens. Sie **DARF NICHT** Geheimnisse, Prompts oder generierte Inhalte enthalten. |
| `request_id` | Nein | Kennung der Anfrage zur Zuordnung zu den Dienstprotokollen. |
| `retryable` | Ja | Ob eine spätere Wiederholung der Anfrage erfolgreich sein kann. |

Gängige Fehlercodes:

| Code | HTTP-Status | Wiederholbar | Bedeutung |
| --- | --- | --- | --- |
| `invalid_request` | 400 | Nein | Die Anfrage ist fehlerhaft oder hat ungültige Parameter. |
| `unauthorized` | 401 | Nein | Das Token fehlt, ist ungültig, abgelaufen oder widerrufen, oder ein Kopplungscode ist falsch. |
| `forbidden` | 403 | Nein | Dem Token fehlt der erforderliche Scope, oder die Prüfung von `Origin` oder `Host` ist fehlgeschlagen. |
| `model_not_found` | 404 | Nein | Kein lokales Modell hat diese ID. |
| `model_not_ready` | 409 | Ja | Das Modell ist nicht geladen und wird nicht bei Bedarf geladen. |
| `model_load_failed` | 500 | Ja | Das Laden des Modells ist fehlgeschlagen. |
| `context_length_exceeded` | 400 | Nein | Die Eingabe passt nicht in das Kontextfenster des Modells. |
| `unsupported_capability` | 400 oder 501 | Nein | Das Modell oder der Dienst unterstützt nicht, was die Anfrage braucht. Ein nicht implementierter optionaler Endpunkt antwortet mit 501. |
| `unsupported_protocol_version` | 426 | Nein | Der Dienst unterstützt die angeforderte Hauptversion nicht. |
| `response_not_found` | 404 | Nein | Keine gespeicherte Antwort hat diese ID. |
| `task_not_found` | 404 | Nein | Keine Aufgabe hat diese ID. |
| `task_not_cancelable` | 409 | Nein | Die Aufgabe ist bereits erfolgreich beendet oder fehlgeschlagen. |
| `idempotency_conflict` | 409 | Nein | Der Idempotenzschlüssel wurde bereits mit einem anderen Anfrage-Body verwendet. |
| `event_history_expired` | 410 | Nein | Die angeforderten Ereignisse sind älter als die Aufbewahrungsdauer. |
| `rate_limited` | 429 | Ja | Zu viele Anfragen. |
| `resource_exhausted` | 503 | Ja | Dem Gerät fehlen Arbeitsspeicher oder eine andere Ressource. |
| `backend_unavailable` | 503 | Ja | Die Modell-Laufzeitumgebung ist nicht erreichbar. |
| `server_restarted` | 503 | Ja | Der Dienst wurde neu gestartet, während die Aufgabe unfertig war. |
| `internal_error` | 500 | Unterschiedlich | Ein unerwarteter Fehler im Dienst. |

Das Feld `retryable` ist maßgeblich. Die Spalte oben zeigt den üblichen Wert. Ein Dienst **KANN** weitere Codes definieren. Ein Client **MUSS** einen Code, den er nicht kennt, anhand seines HTTP-Status und seines Feldes `retryable` behandeln.

## 9.4 Zustandsprüfung {#health}

```http
GET /lmsp/v1/health
```

```json
{
  "status": "ready",
  "service_id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
  "uptime_seconds": 86420,
  "loaded_models": 1,
  "active_tasks": 2,
  "storage": "ok"
}
```

| Feld | Bedeutung |
| --- | --- |
| `status` | `starting`, `ready`, `degraded` oder `stopping`. |
| `service_id` | Die Dienst-ID aus der Dienstbeschreibung. |
| `uptime_seconds` | Sekunden seit dem Start des Dienstes. |
| `loaded_models` | Anzahl der Modelle im Zustand `ready`. |
| `active_tasks` | Anzahl der Aufgaben, die `queued`, `loading`, `running` oder `cancelling` sind. |
| `storage` | `ok` oder `error`. |

Der Status ist `200 OK`, wenn `status` `ready` oder `degraded` ist, andernfalls `503 Service Unavailable`.

Der Health-Endpunkt liefert nur den Betriebszustand. Er **DARF NICHT** Modellpfade, Prompts, Zugriffstokens oder andere sensible Informationen zurückgeben.
