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

⛑️ События: Использование __event_emitter__ и __event_call__ в Open WebUI

Плагинная архитектура Open WebUI — это не просто обработка входных данных и выдача выходных. Она о реальном времени, интерактивной коммуникации с интерфейсом и пользователями. Чтобы сделать ваши инструменты, функции и каналы более динамичными, Open WebUI предоставляет встроенную систему событий через вспомогательные функции __event_emitter__ и __event_call__.

Это руководство объясняет что такое события, как вы можете их инициировать из своего кода, а также позволяет ознакомиться с полным каталогом типов событий, которые вы можете использовать (включая намного больше, чем просто "input").


🌊 Что такое события?

События — это уведомления в реальном времени или интерактивные запросы, отправляемые от вашего бекенда (инструмента или функции) к веб-интерфейсу. Они позволяют обновлять чат, отображать уведомления, запрашивать подтверждения, запускать UI-потоки и многое другое.

  • События отправляются с помощью вспомогательной функции __event_emitter__ для однонаправленных обновлений или через __event_call__, когда требуется ввод пользователя или ответ (например, подтверждение, ввод и т. д.).

Метафора: Представьте события как push-уведомления и модальные диалоги, которые ваш плагин может инициировать, делая взаимодействие с чатом более богатым и интерактивным.


🧰 Базовое использование

Отправка события

Вы можете инициировать событие в любом месте внутри своего инструмента или функции, вызвав:

await __event_emitter__(
{
"type": "status", # Смотрите список типов событий ниже
"data": {
"description": "Процесс начался!",
"done": False,
"hidden": False,
},
}
)

Вам не нужно вручную добавлять поля, такие как chat_id или message_id — Open WebUI автоматически обрабатывает их.

Интерактивные события

Когда необходимо приостановить выполнение до получения ответа от пользователя (например, диалоги подтверждения/отмены, выполнение кода или ввод), используйте __event_call__:

result = await __event_call__(
{
"type": "input", # Или "confirmation", "execute"
"data": {
"title": "Введите ваш пароль",
"message": "Пароль требуется для выполнения данного действия",
"placeholder": "Ваш пароль здесь",
},
}
)
# result будет содержать значение, введенное пользователем

📜 Структура полезной нагрузки события

Когда вы инициируете или вызываете событие, базовая структура выглядит так:

{
"type": "event_type", // См. полный список ниже
"data": { ... } // Полезная нагрузка, специфичная для события
}

В большинстве случаев вам нужно указать только "type" и "data". Open WebUI автоматически добавляет всю маршрутизацию.


🗂 Полный список типов событий

Ниже представлен полный список всех поддерживаемых значений type для событий, вместе с их предполагаемым эффектом и структурой данных. (Это основано на актуальном анализе логики обработки событий Open WebUI.)

typeКогда использоватьСтруктура полезной нагрузки (примеры)
statusПоказать обновление статуса/истории сообщения{description: ..., done: bool, hidden: bool}
chat:completionПредоставить результат завершения чата(Кастомная, см. внутренности Open WebUI)
chat:message:delta,
message
Добавить содержимое к текущему сообщению{content: "текст для добавления"}
chat:message,
replace
Полностью заменить содержимое текущего сообщения{content: "текст замены"}
chat:message:files,
files
Установить или перезаписать файлы сообщений (для загрузок, вывода){files: [...]}
chat:titleУстановить (или обновить) заголовок диалогаСтрока темы или {title: ...}
chat:tagsОбновить набор тегов для чатаМассив тегов или объект
source,
citation
Добавить источник/ссылку или результат выполнения кодаДля кода: См. ниже.
notificationПоказать уведомление ("всплывающее сообщение") в UI{type: "info" или "success" или "error" или "warning", content: "..."}
confirmation
(требует __event_call__)
Запросить подтверждение (диалог OK/Cancel){title: "...", message: "..."}
input
(требует __event_call__)
Запросить ввод пользователя (диалог "ввода данных"){title: "...", message: "...", placeholder: "...", value: ...}
execute
(требуется __event_call__)
Запрос выполнения кода на стороне пользователя и возврат результата{code: "...javascript code..."}

Другие/расширенные типы:

  • Вы можете определить свои собственные типы и обработать их на уровне пользовательского интерфейса (или использовать предстоящие механизмы расширения событий).

❗ Подробности о конкретных типах событий

status

Отображение статуса/обновления прогресса в пользовательском интерфейсе:

await __event_emitter__(
{
"type": "status",
"data": {
"description": "Шаг 1/3: Получение данных...",
"done": False,
"hidden": False,
},
}
)

chat:message:delta или message

Потоковая передача данных (добавление текста):

await __event_emitter__(
{
"type": "chat:message:delta", # или просто "message"
"data": {
"content": "Частичный текст, "
},
}
)

# Позже, когда вы сгенерируете больше:
await __event_emitter__(
{
"type": "chat:message:delta",
"data": {
"content": "следующая часть ответа."
},
}
)

chat:message или replace

Задать (или заменить) содержимое всего сообщения:

await __event_emitter__(
{
"type": "chat:message", # или "replace"
"data": {
"content": "Окончательный, полный ответ."
},
}
)

files или chat:message:files

Прикрепить или обновить файлы:

await __event_emitter__(
{
"type": "files", # или "chat:message:files"
"data": {
"files": [
# Объекты файлов WebUI
]
},
}
)

