feat: 优化表情包插件和 TTS 插件的异步调用,简化错误处理逻辑
This commit is contained in:
@@ -11,6 +11,8 @@
|
||||
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import inspect
|
||||
@@ -19,6 +21,7 @@ import os
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
import tomllib
|
||||
|
||||
from src.common.logger import get_console_handler, get_logger, initialize_logging
|
||||
from src.plugin_runtime import ENV_IPC_ADDRESS, ENV_PLUGIN_DIRS, ENV_SESSION_TOKEN
|
||||
@@ -95,6 +98,7 @@ class PluginRunner:
|
||||
for meta in plugins:
|
||||
instance = meta.instance
|
||||
self._inject_context(meta.plugin_id, instance)
|
||||
self._apply_plugin_config(meta)
|
||||
if hasattr(instance, "on_load"):
|
||||
try:
|
||||
ret = instance.on_load()
|
||||
@@ -212,6 +216,34 @@ class PluginRunner:
|
||||
instance._set_context(ctx)
|
||||
logger.debug(f"已为插件 {plugin_id} 注入 PluginContext")
|
||||
|
||||
def _apply_plugin_config(self, meta: PluginMeta, config_data: Optional[dict[str, Any]] = None) -> None:
|
||||
"""在 Runner 侧为插件实例注入当前插件配置。"""
|
||||
instance = meta.instance
|
||||
if not hasattr(instance, "set_plugin_config"):
|
||||
return
|
||||
|
||||
plugin_config = config_data if config_data is not None else self._load_plugin_config(meta.plugin_dir)
|
||||
try:
|
||||
instance.set_plugin_config(plugin_config)
|
||||
except Exception as exc:
|
||||
logger.warning(f"插件 {meta.plugin_id} 配置注入失败: {exc}")
|
||||
|
||||
@staticmethod
|
||||
def _load_plugin_config(plugin_dir: str) -> dict[str, Any]:
|
||||
"""从插件目录读取 config.toml。"""
|
||||
config_path = Path(plugin_dir) / "config.toml"
|
||||
if not config_path.exists():
|
||||
return {}
|
||||
|
||||
try:
|
||||
with config_path.open("rb") as handle:
|
||||
loaded = tomllib.load(handle)
|
||||
except Exception as exc:
|
||||
logger.warning(f"读取插件配置失败 {config_path}: {exc}")
|
||||
return {}
|
||||
|
||||
return loaded if isinstance(loaded, dict) else {}
|
||||
|
||||
def _register_handlers(self) -> None:
|
||||
"""注册方法处理器"""
|
||||
self._rpc_client.register_method("plugin.invoke_command", self._handle_invoke)
|
||||
@@ -460,14 +492,16 @@ class PluginRunner:
|
||||
"""处理配置更新事件"""
|
||||
plugin_id = envelope.plugin_id
|
||||
meta = self._loader.get_plugin(plugin_id)
|
||||
if meta and hasattr(meta.instance, "on_config_update"):
|
||||
if meta:
|
||||
try:
|
||||
config_data = envelope.payload.get("config_data", {})
|
||||
config_version = envelope.payload.get("config_version", "")
|
||||
ret = meta.instance.on_config_update(config_data, config_version)
|
||||
# 兼容同步和异步的 on_config_update 实现
|
||||
if asyncio.iscoroutine(ret):
|
||||
await ret
|
||||
self._apply_plugin_config(meta, config_data=config_data)
|
||||
if hasattr(meta.instance, "on_config_update"):
|
||||
ret = meta.instance.on_config_update(config_data, config_version)
|
||||
# 兼容同步和异步的 on_config_update 实现
|
||||
if asyncio.iscoroutine(ret):
|
||||
await ret
|
||||
except Exception as e:
|
||||
logger.error(f"插件 {plugin_id} 配置更新失败: {e}")
|
||||
return envelope.make_error_response(ErrorCode.E_UNKNOWN.value, str(e))
|
||||
|
||||
@@ -30,11 +30,7 @@ class EmojiPlugin(MaiBotPlugin):
|
||||
reason = reasoning or "表达当前情绪"
|
||||
|
||||
# 1. 随机获取30个表情包
|
||||
result = await self.ctx.emoji.get_random(30)
|
||||
if not result or not result.get("success"):
|
||||
return False, "无法获取随机表情包"
|
||||
|
||||
sampled_emojis = result.get("emojis", [])
|
||||
sampled_emojis = await self.ctx.emoji.get_random(30)
|
||||
if not sampled_emojis:
|
||||
return False, "无法获取随机表情包"
|
||||
|
||||
@@ -57,19 +53,13 @@ class EmojiPlugin(MaiBotPlugin):
|
||||
# 3. 获取最近消息作为上下文
|
||||
messages_text = ""
|
||||
if chat_id:
|
||||
recent_result = await self.ctx.message.get_recent(chat_id=chat_id, limit=5)
|
||||
if recent_result and recent_result.get("success"):
|
||||
readable_result = await self.ctx.call_capability(
|
||||
"message.build_readable",
|
||||
chat_id=chat_id,
|
||||
start_time=0,
|
||||
end_time=0,
|
||||
limit=5,
|
||||
recent_messages = await self.ctx.message.get_recent(chat_id=chat_id, limit=5)
|
||||
if recent_messages:
|
||||
messages_text = await self.ctx.message.build_readable(
|
||||
recent_messages,
|
||||
timestamp_mode="normal_no_YMD",
|
||||
truncate=False,
|
||||
)
|
||||
if readable_result and readable_result.get("success"):
|
||||
messages_text = readable_result.get("text", "")
|
||||
|
||||
# 4. 构建 prompt 让 LLM 选择情感
|
||||
available_emotions_str = "\n".join(available_emotions)
|
||||
@@ -100,16 +90,14 @@ class EmojiPlugin(MaiBotPlugin):
|
||||
chosen = random.choice(sampled_emojis)
|
||||
|
||||
# 7. 发送
|
||||
send_result = await self.ctx.send.emoji(chosen["base64"], stream_id)
|
||||
if send_result and send_result.get("success"):
|
||||
send_ok = await self.ctx.send.emoji(chosen["base64"], stream_id)
|
||||
if send_ok:
|
||||
return True, f"成功发送表情包:[表情包:{chosen_emotion}]"
|
||||
return False, "发送表情包失败"
|
||||
|
||||
async def on_load(self):
|
||||
# 从插件配置读取 emoji_chance 来覆盖默认概率
|
||||
config_result = await self.ctx.config.get("emoji.emoji_chance")
|
||||
if config_result and isinstance(config_result, dict) and config_result.get("success"):
|
||||
pass # 配置已在宿主端管理
|
||||
await self.ctx.config.get("emoji.emoji_chance")
|
||||
|
||||
|
||||
def create_plugin():
|
||||
|
||||
@@ -36,7 +36,7 @@ class KnowledgePlugin(MaiBotPlugin):
|
||||
except (TypeError, ValueError):
|
||||
limit_value = 5
|
||||
|
||||
result = await self.ctx.call_capability("knowledge.search", query=query, limit=limit_value)
|
||||
result = await self.ctx.knowledge.search(query=query, limit=limit_value)
|
||||
if result and result.get("success"):
|
||||
content = result.get("content", f"你不太了解有关{query}的知识")
|
||||
return {"type": "lpmm_knowledge", "id": query, "content": content}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import re
|
||||
|
||||
from maibot_sdk import MaiBotPlugin, Action
|
||||
from maibot_sdk import Action, MaiBotPlugin
|
||||
from maibot_sdk.types import ActivationType
|
||||
|
||||
|
||||
@@ -40,15 +40,14 @@ class TTSPlugin(MaiBotPlugin):
|
||||
processed_text = f"{processed_text}。"
|
||||
|
||||
# 发送自定义 tts 消息
|
||||
result = await self.ctx.call_capability(
|
||||
"send.custom",
|
||||
message_type="tts_text",
|
||||
content=processed_text,
|
||||
send_ok = await self.ctx.send.custom(
|
||||
custom_type="tts_text",
|
||||
data=processed_text,
|
||||
stream_id=stream_id,
|
||||
)
|
||||
if result and result.get("success"):
|
||||
if send_ok:
|
||||
return True, "TTS动作执行成功"
|
||||
return False, f"TTS动作执行失败: {result}"
|
||||
return False, "TTS动作执行失败"
|
||||
|
||||
|
||||
def create_plugin():
|
||||
|
||||
Reference in New Issue
Block a user