Перейти к основному содержимому

Конфигурация Cordis

Встроенный движок Cordis/DSH настраивается двумя документами и переменными окружения. По умолчанию документы находятся рядом с бэкендом; LIBRE_CORDIS_CONFIG и LIBRE_CORDIS_SETTINGS меняют их расположение.

ДокументВладелецФормаНазначение
cordis.patch.ymlCordis LoaderYAML-массив верхнего уровняСтроки плагинов для загрузки движка
cordis.config.ymlХост Libre WebUIYAML-отображениеПровайдер, источник ключей и флаги возможностей

Документов два, потому что компонент Cordis Include сам читает композицию и принимает только массив верхнего уровня. Настройки хоста не могут находиться в том же файле.

Включение

Переключатель Движок Cordis в Настройках рядом с переключателем Агентов.

Администратор включает движок в Настройки → Управление пользователями → Доступ и политики → Движок 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-webuilibre-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-llmllmцикл агента
dsh-sessionsessionsцикл агента, мост
dsh-session-projectionsessionProjectionsцикл агента
dsh-system-promptsystemPromptинструменты, цикл агента
dsh-toolstoolsцикл агента, мост
dsh-agentagentsмост
dsh-agent-loopдрайвер агентаответы на ходы
строка мостаlibreDshEngineвсе маршруты

Чтобы GET /api/cordis/tools что-то возвращал, добавьте плагин инструментов, например @deepseek-ai/dsh-fs-sandbox вместе с @deepseek-ai/dsh-tool-fs. Реестр без плагинов инструментов закономерно пуст.

Переменные окружения

Каждую настройку можно переопределить окружением. Переменная имеет приоритет перед документом, а документ — перед встроенным значением.

ПеременнаяПереопределяетПо умолчанию
LIBRE_CORDIS_ENABLEDfeatures.enabledfalse
LIBRE_CORDIS_STREAMINGfeatures.streamingtrue
LIBRE_CORDIS_TOOLSfeatures.toolstrue
LIBRE_CORDIS_PERSISTENCEfeatures.persistencetrue
LIBRE_CORDIS_TRACEtracefalse
LIBRE_CORDIS_MODEL_PROVIDERmodel.providerlibre-webui
LIBRE_CORDIS_MODEL_ROUTEmodel.routelibre-webui
LIBRE_CORDIS_MODELmodel.model''
LIBRE_CORDIS_API_KEY_ENVmodel.apiKeyEnvOPENAI_API_KEY
LIBRE_CORDIS_BASE_URLmodel.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 добавляет журнал активации. Частые причины приведены в Устранении неполадок.