chat:title

Обновить заголовок чата:

await __event_emitter__(
{
"type": "chat:title",
"data": {
"title": "Сессия бота анализа рынка"
},
}
)

chat:tags

Обновить теги чата:

await __event_emitter__(
{
"type": "chat:tags",
"data": {
"tags": ["финансы", "ИИ", "ежедневный отчет"]
},
}
)

source или citation (и выполнение кода)

Добавить ссылку/начало цитаты:

await __event_emitter__(
{
"type": "source", # или "citation"
"data": {
# Объект источника или цитаты WebUI
}
}
)

Для выполнения кода (отслеживание состояния выполнения):

await __event_emitter__(
{
"type": "source",
"data": {
# Объект источника выполнения кода WebUI
}
}
)

notification

Показать уведомление-тост:

await __event_emitter__(
{
"type": "notification",
"data": {
"type": "info", # "success", "warning", "error"
"content": "Операция успешно завершена!"
}
}
)

confirmation (требуется __event_call__)

Показать диалог подтверждения и получить ответ от пользователя:

result = await __event_call__(
{
"type": "confirmation",
"data": {
"title": "Вы уверены?",
"message": "Вы действительно хотите продолжить?"
}
}
)

if result: # или проверить содержимое результата
await __event_emitter__({
"type": "notification",
"data": {"type": "success", "content": "Пользователь подтвердил операцию."}
})
else:
await __event_emitter__({
"type": "notification",
"data": {"type": "warning", "content": "Пользователь отменил."}
})

input (требуется __event_call__)

Запрос текста от пользователя:

result = await __event_call__(
{
"type": "input",
"data": {
"title": "Введите ваше имя",
"message": "Нам нужно ваше имя для продолжения.",
"placeholder": "Ваше полное имя"
}
}
)

user_input = result
await __event_emitter__(
{
"type": "notification",
"data": {"type": "info", "content": f"Вы ввели: {user_input}"}
}
)

execute (требуется __event_call__)

Выполнение кода динамически на стороне пользователя:

result = await __event_call__(
{
"type": "execute",
"data": {
"code": "print(40 + 2);",
}
}
)

await __event_emitter__(
{
"type": "notification",
"data": {
"type": "info",
"content": f"Код выполнен, результат: {result}"
}
}
)

🏗️ Когда и где использовать события

  • Из любого инструмента или функции в Open WebUI.
  • Для потоковой передачи ответов, отображения прогресса, запросов данных пользователя, обновления пользовательского интерфейса или показа дополнительной информации/файлов.
  • await __event_emitter__ используется для односторонней передачи сообщений (только отправка).
  • await __event_call__ используется, когда требуется ответ от пользователя (ввод, выполнение, подтверждение).

💡 Советы и дополнительные заметки

  • Несколько типов на одно сообщение: Вы можете отправить несколько событий разных типов для одного сообщения — например, показать обновления status, затем вести потоковую передачу с chat:message:delta, а затем завершить с помощью chat:message.
  • Пользовательские типы событий: Хотя приведенный выше список является стандартным, вы можете использовать свои собственные типы и обрабатывать их в пользовательском интерфейсе.
  • Расширяемость: Система событий разработана с возможностью эволюции — всегда проверяйте документацию Open WebUI для получения актуального списка и передовых возможностей.

🧐 FAQ

В: Как отправить уведомление пользователю?

Используйте тип notification:

await __event_emitter__({
"type": "notification",
"data": {"type": "success", "content": "Задача выполнена"}
})

В: Как запросить ввод данных от пользователя и получить его ответ?

Используйте:

response = await __event_call__({
"type": "input",
"data": {
"title": "Как вас зовут?",
"message": "Введите ваше предпочтительное имя:",
"placeholder": "Имя"
}
})
# response будет: {"value": "ответ пользователя"}

В: Какие типы событий доступны для __event_call__?

  • "input": Диалоговое окно ввода
  • "confirmation": Диалоговые окна "Да/Нет", "OK/Отмена"
  • "execute": Выполнение предоставленного кода на клиентской стороне и возврат результата

В: Можно ли обновить файлы, прикрепленные к сообщению?

Да — используйте тип события "files" или "chat:message:files" с полезной нагрузкой {files: [...]}.

В: Можно ли обновить заголовок разговора или теги?

Конечно: используйте соответственно "chat:title" или "chat:tags".

В: Можно ли передавать ответы (частичные токены) пользователю с помощью потоков?

Да — отправляйте события "chat:message:delta" в цикле, затем завершите с помощью "chat:message".


📝 Заключение

События предоставляют вам интерактивные суперспособности в реальном времени внутри Open WebUI. Они позволяют вашему коду обновлять содержимое, отправлять уведомления, запрашивать ввод пользователя, передавать результаты, обрабатывать код и многое другое — бесшовно подключая вашу серверную логику к интерфейсу чата.

  • Используйте __event_emitter__ для однонаправленных обновлений статуса/содержания.
  • Используйте __event_call__ для взаимодействий, требующих обратной связи от пользователя (ввод, подтверждение, выполнение).

Ссылайтесь на этот документ для получения информации о распространённых типах событий и структурах, а также изучайте исходный код или документацию Open WebUI для получения обновлений или пользовательских событий!


Приятного программирования, основанного на событиях, в Open WebUI! 🚀