Skip to content

v1.32.1

Choose a tag to compare

@github-actions github-actions released this 08 Aug 12:14
· 3 commits to master since this release

Hotfix зависания rlm_start на Windows при stdio-транспорте. Контракты хелперов, стратегия, состав MCP-тулов, схема SQLite и BUILDER_VERSION (14) не тронуты — пересборка индексов не требуется. Поведение на streamable-http не меняется вовсе.

Исправлено

  • rlm_start зависал на Windows при stdio-транспорте в дефолтном режиме песочницы (#25). Было так: транспорт stdio (значение по умолчанию) ведёт протокол по дескрипторам 0 и 1 и весь сеанс держит на fd 0 висящее блокирующее чтение. Windows сериализует операции на синхронном pipe и передаёт дочернему процессу стандартные хэндлы родителя даже при bInheritHandles=FALSE — поэтому sandbox-worker, который в режиме RLM_SANDBOX_MODE=process (тоже значение по умолчанию) запускается на каждую сессию, зависал внутри инициализации интерпретатора, до первой строки собственного кода: сброс буферов на старте упирался в занятую трубу. Наблюдалось это как молчаливое зависание rlm_start до истечения RLM_SANDBOX_START_TIMEOUT_SECONDS (60 секунд по умолчанию) с последующей ошибкой; процесс-worker при этом жив, но не отвечает. Собственная отвязка stdio внутри worker не помогала: она исполняется уже после инициализации интерпретатора, до которой дело не доходило. По HTTP-транспорту воспроизвести было нельзя — там на трубах никто не висит, поэтому установки, работающие через службу (--transport streamable-http), проблему не видели. Стало: при старте с stdio протокол обслуживается с приватных дубликатов дескрипторов, а fd 0 и 1 уводятся на os.devnull и на stderr — дети наследуют отводы, а не протокольные трубы. Проверено на Python 3.10, 3.12 и 3.14: зависание воспроизводилось на всех трёх и на всех трёх устранено. Разводка обратима и best-effort — если увести дескрипторы не удалось, они возвращаются в исходное состояние, а сервер стартует как прежде; отключается RLM_STDIO_HARDENING=0 (не рекомендуется).
  • Посторонний вывод в stdout больше не попадает в поток протокола. Побочное следствие того же исправления: при stdio-транспорте протокол идёт по приватным дубликатам дескрипторов, а sys.stdout вместе с самим дескриптором 1 указывает на stderr. Поэтому любой посторонний вывод из процесса сервера — print() своего или библиотечного кода, raw-запись в дескриптор 1, вывод дочернего процесса — уходит в stderr, а не в JSON-RPC поток, где ломал бы кадрирование сообщений. Оговорка: гарантия опирается на то, что stderr и stdout ведут в разные места; если клиент запускает сервер со stderr, слитым в stdout (2>&1), отвод и есть протокольная труба — тогда посторонний вывод по-прежнему может попасть в поток (зависание при этом всё равно вылечено, его порождает сторона стандартного ввода).
  • Скрипты установки обрывались на финальном блоке, если программа что-то писала в stderr. Было так: строка с версией вызывала rlm-tools-bsl --version с перенаправлением 2>&1. В PowerShell 5.1 stderr нативной программы, уведённый в поток успеха, становится ошибкой (NativeCommandError), а при действующем в скриптах $ErrorActionPreference = "Stop" — завершающей. Достаточно было одного предупреждения любой зависимости при запуске — и установка, уже сделав всю работу и подняв службу, обрывалась на выводе версии: адрес endpoint, ссылка на health, готовый фрагмент для mcp.json и команды управления службой до пользователя не доходили, а вместо них печаталась красная трассировка. Стало: подавление stderr вынесено в cmd (cmd /c 'rlm-tools-bsl --version 2>nul'), поэтому PowerShell его не видит вовсе и никакой посторонний вывод больше не может оборвать скрипт. Правка внесена в simple-install.ps1 и simple-install-from-pip.ps1. В simple-install.sh и simple-install-from-pip.sh обрыва не было — bash так себя не ведёт, — но stderr подмешивался прямо в строку версии, поэтому там 2>&1 заменено на 2>/dev/null.

Добавлено

  • RLM_STDIO_HARDENING — выключатель разводки дескрипторов (по умолчанию включена, действует только на stdio-транспорт). Значения 0, false, no, off отключают. См. docs/ENV_REFERENCE.md.

Полный список изменений: CHANGELOG.md