Merge branch 'dev' of github.com:MaiM-with-u/MaiBot into dev

pull/1235/head
UnCLAS-Prommer 2025-09-13 11:11:44 +08:00
commit a196c940bf
No known key found for this signature in database
8 changed files with 62 additions and 52 deletions

View File

@ -199,7 +199,7 @@ class HeartFChatting:
# !处理no_reply_until_call逻辑
if self.no_reply_until_call:
for message in recent_messages_list:
if message.is_mentioned or message.is_at:
if message.is_mentioned or message.is_at or len(recent_messages_list) >= 8 or time.time() - self.last_read_time > 600:
self.no_reply_until_call = False
break
# 没有提到,继续保持沉默
@ -333,6 +333,31 @@ class HeartFChatting:
loop_start_time=self.last_read_time,
available_actions=available_actions,
)
# !此处使at或者提及必定回复
metioned_message = None
for message in recent_messages_list:
if (message.is_mentioned or message.is_at) and global_config.chat.mentioned_bot_reply:
metioned_message = message
has_reply = False
for action in action_to_use_info:
if action.action_type == "reply":
has_reply =True
break
if not has_reply and metioned_message:
action_to_use_info.append(
ActionPlannerInfo(
action_type="reply",
reasoning="有人提到了你,进行回复",
action_data={},
action_message=metioned_message,
available_actions=available_actions,
)
)
# 3. 并行执行所有动作
action_tasks = [
@ -350,18 +375,15 @@ class HeartFChatting:
reply_text_from_reply = ""
action_success = False
action_reply_text = ""
action_command = ""
for i, result in enumerate(results):
if isinstance(result, BaseException):
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
continue
_cur_action = action_to_use_info[i]
if result["action_type"] != "reply":
action_success = result["success"]
action_reply_text = result["reply_text"]
action_command = result.get("command", "")
elif result["action_type"] == "reply":
if result["success"]:
reply_loop_info = result["loop_info"]
@ -377,7 +399,6 @@ class HeartFChatting:
loop_info["loop_action_info"].update(
{
"action_taken": action_success,
"command": action_command,
"taken_time": time.time(),
}
)
@ -391,7 +412,6 @@ class HeartFChatting:
"loop_action_info": {
"action_taken": action_success,
"reply_text": action_reply_text,
"command": action_command,
"taken_time": time.time(),
},
}

View File

