Общие правила

9.1 Версии и расширения

Каждый запрос LMSP МОЖЕТ нести эти заголовки:

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

LMSP-Version — версия протокола, на которую рассчитан клиент. LMSP-Client обозначает клиентскую программу для диагностики в виде name/version. Сервис НЕ ДОЛЖЕН менять поведение протокола в зависимости от этого заголовка.

Правила:

  • v1 в пути обозначает основную версию.
  • Запрос, в котором указана неизвестная основная версия, получает ответ 426 Upgrade Required с кодом ошибки unsupported_protocol_version.
  • Новые необязательные поля НЕ ДОЛЖНЫ нарушать совместимость 1.x.
  • Сервисы и клиенты ДОЛЖНЫ игнорировать неизвестные им поля.
  • Частные расширения помещаются в объект extensions и именуются в обратной доменной записи:
{
  "extensions": {
    "com.example.cache": {
      "enabled": true
    }
  }
}

9.2 Идемпотентность

Запросы, которые что-то создают, например создание ответа, создание задачи или загрузка модели, принимают ключ идемпотентности:

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

Сервис сохраняет ключ вместе с дайджестом тела запроса и результатом:

  • Тот же ключ с тем же телом возвращает исходный результат.
  • Тот же ключ с другим телом получает ответ 409 Conflict с кодом idempotency_conflict.

Ключ действует в пределах клиента и эндпоинта. Ключ СЛЕДУЕТ делать уникальным значением длиной не более 255 символов, например ULID или UUID. Сервису СЛЕДУЕТ хранить ключи не менее 24 часов.

Сервис МОЖЕТ игнорировать ключ в потоковых запросах. Клиент, которому нужны безопасные повторы, использует задачу.

9.3 Ошибки

Каждая ошибка интерфейса LMSP использует application/problem+json (RFC 9457):

{
  "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
}
Поле Обязательное Значение
type Да URI, обозначающий вид ошибки. LMSP использует urn:lmsp:error:, за которым следует код с дефисами вместо подчёркиваний.
title Да Краткое описание, понятное человеку.
status Да Код состояния HTTP.
code Да Машиночитаемый код ошибки из списка ниже.
detail Нет Понятное человеку пояснение к данному случаю. Сервис НЕ ДОЛЖЕН помещать в него секреты, промпты или сгенерированное содержимое.
request_id Нет Идентификатор запроса для сопоставления с журналами сервиса.
retryable Да Может ли повторный запрос позже завершиться успехом.

Типичные коды ошибок:

Код HTTP-статус Можно повторить Значение
invalid_request 400 Нет Запрос искажён или содержит недопустимые параметры.
unauthorized 401 Нет Токен отсутствует, недействителен, просрочен или отозван, либо неверен код сопряжения.
forbidden 403 Нет У токена нет нужной области доступа, либо не пройдена проверка Origin или Host.
model_not_found 404 Нет Ни у одной локальной модели нет такого идентификатора.
model_not_ready 409 Да Модель не загружена и не загружается по требованию.
model_load_failed 500 Да Не удалось загрузить модель.
context_length_exceeded 400 Нет Ввод не помещается в контекстное окно модели.
unsupported_capability 400 или 501 Нет Модель или сервис не поддерживают то, что нужно запросу. Нереализованный необязательный эндпоинт отвечает 501.
unsupported_protocol_version 426 Нет Сервис не поддерживает запрошенную основную версию.
response_not_found 404 Нет Ни у одного сохранённого ответа нет такого идентификатора.
task_not_found 404 Нет Ни у одной задачи нет такого идентификатора.
task_not_cancelable 409 Нет Задача уже завершилась успешно или с ошибкой.
idempotency_conflict 409 Нет Ключ идемпотентности уже использован с другим телом запроса.
event_history_expired 410 Нет Запрошенные события старше срока хранения.
rate_limited 429 Да Слишком много запросов.
resource_exhausted 503 Да На устройстве закончилась память или другой ресурс.
backend_unavailable 503 Да Среда выполнения модели недоступна.
server_restarted 503 Да Сервис перезапустился, пока задача была не завершена.
internal_error 500 По-разному Неожиданный сбой внутри сервиса.

Поле retryable является определяющим. В столбце выше показано обычное значение. Сервис МОЖЕТ определять дополнительные коды. Клиент ДОЛЖЕН обрабатывать неизвестный ему код по его HTTP-статусу и полю retryable.

9.4 Проверка работоспособности

GET /lmsp/v1/health
{
  "status": "ready",
  "service_id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
  "uptime_seconds": 86420,
  "loaded_models": 1,
  "active_tasks": 2,
  "storage": "ok"
}
Поле Значение
status starting, ready, degraded или stopping.
service_id Идентификатор сервиса из описания сервиса.
uptime_seconds Секунды с момента запуска сервиса.
loaded_models Число моделей в состоянии ready.
active_tasks Число задач в состоянии queued, loading, running или cancelling.
storage ok или error.

Статус HTTP — 200 OK, когда status равен ready или degraded, и 503 Service Unavailable в остальных случаях.

Эндпоинт проверки возвращает только рабочее состояние. Он НЕ ДОЛЖЕН возвращать пути к моделям, промпты, токены доступа и другие чувствительные сведения.