# Règles communes

> Règles partagées par tous les points de terminaison LMSP, avec les en-têtes de version et les extensions, les clés d’idempotence, le format d’erreur problem+json et ses codes, et le contrôle d’état.

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

## 9.1 Versions et extensions {#versioning}

Chaque requête LMSP **PEUT** porter ces en-têtes :

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

`LMSP-Version` est la version du protocole visée par le client. `LMSP-Client` identifie le logiciel client à des fins de diagnostic, sous la forme `name/version`. Un service **NE DOIT PAS** modifier le comportement du protocole d’après ce dernier.

Règles :

- Le `v1` du chemin désigne la version majeure.
- Une requête qui nomme une version majeure inconnue reçoit la réponse `426 Upgrade Required` avec le code d’erreur `unsupported_protocol_version`.
- Les nouveaux champs facultatifs **NE DOIVENT PAS** rompre la compatibilité 1.x.
- Les services et les clients **DOIVENT** ignorer les champs qu’ils ne connaissent pas.
- Les extensions privées vont dans un objet `extensions` et sont nommées en notation de domaine inversé :

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

## 9.2 Idempotence {#idempotency}

Les requêtes qui créent quelque chose, comme créer une réponse, créer une tâche ou charger un modèle, acceptent une clé d’idempotence :

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

Le service stocke la clé avec une empreinte du corps de la requête et le résultat :

- La même clé avec le même corps renvoie le résultat d’origine.
- La même clé avec un corps différent reçoit la réponse `409 Conflict` avec `idempotency_conflict`.

Une clé est propre au client et au point de terminaison. Elle **DEVRAIT** être une valeur unique d’au plus 255 caractères, telle qu’un ULID ou un UUID. Un service **DEVRAIT** conserver les clés au moins 24 heures.

Un service **PEUT** ignorer la clé sur les requêtes en streaming. Un client qui a besoin de nouvelles tentatives sûres utilise une [tâche](https://madeforagent.com/fr/lmsp/1.0/tasks.md).

## 9.3 Erreurs {#errors}

Chaque erreur de l’interface LMSP utilise `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
}
```

| Champ | Obligatoire | Signification |
| --- | --- | --- |
| `type` | Oui | URI qui identifie le type d’erreur. LMSP utilise `urn:lmsp:error:` suivi du code avec des tirets à la place des traits de soulignement. |
| `title` | Oui | Résumé court et lisible. |
| `status` | Oui | Le code d’état HTTP. |
| `code` | Oui | Code d’erreur lisible par machine, tiré de la liste ci-dessous. |
| `detail` | Non | Explication lisible de cette occurrence. Il **NE DOIT PAS** contenir de secrets, de prompts ni de contenu généré. |
| `request_id` | Non | Identifiant de la requête, pour la corréler avec les journaux du service. |
| `retryable` | Oui | Indique si répéter la requête plus tard peut réussir. |

Codes d’erreur courants :

| Code | État HTTP | Réessayable | Signification |
| --- | --- | --- | --- |
| `invalid_request` | 400 | Non | La requête est mal formée ou comporte des paramètres invalides. |
| `unauthorized` | 401 | Non | Le jeton est absent, invalide, expiré ou révoqué, ou un code d’appairage est erroné. |
| `forbidden` | 403 | Non | Le jeton n’a pas la portée requise, ou la vérification de `Origin` ou de `Host` a échoué. |
| `model_not_found` | 404 | Non | Aucun modèle local n’a cet identifiant. |
| `model_not_ready` | 409 | Oui | Le modèle n’est pas chargé et n’est pas chargé à la demande. |
| `model_load_failed` | 500 | Oui | Le chargement du modèle a échoué. |
| `context_length_exceeded` | 400 | Non | L’entrée ne tient pas dans la fenêtre de contexte du modèle. |
| `unsupported_capability` | 400 ou 501 | Non | Le modèle ou le service ne prend pas en charge ce dont la requête a besoin. Un point de terminaison facultatif non implémenté répond 501. |
| `unsupported_protocol_version` | 426 | Non | Le service ne prend pas en charge la version majeure demandée. |
| `response_not_found` | 404 | Non | Aucune réponse stockée n’a cet identifiant. |
| `task_not_found` | 404 | Non | Aucune tâche n’a cet identifiant. |
| `task_not_cancelable` | 409 | Non | La tâche a déjà réussi ou échoué. |
| `idempotency_conflict` | 409 | Non | La clé d’idempotence a déjà été utilisée avec un corps de requête différent. |
| `event_history_expired` | 410 | Non | Les événements demandés sont plus anciens que la durée de conservation. |
| `rate_limited` | 429 | Oui | Trop de requêtes. |
| `resource_exhausted` | 503 | Oui | L’appareil manque de mémoire ou d’une autre ressource. |
| `backend_unavailable` | 503 | Oui | L’environnement d’exécution du modèle est injoignable. |
| `server_restarted` | 503 | Oui | Le service a redémarré alors que la tâche était inachevée. |
| `internal_error` | 500 | Variable | Une défaillance inattendue à l’intérieur du service. |

Le champ `retryable` fait foi. La colonne ci-dessus indique la valeur habituelle. Un service **PEUT** définir d’autres codes. Un client **DOIT** traiter un code qu’il ne connaît pas d’après son état HTTP et son champ `retryable`.

## 9.4 Contrôle d’état {#health}

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

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

| Champ | Signification |
| --- | --- |
| `status` | `starting`, `ready`, `degraded` ou `stopping`. |
| `service_id` | L’identifiant du service tiré de la description du service. |
| `uptime_seconds` | Secondes écoulées depuis le démarrage du service. |
| `loaded_models` | Nombre de modèles à l’état `ready`. |
| `active_tasks` | Nombre de tâches à l’état `queued`, `loading`, `running` ou `cancelling`. |
| `storage` | `ok` ou `error`. |

L’état HTTP est `200 OK` lorsque `status` vaut `ready` ou `degraded`, et `503 Service Unavailable` sinon.

Le point de terminaison de santé ne renvoie que l’état opérationnel. Il **NE DOIT PAS** renvoyer de chemins de modèles, de prompts, de jetons d’accès ni d’autres informations sensibles.
