Skip to main content

⛑️ 事件:在Open WebUI中使用__event_emitter____event_call__

Open WebUI的插件架构不仅仅是处理输入和产生输出——它是关于与UI和用户的实时交互式通信。为了让您的工具、函数和管道更加动态,Open WebUI通过__event_emitter____event_call__助手提供了内置的事件系统。

本指南解释了什么是事件如何从代码中触发它们,以及可以使用的事件类型的完整目录(包括远不止"input")。


🌊 什么是事件?

事件是从您的后端代码(工具或函数)发送到Web UI的实时通知或交互式请求。它们允许您更新聊天、显示通知、请求确认、运行UI流程等等。

  • 事件使用__event_emitter__助手发送单向更新,或在需要用户输入或响应时(例如,确认、输入等)使用__event_call__

比喻:
将事件想象为推送通知和您的插件可以触发的模态对话框,使聊天体验更丰富和更具交互性。


🧰 基本用法

发送事件

您可以通过调用以下方式在工具或函数内的任何地方触发事件:

await __event_emitter__(
{
"type": "status", # 请参阅下面的事件类型列表
"data": {
"description": "处理开始!",
"done": False,
"hidden": False,
},
}
)

不需要手动添加像chat_idmessage_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中显示通知("toast"){type: "info"或"success"或"error"或"warning", content: "..."}
confirmation
(需要__event_call__
请求确认(确定/取消对话框){title: "...", message: "..."}
input
(需要__event_call__
请求简单的用户输入("输入框"对话框){title: "...", message: "...", placeholder: "...", value: ...}
execute
(需要__event_call__
请求用户端代码执行并返回结果{code: "...javascript代码..."}

其他/高级类型:

  • 您可以定义自己的类型并在UI层处理它们(或使用即将推出的事件扩展机制)。

❗ 特定事件类型的详细信息

status

在UI中显示状态/进度更新:

await __event_emitter__(
{
"type": "status",
"data": {
"description": "步骤 1/3:获取数据...",
"done": False,
"hidden": False,
},
}
)

chat:message:deltamessage

流式输出(追加文本):

await __event_emitter__(
{
"type": "chat:message:delta", # 或简单的"message"
"data": {
"content": "部分文本,"
},
}
)

# 稍后,当您生成更多内容时:
await __event_emitter__(
{
"type": "chat:message:delta",
"data": {
"content": "响应的下一个块。"
},
}
)

chat:messagereplace

设置(或替换)整个消息内容:

await __event_emitter__(
{
"type": "chat:message", # 或"replace"
"data": {
"content": "最终的完整响应。"
},
}
)

fileschat:message:files

附加或更新文件:

await __event_emitter__(
{
"type": "files", # 或"chat:message:files"
"data": {
"files": [
# Open WebUI文件对象
]
},
}
)

chat:title

更新聊天的标题:

await __event_emitter__(
{
"type": "chat:title",
"data": {
"title": "市场分析机器人会话"
},
}
)

chat:tags

更新聊天的标签:

await __event_emitter__(
{
"type": "chat:tags",
"data": {
"tags": ["金融", "AI", "日报"]
},
}
)

sourcecitation(和代码执行)

添加参考/引用:

await __event_emitter__(
{
"type": "source", # 或"citation"
"data": {
# Open WebUI来源(引用)对象
}
}
)

对于代码执行(跟踪执行状态):

await __event_emitter__(
{
"type": "source",
"data": {
# Open WebUI代码来源(引用)对象
}
}
)

notification

显示toast通知:

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: # 或检查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中的任何工具或函数
  • 用于流式响应、显示进度、请求用户数据、更新UI或显示补充信息/文件。
  • await __event_emitter__用于单向消息(发送并忘记)。
  • await __event_call__用于需要用户响应的情况(输入、执行、确认)。

💡 提示和高级注意事项

  • **每条消息多种类型:**您可以为一条消息发出几种不同类型的事件——例如,显示status更新,然后用chat:message:delta流式传输,然后用chat:message完成。
  • **自定义事件类型:**虽然上面的列表是标准的,但您可以使用自己的类型并在自定义UI代码中检测/处理它们。
  • **可扩展性:**事件系统设计为可进化——始终检查Open WebUI文档以获取最新列表和高级用法。

🧐 常见问题

问:如何为用户触发通知?

使用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":是/否,确定/取消对话框
  • "execute":在客户端运行提供的代码并返回结果

问:我可以更新附加到消息的文件吗?

是的——使用"files""chat:message:files"事件类型,负载为{files: [...]}

问:我可以更新对话标题或标签吗?

当然:相应地使用"chat:title""chat:tags"

问:我可以向用户流式传输响应(部分令牌)吗?

是的——在循环中发出"chat:message:delta"事件,然后用"chat:message"完成。


📝 结论

事件为您在Open WebUI内提供实时、交互式的超能力。它们让您的代码更新内容、触发通知、请求用户输入、流式传输结果、处理代码等等——无缝地将您的后端智能插入到聊天UI中。

  • 使用__event_emitter__进行单向状态/内容更新。
  • 使用__event_call__进行需要用户后续操作的交互(输入、确认、执行)。

参考本文档了解常见的事件类型和结构,并探索Open WebUI源代码或文档以获取重大更新或自定义事件!


在Open WebUI中愉快的事件驱动编程!🚀