Обнаружение сервисов

3.1 Способы обнаружения

Клиент обнаруживает сервис, пробуя эти способы по порядку:

  1. Ручная настройка. Пользователь вводит адрес сервиса напрямую.
  2. Проверка стандартных локальных адресов. Клиент запрашивает /.well-known/lmsp.json по адресам-кандидатам. Стандартные кандидаты — http://127.0.0.1:17832 и http://[::1]:17832.
  3. Обнаружение в локальной сети. Клиент ищет _lmsp._tcp.local. через mDNS и DNS-SD.

Способ считается успешным, если он даёт корректное описание сервиса (раздел 3.3). Адрес, введённый пользователем вручную, всегда имеет приоритет над обнаруженными.

3.2 Объявление в локальной сети

DNS-SD использует записи PTR для поиска экземпляров сервиса, записи SRV для получения хоста и порта и записи TXT для передачи небольшого объёма дополнительных сведений. Вместе с mDNS он обеспечивает обнаружение без настройки в локальной сети (RFC 6763, RFC 6762).

Пример объявления:

Service type:   _lmsp._tcp.local.
Instance name:  Workstation LMSP._lmsp._tcp.local.

TXT record:
  v=1
  id=svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2
  path=/
  auth=pairing
Ключ TXT Значение
v Версия формата объявления. 1 для LMSP 1.0.
id Идентификатор сервиса, равный service.id в описании сервиса.
path Путь URL к корню сервиса. Клиенты запрашивают {path}.well-known/lmsp.json.
auth Подсказка об аутентификации. pairing означает, что клиент должен пройти сопряжение, прежде чем пользоваться сервисом.

Правила:

  • Сервис НЕ ДОЛЖЕН помещать в запись TXT токены доступа, списки моделей, пути к файлам и любые другие чувствительные сведения. Запись лишь указывает, где находится сервис. Реальные возможности ДОЛЖНЫ считываться из описания сервиса.
  • Сервис ДОЛЖЕН по умолчанию держать объявление mDNS выключенным. Оно включается только тогда, когда пользователь явно включил обнаружение в локальной сети. Сервис, который используется только на локальной машине, ничего не объявляет.
  • Сервис, объявляющий себя в локальной сети, вынужден слушать не только loopback, а это разрешено только в режиме LAN (раздел 10.5).
  • Клиент ДОЛЖЕН считать запись TXT непроверенной подсказкой и подтверждать сервис, прочитав его описание.

3.3 Описание сервиса

GET /.well-known/lmsp.json

Сервис ДОЛЖЕН отдавать этот документ как application/json без требования аутентификации.

{
  "protocol": "lmsp",
  "versions": ["1.0"],
  "service": {
    "id": "svc_01J8M4Y8K6M5E6K6Z7Z0Y8W3M2",
    "name": "Workstation Local Models",
    "version": "1.0.0"
  },
  "interfaces": [
    {
      "kind": "lmsp",
      "version": "1.0",
      "url": "http://127.0.0.1:17832/lmsp/v1",
      "transport": "http+json"
    },
    {
      "kind": "openai",
      "version": "responses+chat",
      "url": "http://127.0.0.1:17832/v1",
      "transport": "http+json"
    }
  ],
  "capabilities": {
    "streaming": true,
    "tasks": true,
    "event_resume": true,
    "conversations": true,
    "model_management": true
  },
  "authentication": {
    "type": "bearer",
    "pairing_url": "http://127.0.0.1:17832/lmsp/v1/pair"
  },
  "openapi": "http://127.0.0.1:17832/lmsp/v1/openapi.json"
}
Поле Значение
protocol Всегда "lmsp".
versions Версии LMSP, которые поддерживает сервис, в виде строк major.minor.
service id — стабильный идентификатор сервиса, name — отображаемое имя, version — версия программного обеспечения сервиса.
interfaces Предлагаемые интерфейсы. У каждого есть kind (lmsp, openai или ollama), version, базовый url и transport. Для openai в version указаны обслуживаемые семейства API, например responses+chat.
capabilities Булевы флаги возможностей, перечисленные ниже.
authentication type — bearer. pairing_url — адрес, по которому клиенты обменивают код сопряжения на токен (раздел 10.2).
openapi URL документа OpenAPI, описывающего интерфейс LMSP.

Флаги возможностей:

Флаг Значение
streaming Ответы можно передавать потоком в виде событий, отправляемых сервером. В версии 1.0 флаг ДОЛЖЕН быть true.
tasks Доступны асинхронные задачи. В версии 1.0 флаг ДОЛЖЕН быть true.
event_resume На потоки событий задач можно подписаться и возобновить их (GET /lmsp/v1/tasks/{task_id}/events).
conversations Сервис хранит ответы, поэтому работают store и previous_response_id, а GET /lmsp/v1/responses/{response_id} доступен.
model_management Модели можно загружать и выгружать явно.

3.4 Поведение клиента

Клиент:

  • СЛЕДУЕТ выбирать наибольшую версию из versions, которую он тоже поддерживает.
  • СЛЕДУЕТ выбирать из interfaces интерфейс LMSP или интерфейс OpenAI в зависимости от того, на каком из них он умеет работать.
  • ДОЛЖЕН использовать только те возможности, которые объявлены в описании. Отсутствующий флаг означает false.
  • ДОЛЖЕН игнорировать поля расширений, которых он не знает.
  • СЛЕДУЕТ периодически перечитывать описание сервиса, а также при сбое запроса, а не кэшировать его навсегда.
  • СЛЕДУЕТ запоминать выбранный сервис по service.id, а не по адресу, потому что адреса могут меняться.