Конфигурация Cordis
Встроенный движок Cordis/DSH настраивается двумя документами и переменными окружения. По умолчанию документы находятся рядом с бэкендом; LIBRE_CORDIS_CONFIG и LIBRE_CORDIS_SETTINGS меняют их расположение.
| Документ | Владелец | Форма | Назначение |
|---|---|---|---|
cordis.patch.yml | Cordis Loader | YAML-массив верхнего уровня | Строки плагинов для загрузки движка |
cordis.config.yml | Хост Libre WebUI | YAML-отображение | Провайдер, источник ключей и флаги возможностей |
Документов два, потому что компонент Cordis Include сам читает композицию и принимает только массив верхнего уровня. Настройки хоста не могут находиться в том же файле.
Включение
Администратор включает движок в Настройки → Управление пользователями → Доступ и политики → Движок Cordis. Изменение действует сразу: включение запускает движок при следующем запросе, выключение освобождает его. Перезапуск не нужен.
Два источника уровня развёртывания могут закрепить значение. Оба блокируют переключатель, а не перезаписываются незаметно:
| Источник | Действие |
|---|---|
LIBRE_CORDIS_ENABLED переменная окружения | true/false закрепляет функцию для развёртывания |
features.enabled в cordis.config.yml | Явное значение закрепляет выбор; без ключа решает администратор |
Движку также нужна композиция. Начните с поставляемых примеров:
cd backend
cp cordis.patch.example.yml cordis.patch.yml
cp cordis.config.example.yml cordis.config.yml
Хост читает cordis.patch.yml, объединяет свои значения по умолчанию со строкой моста и записывает <DATA_DIR>/cordis-runtime/cordis.composed.yml. Этот генерируемый файл можно восстановить и нельзя редактировать; источник истины — cordis.patch.yml оператора.
cordis.config.yml
trace: false
model:
provider: libre-webui
# Empty selects the authenticated caller's configured default/fallback route.
model: ''
features:
# Omit enabled to let the administrator use the Settings toggle.
streaming: true
tools: true
persistence: true
# Optional absolute paths; defaults live under Libre WebUI's data directory.
# workspacePath: /absolute/path/to/workspace
# sessionStorePath: /absolute/path/to/sessions
Ключи верхнего уровня
| Ключ | Тип | По умолчанию | Значение |
|---|---|---|---|
trace | логический | false | Журналировать все переходы активации Cordis |
model | отображение | – | Выбор адаптера модели; см. ниже |
features | отображение | – | Переключатели возможностей; см. ниже |
features
| Ключ | Тип | По умолчанию | Значение |
|---|---|---|---|
enabled | логический | false | Загрузить движок; при отключении все маршруты отвечают 503. |
streaming | логический | true | Принимать ходы с потоковым ответом модели |
tools | логический | true | Разрешить инструменты движка и показать их реестр |
persistence | логический | true | Включить и потребовать хранение JSONL; сеансы переживают рестарт |
features.enabled — единственный переключатель, необходимый для включения моста. Ключ enabled верхнего уровня не читается: все переключатели находятся в features, чтобы состояние функций проверялось в одном месте.
model
| Ключ | Тип | По умолчанию | Значение |
|---|---|---|---|
provider | строка | libre-webui | libre-webui, deepseek, pi-ai или none |
apiKeyEnv | строка | OPENAI_API_KEY | Имя переменной окружения с ключом |
route | строка | libre-webui | Маршрут провайдера, используемый движком |
model | строка | '' | ID запрашиваемой модели. Задайте для ручного маршрута |
baseUrl | строка | '' | Переопределение адреса; пусто означает стандарт адаптера |
providers | отображение | {} | Маршруты провайдеров, заданные вручную по именам |
Откуда берутся модели движка
У движка нет отдельной конфигурации провайдеров. Он вызывает уже настроенных провайдеров Libre WebUI по маршруту libre-webui, зарегистрированному строкой libre-webui-llm-adapter. Доступны те же модели, что для чата в интерфейсе: загрузите модель там, и движок увидит её с готовыми ключами и адресом.
Установите model.provider: libre-webui, поставляемое значение по умолчанию. Учётные данные и адреса остаются в существующих настройках Libre WebUI.
model задаёт запрашиваемую модель. Пусто означает стандарт приложения; без него выбирается первая чат-модель, сообщённая слоем провайдеров, с предпочтением доступных локальных моделей. Embedding-модели исключены. Внутренние маршруты сохраняют модель и провайдера: lwui:ollama:<encoded-model> или lwui:plugin:<encoded-provider>:<encoded-model>. Совпадение имён или сбой Ollama поэтому не перенаправляет локальный запрос удалённому провайдеру. Явно выбранный недоступный провайдер даёт ошибку, не скрытую замену.
Пустой model безопасен только для libre-webui. Маршруту пакета провайдера нужна явная модель: dsh-llm-pi-ai разрешает каталог для запросов каталога, но не выбирает первую запись как запасную. Ручной маршрут без model не принимает ход и сообщает:
provider "<route>" resolves no models; the installed catalog does not describe
this route, so its models must be listed in configuration
Задайте model из списка models этого маршрута. Пример сочетает route: ollama с model: llama3.2, соответствуя объявленной записи llama3.2.
provider выбирает загружаемый пакет адаптера:
libre-webuiиспользует слой провайдеров данного развёртывания; это поддерживаемый стандарт.noneзапускает без доступа к модели. Инструменты перечисляются, сеансы работают, но ответить на ход нельзя; полезно для проверки композиции.deepseekиpi-aiнапрямую загружают пакет провайдера. Они не являются зависимостями бэкенда: включение всех SDK добавляло 59 транзитивных пакетов, в том числе устаревших, ради неиспользуемых возможностей. Установите нужный пакет и его строку; хост укажет отсутствующий пакет.
Маршрут описывается полями:
| Поле | Значение |
|---|---|
displayName | Понятное имя |
api | Протокол обмена, например openai-completions |
baseURL | Базовый адрес конечной точки |
apiKeyEnv | Переменная окружения с ключом |
models | Список моделей; поля записи: id, name, contextWindow, maxTokens |
Учётные данные никогда не записываются в эти документы. apiKeyEnv называет переменную окружения, которую адаптер разрешает на каждый запрос; ротация ключа не требует перезапуска.
cordis.patch.yml
Массив записей Loader верхнего уровня. Поставляемый пример загружает девять строк и рекомендуется как отправная точка.
- id: llm
name: '@deepseek-ai/dsh-llm'
- id: session
name: '@deepseek-ai/dsh-session'
- id: session-projection
name: '@deepseek-ai/dsh-session-projection'
- id: session-persistence
name: '@deepseek-ai/dsh-session-persistence-jsonl'
config:
# The host supplies the resolved sessionStorePath.
- id: system-prompt
name: '@deepseek-ai/dsh-system-prompt'
config:
personaPrefix: ''
- id: tools
name: '@deepseek-ai/dsh-tools'
- id: agent
name: '@deepseek-ai/dsh-agent'
- id: agent-loop
name: '@deepseek-ai/dsh-agent-loop'
config:
agents: []
- id: libre-webui-bridge
name: './dist/cordis/dsh/engine-plugin.js'
Поля записи
| Поле | Обязательное | Значение |
|---|---|---|
id | нет | Стабильный ID строки; без него используется name |
name | да | Спецификатор модуля Loader; требуется строковый литерал |
config | нет | Конфигурация плагина; допустимы выражения !!js |
disabled | нет | Пропуск строки без удаления; допустимо !!js |
inject | нет | Дополнительные зависимости или конфигурация перехвата строки |
Loader напрямую импортирует name, не вычисляя его; выражение !!js недопустимо. Значения config могут использовать !!js: они вычисляются позже в fiber строки с доступным контекстом Loader. process.env и ctx.get(...) работают, import.meta — нет.
Относительные спецификаторы разрешаются от каталога самого файла композиции. Имена пакетов — через пакет бэкенда, поэтому @deepseek-ai/dsh-tools найдёт копию в backend/node_modules.
Порядок строк не определяет загрузку. Cordis активирует строку при наличии её сервисов; приведённая группировка нужна только читателю.
Обязательные строки
Движку, отвечающему на чат, нужны все перечисленные элементы:
| Строка | Предоставляет | Требуется для |
|---|---|---|
dsh-llm | llm | цикл агента |
dsh-session | sessions | цикл агента, мост |
dsh-session-projection | sessionProjections | цикл агента |
dsh-system-prompt | systemPrompt | инструменты, цикл агента |
dsh-tools | tools | цикл агента, мост |
dsh-agent | agents | мост |
dsh-agent-loop | драйвер агента | ответы на ходы |
| строка моста | libreDshEngine | все маршруты |
Чтобы GET /api/cordis/tools что-то возвращал, добавьте плагин инструментов, например @deepseek-ai/dsh-fs-sandbox вместе с @deepseek-ai/dsh-tool-fs. Реестр без плагинов инструментов закономерно пуст.
Переменные окружения
Каждую настройку можно переопределить окружением. Переменная имеет приоритет перед документом, а документ — перед встроенным значением.
| Переменная | Переопределяет | По умолчанию |
|---|---|---|
LIBRE_CORDIS_ENABLED | features.enabled | false |
LIBRE_CORDIS_STREAMING | features.streaming | true |
LIBRE_CORDIS_TOOLS | features.tools | true |
LIBRE_CORDIS_PERSISTENCE | features.persistence | true |
LIBRE_CORDIS_TRACE | trace | false |
LIBRE_CORDIS_MODEL_PROVIDER | model.provider | libre-webui |
LIBRE_CORDIS_MODEL_ROUTE | model.route | libre-webui |
LIBRE_CORDIS_MODEL | model.model | '' |
LIBRE_CORDIS_API_KEY_ENV | model.apiKeyEnv | OPENAI_API_KEY |
LIBRE_CORDIS_BASE_URL | model.baseUrl | '' |
LIBRE_CORDIS_CONFIG | Путь документа композиции | <cwd>/cordis.patch.yml |
LIBRE_CORDIS_SETTINGS | Путь документа настроек | рядом с документом композиции |
LIBRE_CORDIS_WORKSPACE | Рабочая область движка по умолчанию | <DATA_DIR>/cordis-workspace |
LIBRE_CORDIS_SESSION_STORE | Каталог сохранённых сеансов | <DATA_DIR>/cordis-sessions |
Логические переменные принимают 1/true/yes/on и 0/false/no/off. Непонятное значение возвращает выбор документу, а не угадывается.
Выражения !!js поставляемой композиции также читают LIBRE_CORDIS_SESSION_STORE и LIBRE_CORDIS_WORKSPACE; поэтому хост экспортирует их до загрузки дерева.
Рабочие примеры
Локальная Ollama, полностью автономно
features:
enabled: true
model:
provider: pi-ai
route: ollama
model: llama3.2
apiKeyEnv: OLLAMA_API_KEY
providers:
ollama:
api: openai-completions
baseURL: http://127.0.0.1:11434/v1
apiKeyEnv: OLLAMA_API_KEY
models:
- id: llama3.2
contextWindow: 131072
maxTokens: 4096
Ollama игнорирует ключ, но клиент OpenAI требует его наличия. Экспортируйте OLLAMA_API_KEY=ollama, не создавая вымышленный секрет. Ничто не покидает машину.
OpenAI-совместимый шлюз
features:
enabled: true
model:
provider: pi-ai
route: gateway
model: acme-large
apiKeyEnv: ACME_GATEWAY_API_KEY
providers:
gateway:
displayName: Acme Gateway
api: openai-completions
baseURL: https://gateway.acme.example/v1
apiKeyEnv: ACME_GATEWAY_API_KEY
models:
- id: acme-large
contextWindow: 65536
maxTokens: 4096
Официальный DeepSeek
features:
enabled: true
model:
provider: deepseek
route: deepseek
apiKeyEnv: DEEPSEEK_API_KEY
Задайте DEEPSEEK_API_KEY в окружении бэкенда.
Без провайдера, только инструменты
features:
enabled: true
model:
provider: none
Движок запускается, сеансы создаются, GET /api/cordis/tools показывает настроенные плагины. Отправка сообщения завершается ошибкой, поскольку адаптера для запроса нет.
Замечания о миграции
Мост добавляет возможности. В выключенном состоянии, которое действует по умолчанию, существующее поведение не меняется.
Обновление существующей установки. Ничего делать не нужно. Примеры cordis.patch.example.yml и cordis.config.example.yml не используются до копирования и включения функции. Миграции не запускаются, таблицы не создаются, существующие каталоги данных не затрагиваются.
Первое включение. Скопируйте оба примера, задайте features.enabled: true. Дополнительная установка не нужна: пакеты движка уже зависимости бэкенда. Первый запрос создаёт <DATA_DIR>/cordis-workspace, <DATA_DIR>/cordis-sessions и <DATA_DIR>/cordis-runtime. Это новые каталоги под существующим каталогом данных; его резервная копия и восстановление охватывают и их.
Обновление движка. Точные версии указаны в package-lock.json, а backend/package.json задаёт alpha-совместимые диапазоны. Обновляйте осознанно и после npm install проверяйте контракты провайдеров и сеансов. Новые peer-зависимости npm сообщит при установке, а не загрузке. DSH владеет форматами моделей и сеансов: смена формата относится к примечаниям DSH, не к миграциям Libre WebUI.
Откат. Установите features.enabled: false и перезапустите либо удалите строку моста из cordis.patch.yml. Сервис libreDshEngine будет отозван, обработчик освобождён, агенты уничтожены. Сеансы остаются данными на диске; удалите sessionStorePath для освобождения места. Удаление пакетов необязательно и не влияет на другие функции.
Существующие Чат и Work. Чат получает выбор DSH только для администратора, с временными сеансами и текущей историей Чата. Work получает отдельный движок DSH с изолированным драйвером и прежним потоком согласований/песочницы. Старые выборы моделей сохраняют обычное поведение.
Со стандартным libre-webui селектор Агентов Чата содержит конкретные пары DSH-провайдер/модель и базовый профиль. Явные варианты сохраняют квалифицированную идентичность, базовый использует модель текущей композиции. Заголовки и итоги размышлений напрямую обращаются к провайдеру без инструментов агента. Собственный маршрут адаптера оставляет только базовую запись и требует отдельную модель задач Ollama или плагина для этих функций.
DSH соблюдает настройку Ollama администратора. При отключении её модели не перечисляются и не опрашиваются; явный выбор Ollama завершается ошибкой без смены провайдера. Неквалифицированным именам оператора тоже нужен каталог Ollama для безопасного разрешения. В установке только с плагинами используйте lwui:plugin:<plugin>:<model>.
Эксплуатационные границы
- Движок хоста и Чат — только для администраторов и solo. Страница Движка является общей консолью с локальным JSONL; в team её загрузка запрещена. Work использует существующие SQL-репозитории.
- Модель вызывается от аутентифицированного пользователя. Интерактивные ходы используют ключи и модель по умолчанию этого администратора. Доверенная неинтерактивная композиция может явно задать
LIBRE_CORDIS_USERкак ID активного администратора. Скрытого выбора самого старого администратора нет. - Файловые инструменты хоста ограничены рабочей областью. Чтение и запись проверяют канонический путь; рабочий каталог сеанса не может быть вне корня. Ограничения изменений DSH сохраняются. Дополнительные плагины оператора — доверенный серверный код.
- Инструменты хоста используют политики DSH. Страница Движка предоставляет режимы чтения/записи и одноразовые нативные согласия, не обходящие границу. Headless-Чат отвергает вопросы, которые не может показать. Work использует собственные согласования и контейнеры без файловых инструментов хоста.
- Потоки содержат живой текст и доступные рассуждения. Сохранённые сообщения удерживают завершённую историю; клиент не получает вторую копию текста.
- Перезапуск и удаление используют сохранённые сеансы. Пустые и завершённые сеансы переживают рестарт. Удаление сеанса JSONL моста останавливает запись и убирает файл; другие хранилища должны предоставлять подходящий адаптер удаления.
- Старые неверные логи требуют явного ремонта. Прежние версии писали сообщения без ID. Строгий читатель отвергает такие логи, а не отбрасывает их. См. процедуру в Устранении неполадок.
- Заголовки выводятся локально. Первое человеческое сообщение становится коротким заголовком; у пустых сеансов производного заголовка нет.
Подключение моделей работающей инстанции DSH
Необязательный плагин dsh-native-provider открывает модели и подключения, уже настроенные в другой инстанции DSH, например локальном веб-приложении на порте 3080. Установите его в существующий профиль. Вызывается только ctx.llm: ключи остаются в DSH; соединение не создаёт сеансы, не запускает агентов или нативные инструменты и не читает нативные вложения.
Оба процесса должны работать на одном Unix-хосте под одной учётной записью ОС. Явно настроенный Unix-сокет использует физический каталог этой учётной записи с режимом 0700 и сокет 0600. TCP-слушатель не добавляется, браузерная аутентификация DSH не используется повторно и не ослабляется. Windows и удалённые DSH-хосты не поддерживаются.
Локальная граница доступа — учётная запись ОС: её другие процессы могут обращаться к сокету. Отдельных нативных ключей или изоляции приложений этой учётной записи соединение не предоставляет.
Установка отдельного плагина
В DSH → Plugins → Add plugin вставьте публичный адрес репозитория в Package name or address и нажмите Install:
https://github.com/libre-webui/dsh-native-provider
Включите компонент по запросу DSH. Публичный пакет 0.1.1 под Apache-2.0 содержит готовую среду и patch bundle. Локальная сборка, установочные скрипты и runtime-зависимости npm не нужны. Имя @libre-webui/dsh-native-provider не опубликовано в npm; используйте GitHub-URL.
Bundle выбирает <DSH home>/lwui-provider/llm.sock, обычно $HOME/.dsh/lwui-provider/llm.sock; заданный DSH_HOME имеет приоритет. Закрытый каталог создаётся, если отсутствует. Используйте один активный мост на DSH home либо переопределите путь в пользовательском cordis.patch.yml дополнительных профилей. Полный путь должен занимать не более 100 байт UTF-8 и не содержать символьных ссылок. Переопределения описаны в отдельном руководстве пакета.
Необязательный вариант CLI:
dsh plugin --profile web add https://github.com/libre-webui/dsh-native-provider
Замените web на реально работающий профиль. После CLI-установки перезапустите профиль; установка через действующий интерфейс может сразу включить плагин. Следуйте сообщениям DSH о перезапуске. Изменение исходников DSH и копирование ключей не нужны.
Подготовка bundle из Libre WebUI
Libre WebUI также поставляет скрипт подготовки. В checkout исходников соберите бэкенд и создайте новый выходной каталог:
npm run build:backend
node scripts/prepare-dsh-provider.mjs /absolute/dsh-provider-bundle /absolute/private-directory/provider.sock
dsh plugin --profile web add /absolute/dsh-provider-bundle
Npm-дистрибутивы уже содержат собранный бэкенд и скрипт; выполните последние две команды из каталога установки без сборки. Затем перезапустите выбранный профиль DSH. Оба способа подготовки отвергают существующие каталоги и включают метаданные, лицензию и примечания по установке.
Подключение Libre WebUI
Направьте cordis.config.yml на тот же абсолютный путь сокета. Для публичного стандарта замените /absolute/home своим реальным домашним каталогом:
nativeProvider:
socketPath: /absolute/home/.dsh/lwui-provider/llm.sock
Можно также задать LIBRE_DSH_PROVIDER_SOCKET как этот абсолютный путь. Пустая переменная выключает соединение, даже если путь есть в файле. Включите Движок Cordis в LWUI. Активные администраторы смогут выбрать нативные модели в движке DeepSeek Harness Work, на странице Движка и в группе Агентов Чата; Чату дополнительно нужны Модели агентов CLI. Work сохраняет исходную модель и ID провайдера с providerType: dsh; существующие задачи через LWUI сохраняют прежнюю идентичность и маркер движка.
Каталог читается в реальном времени. Смена провайдера или учётных данных меняет поколение соединения и отменяет активные вызовы. Недоступный сокет, модель или провайдер останавливает запрос; перехода на Ollama или другого провайдера нет. Заголовки и итоги напрямую вызывают выбранный LLM без инструментов. Эта первая версия принимает текст, рассуждения и сообщения инструментов; нативные ссылки на изображения и файлы отвергаются.
Ключи принадлежат оператору DSH, поэтому соединение доступно лишь администраторам, даже если Work доступен шире. Запросы могут покидать хост согласно настройкам DSH; Work показывает уведомление об удалённом провайдере. В team каждый обслуживающий такие задачи воркер должен иметь доступ к локальному соединению; отсутствие доступа запрещает выполнение. Отключение Cordis или удаление настройки сокета отзывает нативный доступ, сохраняя задачи. Если после аварии DSH остаётся сокет, остановите владеющую инстанцию и удалите только устаревший сокет перед рестартом; плагин не заменяет существующие записи файловой системы.
Обновление или удаление плагина
Завершите или отмените активные запросы до изменения. Для замены старого локального bundle 0.0.0/0.1.0 в DSH выберите Uninstall, вернитесь в Add plugin и установите указанный GitHub-URL. Сохраните особый путь сокета через поддерживаемое переопределение пользовательского профиля. Нативные сеансы и ключи сохраняются.
Установку из GitHub можно обновить через CLI:
dsh plugin --profile web update @libre-webui/dsh-native-provider
После CLI-обновления перезапустите и проверьте версию. Выключенный плагин остаётся выключенным; проверьте его перед тестом связи. Для закрепления или отката используйте github:libre-webui/dsh-native-provider#<commit>. Для собственных локальных bundle создайте новый каталог и добавьте его заново: обновление локальной зависимости не загружает GitHub.
Чтобы удалить соединение, сначала уберите nativeProvider.socketPath в LWUI либо оставьте LIBRE_DSH_PROVIDER_SOCKET пустым, затем выполните:
dsh plugin --profile web remove @libre-webui/dsh-native-provider
Перезапустите профиль DSH. Задачи LWUI сохраняются, но нативные запросы не работают до восстановления того же явного соединения. Удаление плагина не удаляет провайдеров и ключи DSH. Старые каталоги bundle удаляйте только после прекращения их использования установленным плагином.
Использование нативного провайдера
Нативные запросы показываются в Использование провайдера под DeepSeek Harness · provider, с исходным именем выбранной модели. Каждая реальная модельная заявка учитывается один раз, включая раунды инструментов, заголовки и итоги размышлений. Панель показывает успехи, ошибки, отмены, задержку и сообщённые DSH токены. Кешированный ввод учитывается однократно; неизвестное использование остаётся неизмеренным, без оценок. ID dsh-native:<percent-encoded-native-provider-id> использует существующие правила тарифов и затрат. Неизвестная стоимость остаётся неоценённой.
DSH через провайдеров LWUI сохраняет их существующие записи. Чтение каталога и отклонённые до инференса запросы не создают дополнительных вызовов. Учёт начинается при установке этой версии соединения; история не выдумывается. Записываются идентичность, статус, время и счётчики, без промптов, ответов, ключей, адресов и текста ошибок провайдера.
Проверка конфигурации
curl -s http://127.0.0.1:3001/api/cordis/health | jq
{
"success": true,
"enabled": true,
"ready": true,
"services": [
{ "name": "llm", "state": "ready" },
{ "name": "systemPrompt", "state": "ready" },
{ "name": "sessions", "state": "ready" },
{ "name": "tools", "state": "ready" },
{ "name": "agents", "state": "ready" }
]
}
503 с code: CORDIS_UNAVAILABLE означает, что композиция не загрузилась. Поле error содержит причину, а LIBRE_CORDIS_TRACE=true добавляет журнал активации. Частые причины приведены в Устранении неполадок.