跳到主要内容

⛑️ 事件:在 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 事件处理逻辑的最新分析)

类型使用场景数据负载结构(示例)
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__)
请求确认(确定/取消对话框){title: "...", message: "..."}
input
(需要 __event_call__)
请求简单用户输入(“输入框”对话框){title: "...", message: "...", placeholder: "...", value: ...}
execute
(需要 __event_call__)
请求用户端执行代码并返回结果{code: "...javascript code..."}

其他/高级类型:

  • 您可以在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

显示一个弹出通知:

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 中愉快地进行事件驱动编码吧!🚀