@ -39,6 +39,7 @@ def init_prompt():
"""
{time_block}
{name_block}
你的兴趣是{interest}
{chat_context_description}以下是具体的聊天内容
**聊天内容**
{chat_content_block}
@ -60,6 +61,7 @@ reply
no_reply
动作描述
保持沉默不回复直到有新消息
控制聊天频率不要太过频繁的发言
{{
"action": "no_reply",
}}
@ -67,30 +69,18 @@ no_reply
no_reply_until_call
动作描述
保持沉默直到有人直接叫你的名字
当前话题不感兴趣时使用或有人不喜欢你的发言时使用
{{
"action": "no_reply_until_call",
}}
wait_time
动作描述
沉默等待时间等待一段时间后回复
{{
"action": "wait_time",
"time":"等待时间",
}}
{action_options_text}
请选择合适的action并说明触发action的消息id和选择该action的原因消息id格式:m+数字
先输出你的选择思考理由再输出你选择的action理由是一段平文本不要分点精简
**动作选择要求**
请你根据聊天内容和用户的最新消息选择合适的动作:
1.思考**所有**的可用的action中的**每个动作**是否符合当下条件如果动作使用调节符合当下条件就使用
2.如果相同的内容已经被执行请不要重复执行
3.你的兴趣是{interest}
4.请控制你的发言频率不要太过频繁的发言
5.如果有人对你感到厌烦请减少回复
6.如果有人对你进行攻击或者情绪激动请你以合适的方法应对
请你根据聊天内容,用户的最新消息和以下标准选择合适的动作:
{plan_style}
{moderation_prompt}
请选择所有符合使用要求的action动作用json格式输出如果输出多个json每个json都要单独用```json包裹你可以重复使用同一个动作或不同动作:
@ -175,7 +165,7 @@ class ActionPlanner:
try:
action = action_json.get("action", "no_action")
reasoning = action_json.get("reason", "未提供原因")
action_data = {key: value for key, value in action_json.items() if key not in ["action", "reasoning"]}
action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]}
# 非no_action动作需要target_message_id
target_message = None
@ -357,6 +347,7 @@ class ActionPlanner:
moderation_prompt=moderation_prompt_block,
name_block=name_block,
interest=interest,
plan_style=global_config.personality.plan_style,
)
return prompt, message_id_list

View File

@ -153,7 +153,7 @@ class ImageManager:
"这是一个表情包,请详细描述一下表情包所表达的情感和内容,描述细节,从互联网梗,meme的角度去分析"
)
detailed_description, _ = await self.vlm.generate_response_for_image(
vlm_prompt, image_base64, image_format, temperature=0.4, max_tokens=300
vlm_prompt, image_base64, image_format, temperature=0.4
)
if detailed_description is None:
@ -175,7 +175,7 @@ class ImageManager:
# 使用较低温度确保输出稳定
emotion_llm = LLMRequest(model_set=model_config.model_task_config.utils, request_type="emoji")
emotion_result, _ = await emotion_llm.generate_response_async(
emotion_prompt, temperature=0.3, max_tokens=50
emotion_prompt, temperature=0.3
)
if not emotion_result:
@ -270,7 +270,7 @@ class ImageManager:
# 调用AI获取描述
image_format = Image.open(io.BytesIO(image_bytes)).format.lower() # type: ignore
prompt = global_config.custom_prompt.image_prompt
prompt = global_config.personality.visual_style
logger.info(f"[VLM调用] 为图片生成新描述 (Hash: {image_hash[:8]}...)")
description, _ = await self.vlm.generate_response_for_image(
prompt, image_base64, image_format, temperature=0.4, max_tokens=300
@ -566,7 +566,7 @@ class ImageManager:
image_format = Image.open(io.BytesIO(image_bytes)).format.lower() # type: ignore
# 构建prompt
prompt = global_config.custom_prompt.image_prompt
prompt = global_config.personality.visual_style
# 获取VLM描述
description, _ = await self.vlm.generate_response_for_image(

View File

@ -117,9 +117,6 @@ class ModelTaskConfig(ConfigBase):
planner: TaskConfig
"""规划模型配置"""
planner_small: TaskConfig
"""副规划模型配置"""
embedding: TaskConfig
"""嵌入模型配置"""

View File

@ -32,7 +32,6 @@ from src.config.official_configs import (
ToolConfig,
VoiceConfig,
DebugConfig,
CustomPromptConfig,
)
from .api_ada_configs import (
@ -55,7 +54,7 @@ TEMPLATE_DIR = os.path.join(PROJECT_ROOT, "template")
# 考虑到实际上配置文件中的mai_version是不会自动更新的,所以采用硬编码
# 对该字段的更新请严格参照语义化版本规范https://semver.org/lang/zh-CN/
MMC_VERSION = "0.10.3-snapshot.2"
MMC_VERSION = "0.10.3-snapshot.3"
def get_key_comment(toml_table, key):
@ -357,7 +356,6 @@ class Config(ConfigBase):
lpmm_knowledge: LPMMKnowledgeConfig
tool: ToolConfig
debug: DebugConfig
custom_prompt: CustomPromptConfig
voice: VoiceConfig

View File

@ -46,6 +46,12 @@ class PersonalityConfig(ConfigBase):
interest: str = ""
"""兴趣"""
plan_style: str = ""
"""说话规则,行为风格"""
visual_style: str = ""
"""图片提示词"""
@dataclass
@ -72,6 +78,9 @@ class ChatConfig(ConfigBase):
planner_size: float = 1.5
"""副规划器大小越小麦麦的动作执行能力越精细但是消耗更多token调大可以缓解429类错误"""
mentioned_bot_reply: bool = True
"""是否启用提及必回复"""
at_bot_inevitable_reply: float = 1
"""@bot 必然回复1为100%回复0为不额外增幅"""
@ -382,14 +391,6 @@ class KeywordReactionConfig(ConfigBase):
raise ValueError(f"规则必须是KeywordRuleConfig类型而不是{type(rule).__name__}")
@dataclass
class CustomPromptConfig(ConfigBase):
"""自定义提示词配置类"""
image_prompt: str = ""
"""图片提示词"""
@dataclass
class ResponsePostProcessConfig(ConfigBase):
"""回复后处理配置类"""

View File

@ -1,5 +1,5 @@
[inner]
version = "6.10.1"
version = "6.11.0"
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
#如果你想要修改配置文件请递增version的值
@ -28,6 +28,17 @@ emotion_style = "情绪较为稳定,但遭遇特定事件的时候起伏较大
# 麦麦的兴趣,会影响麦麦对什么话题进行回复
interest = "对技术相关话题,游戏和动漫相关话题感兴趣,也对日常话题感兴趣,不喜欢太过沉重严肃的话题"
# 麦麦的说话规则,行为风格:
plan_style = """,:
1.****action****使使
2.
3.
4.
5."""
# 麦麦识图规则,不建议修改
visual_style = "请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本"
[expression]
# 表达学习配置
learning_list = [ # 表达学习配置列表,支持按聊天流配置
@ -50,7 +61,8 @@ expression_groups = [
[chat] #麦麦的聊天设置
talk_value = 1.5
talk_value = 1
mentioned_bot_reply = true # 是否启用提及必回复
max_context_size = 20 # 上下文长度
[relationship]
@ -120,10 +132,6 @@ regex_rules = [
{ regex = ["^(?P<n>\\S{1,20})是这样的$"], reaction = "请按照以下模板造句:[n]是这样的xx只要xx就可以可是[n]要考虑的事情就很多了比如什么时候xx什么时候xx什么时候xx。请自由发挥替换xx部分只需保持句式结构同时表达一种将[n]过度重视的反讽意味)" }
]
# 可以自定义部分提示词
[custom_prompt]
image_prompt = "请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本"
[response_post_process]
enable_response_post_process = true # 是否启用回复后处理,包括错别字生成器,回复分割器

View File

@ -1,5 +1,5 @@
[inner]
version = "1.5.0"
version = "1.6.0"
# 配置文件版本号迭代规则同bot_config.toml
@ -113,11 +113,6 @@ model_list = ["siliconflow-deepseek-v3"]
temperature = 0.3
max_tokens = 800
[model_task_config.planner_small] #副决策:负责决定麦麦该做什么的模型
model_list = ["qwen3-30b"]
temperature = 0.3
max_tokens = 800
[model_task_config.emotion] #负责麦麦的情绪变化
model_list = ["qwen3-30b"]
temperature = 0.7