feat: 重构了智能思维导图和摘要插件的事件发射逻辑,并新增了插件开发指南。
This commit is contained in:
@@ -394,11 +394,11 @@ SCRIPT_TEMPLATE_MINDMAP = """
|
||||
|
||||
class Action:
|
||||
class Valves(BaseModel):
|
||||
show_status: bool = Field(
|
||||
SHOW_STATUS: bool = Field(
|
||||
default=True,
|
||||
description="Whether to show action status updates in the chat interface.",
|
||||
)
|
||||
LLM_MODEL_ID: str = Field(
|
||||
MODEL_ID: str = Field(
|
||||
default="",
|
||||
description="Built-in LLM model ID for text analysis. If empty, uses the current conversation's model.",
|
||||
)
|
||||
@@ -434,6 +434,20 @@ class Action:
|
||||
extracted_content = llm_output.strip()
|
||||
return extracted_content.replace("</script>", "<\\/script>")
|
||||
|
||||
async def _emit_status(self, emitter, description: str, done: bool = False):
|
||||
"""Emits a status update event."""
|
||||
if self.valves.SHOW_STATUS and emitter:
|
||||
await emitter(
|
||||
{"type": "status", "data": {"description": description, "done": done}}
|
||||
)
|
||||
|
||||
async def _emit_notification(self, emitter, content: str, ntype: str = "info"):
|
||||
"""Emits a notification event (info/success/warning/error)."""
|
||||
if emitter:
|
||||
await emitter(
|
||||
{"type": "notification", "data": {"type": ntype, "content": content}}
|
||||
)
|
||||
|
||||
def _remove_existing_html(self, content: str) -> str:
|
||||
"""Removes existing plugin-generated HTML code blocks from the content."""
|
||||
pattern = r"```html\s*<!-- OPENWEBUI_PLUGIN_OUTPUT -->[\s\S]*?```"
|
||||
@@ -523,16 +537,11 @@ class Action:
|
||||
current_year = now.strftime("%Y")
|
||||
current_timezone_str = "Unknown"
|
||||
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "info",
|
||||
"content": "Smart Mind Map is starting, generating mind map for you...",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__,
|
||||
"Smart Mind Map is starting, generating mind map for you...",
|
||||
"info",
|
||||
)
|
||||
|
||||
messages = body.get("messages")
|
||||
if (
|
||||
@@ -541,13 +550,7 @@ class Action:
|
||||
or not messages[-1].get("content")
|
||||
):
|
||||
error_message = "Unable to retrieve valid user message content."
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {"type": "error", "content": error_message},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(__event_emitter__, error_message, "error")
|
||||
return {
|
||||
"messages": [{"role": "assistant", "content": f"❌ {error_message}"}]
|
||||
}
|
||||
@@ -565,30 +568,20 @@ class Action:
|
||||
|
||||
if len(long_text_content) < self.valves.MIN_TEXT_LENGTH:
|
||||
short_text_message = f"Text content is too short ({len(long_text_content)} characters), unable to perform effective analysis. Please provide at least {self.valves.MIN_TEXT_LENGTH} characters of text."
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {"type": "warning", "content": short_text_message},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__, short_text_message, "warning"
|
||||
)
|
||||
return {
|
||||
"messages": [
|
||||
{"role": "assistant", "content": f"⚠️ {short_text_message}"}
|
||||
]
|
||||
}
|
||||
|
||||
if self.valves.show_status and __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "Smart Mind Map: Analyzing text structure in depth...",
|
||||
"done": False,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(
|
||||
__event_emitter__,
|
||||
"Smart Mind Map: Analyzing text structure in depth...",
|
||||
False,
|
||||
)
|
||||
|
||||
try:
|
||||
unique_id = f"id_{int(time.time() * 1000)}"
|
||||
@@ -603,7 +596,7 @@ class Action:
|
||||
)
|
||||
|
||||
# Determine model to use
|
||||
target_model = self.valves.LLM_MODEL_ID
|
||||
target_model = self.valves.MODEL_ID
|
||||
if not target_model:
|
||||
target_model = body.get("model")
|
||||
|
||||
@@ -684,26 +677,14 @@ class Action:
|
||||
html_embed_tag = f"```html\n{final_html}\n```"
|
||||
body["messages"][-1]["content"] = f"{long_text_content}\n\n{html_embed_tag}"
|
||||
|
||||
if self.valves.show_status and __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "Smart Mind Map: Drawing completed!",
|
||||
"done": True,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "success",
|
||||
"content": f"Mind map has been generated, {user_name}!",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(
|
||||
__event_emitter__, "Smart Mind Map: Drawing completed!", True
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__,
|
||||
f"Mind map has been generated, {user_name}!",
|
||||
"success",
|
||||
)
|
||||
logger.info("Action: Smart Mind Map (v0.7.2) completed successfully")
|
||||
|
||||
except Exception as e:
|
||||
@@ -714,26 +695,13 @@ class Action:
|
||||
"content"
|
||||
] = f"{long_text_content}\n\n❌ **Error:** {user_facing_error}"
|
||||
|
||||
if __event_emitter__:
|
||||
if self.valves.show_status:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "Smart Mind Map: Processing failed.",
|
||||
"done": True,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "error",
|
||||
"content": f"Smart Mind Map generation failed, {user_name}!",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(
|
||||
__event_emitter__, "Smart Mind Map: Processing failed.", True
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__,
|
||||
f"Smart Mind Map generation failed, {user_name}!",
|
||||
"error",
|
||||
)
|
||||
|
||||
return body
|
||||
|
||||
@@ -394,10 +394,10 @@ SCRIPT_TEMPLATE_MINDMAP = """
|
||||
|
||||
class Action:
|
||||
class Valves(BaseModel):
|
||||
show_status: bool = Field(
|
||||
SHOW_STATUS: bool = Field(
|
||||
default=True, description="是否在聊天界面显示操作状态更新。"
|
||||
)
|
||||
LLM_MODEL_ID: str = Field(
|
||||
MODEL_ID: str = Field(
|
||||
default="",
|
||||
description="用于文本分析的内置LLM模型ID。如果为空,则使用当前对话的模型。",
|
||||
)
|
||||
@@ -433,6 +433,20 @@ class Action:
|
||||
extracted_content = llm_output.strip()
|
||||
return extracted_content.replace("</script>", "<\\/script>")
|
||||
|
||||
async def _emit_status(self, emitter, description: str, done: bool = False):
|
||||
"""发送状态更新事件。"""
|
||||
if self.valves.SHOW_STATUS and emitter:
|
||||
await emitter(
|
||||
{"type": "status", "data": {"description": description, "done": done}}
|
||||
)
|
||||
|
||||
async def _emit_notification(self, emitter, content: str, ntype: str = "info"):
|
||||
"""发送通知事件 (info/success/warning/error)。"""
|
||||
if emitter:
|
||||
await emitter(
|
||||
{"type": "notification", "data": {"type": ntype, "content": content}}
|
||||
)
|
||||
|
||||
def _remove_existing_html(self, content: str) -> str:
|
||||
"""移除内容中已有的插件生成 HTML 代码块 (通过标记识别)。"""
|
||||
pattern = r"```html\s*<!-- OPENWEBUI_PLUGIN_OUTPUT -->[\s\S]*?```"
|
||||
@@ -522,16 +536,9 @@ class Action:
|
||||
current_year = now.strftime("%Y")
|
||||
current_timezone_str = "未知时区"
|
||||
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "info",
|
||||
"content": "智绘心图已启动,正在为您生成思维导图...",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__, "智绘心图已启动,正在为您生成思维导图...", "info"
|
||||
)
|
||||
|
||||
messages = body.get("messages")
|
||||
if (
|
||||
@@ -540,13 +547,7 @@ class Action:
|
||||
or not messages[-1].get("content")
|
||||
):
|
||||
error_message = "无法获取有效的用户消息内容。"
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {"type": "error", "content": error_message},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(__event_emitter__, error_message, "error")
|
||||
return {
|
||||
"messages": [{"role": "assistant", "content": f"❌ {error_message}"}]
|
||||
}
|
||||
@@ -564,30 +565,18 @@ class Action:
|
||||
|
||||
if len(long_text_content) < self.valves.MIN_TEXT_LENGTH:
|
||||
short_text_message = f"文本内容过短({len(long_text_content)}字符),无法进行有效分析。请提供至少{self.valves.MIN_TEXT_LENGTH}字符的文本。"
|
||||
if __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {"type": "warning", "content": short_text_message},
|
||||
}
|
||||
)
|
||||
await self._emit_notification(
|
||||
__event_emitter__, short_text_message, "warning"
|
||||
)
|
||||
return {
|
||||
"messages": [
|
||||
{"role": "assistant", "content": f"⚠️ {short_text_message}"}
|
||||
]
|
||||
}
|
||||
|
||||
if self.valves.show_status and __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "智绘心图: 深入分析文本结构...",
|
||||
"done": False,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(
|
||||
__event_emitter__, "智绘心图: 深入分析文本结构...", False
|
||||
)
|
||||
|
||||
try:
|
||||
unique_id = f"id_{int(time.time() * 1000)}"
|
||||
@@ -602,7 +591,7 @@ class Action:
|
||||
)
|
||||
|
||||
# 确定使用的模型
|
||||
target_model = self.valves.LLM_MODEL_ID
|
||||
target_model = self.valves.MODEL_ID
|
||||
if not target_model:
|
||||
target_model = body.get("model")
|
||||
|
||||
@@ -682,26 +671,10 @@ class Action:
|
||||
html_embed_tag = f"```html\n{final_html}\n```"
|
||||
body["messages"][-1]["content"] = f"{long_text_content}\n\n{html_embed_tag}"
|
||||
|
||||
if self.valves.show_status and __event_emitter__:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "智绘心图: 绘制完成!",
|
||||
"done": True,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "success",
|
||||
"content": f"思维导图已生成,{user_name}!",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(__event_emitter__, "智绘心图: 绘制完成!", True)
|
||||
await self._emit_notification(
|
||||
__event_emitter__, f"思维导图已生成,{user_name}!", "success"
|
||||
)
|
||||
logger.info("Action: 智绘心图 (v12) completed successfully")
|
||||
|
||||
except Exception as e:
|
||||
@@ -712,26 +685,9 @@ class Action:
|
||||
"content"
|
||||
] = f"{long_text_content}\n\n❌ **错误:** {user_facing_error}"
|
||||
|
||||
if __event_emitter__:
|
||||
if self.valves.show_status:
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "status",
|
||||
"data": {
|
||||
"description": "智绘心图: 处理失败。",
|
||||
"done": True,
|
||||
"hidden": False,
|
||||
},
|
||||
}
|
||||
)
|
||||
await __event_emitter__(
|
||||
{
|
||||
"type": "notification",
|
||||
"data": {
|
||||
"type": "error",
|
||||
"content": f"智绘心图生成失败, {user_name}!",
|
||||
},
|
||||
}
|
||||
)
|
||||
await self._emit_status(__event_emitter__, "智绘心图: 处理失败。", True)
|
||||
await self._emit_notification(
|
||||
__event_emitter__, f"智绘心图生成失败, {user_name}!", "error"
|
||||
)
|
||||
|
||||
return body
|
||||
|
||||
Reference in New Issue
Block a user