fix:添加新插件API

This commit is contained in:
SengokuCola
2025-06-04 01:28:57 +08:00
parent 3476d12498
commit 5880fe707e
5 changed files with 141 additions and 20 deletions

View File

@@ -1,16 +1,29 @@
# Changelog
## [0.7.1] -2025-6-2
- 修复关键词功能并且在focus中可用
- 更新planner架构大大加快速度和表现效果建议使用simple规划器
- 为normal加入使用action的能力
- 修复emoji配置项无效问题
## [0.7.1] -2025-6-3
重点优化
加入了人物侧写!麦麦认得群友
更新planner架构大大加快速度和表现效果
为normal_chat加入动作执行
新增关系处理器
修复关键词功能并且在focus中可用
- 修复log出错问题
- 修复focus吞第一条消息问题
- 可关闭聊天规划处理器(建议关闭)
- 优化记忆同步速度修复记忆构建缺少chat_id的问题
修复了:
群名称导致log保存失败
focus吞掉首条消息
表达方式的多样性
可关闭思考处理器(建议默认关闭)
focus没有时间信息的问题
修复了表情包action
优化聊天记录构建方式
优化记忆同步速度和记忆构建缺少chat_id的问题
优化工作记忆处理器
优化人格表达
删除无效字段防止数据库报错

View File

@@ -4,8 +4,10 @@ from src.chat.focus_chat.planners.actions.base_action import BaseAction, registe
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
from src.chat.focus_chat.hfc_utils import create_empty_anchor_message
from src.common.logger_manager import get_logger
from src.llm_models.utils_model import LLMRequest
from src.person_info.person_info import person_info_manager
from abc import abstractmethod
from src.config.config import global_config
import os
import inspect
import toml # 导入 toml 库
@@ -35,7 +37,6 @@ class PluginAction(BaseAction):
# 存储内部服务和对象引用
self._services = {}
self._global_config = global_config # 存储全局配置的只读引用
self.config: Dict[str, Any] = {} # 用于存储插件自身的配置
# 从kwargs提取必要的内部服务
@@ -100,10 +101,8 @@ class PluginAction(BaseAction):
安全地从全局配置中获取一个值。
插件应使用此方法读取全局配置,以保证只读和隔离性。
"""
if self._global_config:
return self._global_config.get(key, default)
logger.debug(f"{self.log_prefix} 尝试访问全局配置项 '{key}',但全局配置未提供。")
return default
return global_config.get(key, default)
async def get_user_id_by_person_name(self, person_name: str) -> Tuple[str, str]:
"""根据用户名获取用户ID"""
@@ -228,6 +227,62 @@ class PluginAction(BaseAction):
return success
async def send_message_by_replyer(self, target: Optional[str] = None, extra_info_block: Optional[str] = None) -> bool:
"""通过 replyer 发送消息的简化方法
Args:
text: 要发送的消息文本
target: 目标消息(可选)
Returns:
bool: 是否发送成功
"""
replyer = self._services.get("replyer")
chat_stream = self._services.get("chat_stream")
if not replyer or not chat_stream:
logger.error(f"{self.log_prefix} 无法发送消息:缺少必要的内部服务")
return False
# 构造简化的动作数据
reply_data = {"target": target or "", "extra_info_block": extra_info_block}
# 获取锚定消息(如果有)
observations = self._services.get("observations", [])
# 查找 ChattingObservation 实例
chatting_observation = None
for obs in observations:
if isinstance(obs, ChattingObservation):
chatting_observation = obs
break
if not chatting_observation:
logger.warning(f"{self.log_prefix} 未找到 ChattingObservation 实例,创建占位符")
anchor_message = await create_empty_anchor_message(
chat_stream.platform, chat_stream.group_info, chat_stream
)
else:
anchor_message = chatting_observation.search_message_by_text(reply_data["target"])
if not anchor_message:
logger.info(f"{self.log_prefix} 未找到锚点消息,创建占位符")
anchor_message = await create_empty_anchor_message(
chat_stream.platform, chat_stream.group_info, chat_stream
)
else:
anchor_message.update_chat_stream(chat_stream)
# 调用内部方法发送消息
success, _ = await replyer.deal_reply(
cycle_timers=self.cycle_timers,
action_data=reply_data,
anchor_message=anchor_message,
reasoning=self.reasoning,
thinking_id=self.thinking_id,
)
return success
def get_chat_type(self) -> str:
"""获取当前聊天类型
@@ -266,6 +321,60 @@ class PluginAction(BaseAction):
return messages
def get_available_models(self) -> Dict[str, Any]:
"""获取所有可用的模型配置
Returns:
Dict[str, Any]: 模型配置字典key为模型名称value为模型配置
"""
if not hasattr(global_config, "model"):
logger.error(f"{self.log_prefix} 无法获取模型列表:全局配置中未找到 model 配置")
return {}
models = global_config.model
return models
async def generate_with_model(
self,
prompt: str,
model_config: Dict[str, Any],
max_tokens: int = 2000,
request_type: str = "plugin.generate",
**kwargs
) -> Tuple[bool, str]:
"""使用指定模型生成内容
Args:
prompt: 提示词
model_config: 模型配置(从 get_available_models 获取的模型配置)
temperature: 温度参数,控制随机性 (0-1)
max_tokens: 最大生成token数
request_type: 请求类型标识
**kwargs: 其他模型特定参数
Returns:
Tuple[bool, str]: (是否成功, 生成的内容或错误信息)
"""
try:
logger.info(f"prompt: {prompt}")
llm_request = LLMRequest(
model=model_config,
max_tokens=max_tokens,
request_type=request_type,
**kwargs
)
response,(resoning , model_name) = await llm_request.generate_response_async(prompt)
return True, response, resoning, model_name
except Exception as e:
error_msg = f"生成内容时出错: {str(e)}"
logger.error(f"{self.log_prefix} {error_msg}")
return False, error_msg
@abstractmethod
async def process(self) -> Tuple[bool, str]:
"""插件处理逻辑,子类必须实现此方法

View File

@@ -190,11 +190,10 @@ class ActionPlanner(BasePlanner):
prompt = f"{prompt}"
llm_content, (reasoning_content, _) = await self.planner_llm.generate_response_async(prompt=prompt)
logger.debug(
f"{self.log_prefix}规划器Prompt:\n{prompt}\n\n决策动作:{action},\n动作信息: '{action_data}'\n理由: {reasoning}"
logger.info(
f"{self.log_prefix}规划器Prompt:\n{prompt}\n\nLLM 原始响应: {llm_content}'"
)
logger.debug(f"{self.log_prefix}LLM 原始响应: {llm_content}")
logger.debug(f"{self.log_prefix}LLM 原始理由响应: {reasoning_content}")
except Exception as req_e:
logger.error(f"{self.log_prefix}LLM 请求执行失败: {req_e}")

View File

@@ -24,7 +24,7 @@ import random
from datetime import datetime
import re
logger = get_logger("expressor")
logger = get_logger("replyer")
def init_prompt():
@@ -295,7 +295,7 @@ class DefaultReplyer:
# logger.info(f"{self.log_prefix}[Replier-{thinking_id}]\nPrompt:\n{prompt}\n")
content, (reasoning_content, model_name) = await self.express_model.generate_response_async(prompt)
logger.debug(f"prompt: {prompt}")
logger.info(f"prompt: {prompt}")
logger.info(f"最终回复: {content}")
info_catcher.catch_after_llm_generated(

View File

@@ -1,5 +1,5 @@
[inner]
version = "2.12.0"
version = "2.12.1"
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
#如果你想要修改配置文件请在修改后将version的值进行变更