Ruff fix
This commit is contained in:
@@ -46,6 +46,7 @@ init_memory_retrieval_prompt()
|
||||
|
||||
logger = get_logger("replyer")
|
||||
|
||||
|
||||
class PrivateReplyer:
|
||||
def __init__(
|
||||
self,
|
||||
@@ -277,9 +278,7 @@ class PrivateReplyer:
|
||||
expression_habits_block = ""
|
||||
expression_habits_title = ""
|
||||
if style_habits_str.strip():
|
||||
expression_habits_title = (
|
||||
"在回复时,你可以参考以下的语言习惯,不要生硬使用:"
|
||||
)
|
||||
expression_habits_title = "在回复时,你可以参考以下的语言习惯,不要生硬使用:"
|
||||
expression_habits_block += f"{style_habits_str}\n"
|
||||
|
||||
return f"{expression_habits_title}\n{expression_habits_block}", selected_ids
|
||||
@@ -291,7 +290,6 @@ class PrivateReplyer:
|
||||
mood_state = await mood_manager.get_mood_by_chat_id(self.chat_stream.stream_id).get_mood()
|
||||
return f"你现在的心情是:{mood_state}"
|
||||
|
||||
|
||||
async def build_tool_info(self, chat_history: str, sender: str, target: str, enable_tool: bool = True) -> str:
|
||||
"""构建工具信息块
|
||||
|
||||
@@ -358,45 +356,45 @@ class PrivateReplyer:
|
||||
|
||||
def _replace_picids_with_descriptions(self, text: str) -> str:
|
||||
"""将文本中的[picid:xxx]替换为具体的图片描述
|
||||
|
||||
|
||||
Args:
|
||||
text: 包含picid标记的文本
|
||||
|
||||
|
||||
Returns:
|
||||
替换后的文本
|
||||
"""
|
||||
# 匹配 [picid:xxxxx] 格式
|
||||
pic_pattern = r"\[picid:([^\]]+)\]"
|
||||
|
||||
|
||||
def replace_pic_id(match: re.Match) -> str:
|
||||
pic_id = match.group(1)
|
||||
description = translate_pid_to_description(pic_id)
|
||||
return f"[图片:{description}]"
|
||||
|
||||
|
||||
return re.sub(pic_pattern, replace_pic_id, text)
|
||||
|
||||
def _analyze_target_content(self, target: str) -> Tuple[bool, bool, str, str]:
|
||||
"""分析target内容类型(基于原始picid格式)
|
||||
|
||||
|
||||
Args:
|
||||
target: 目标消息内容(包含[picid:xxx]格式)
|
||||
|
||||
|
||||
Returns:
|
||||
Tuple[bool, bool, str, str]: (是否只包含图片, 是否包含文字, 图片部分, 文字部分)
|
||||
"""
|
||||
if not target or not target.strip():
|
||||
return False, False, "", ""
|
||||
|
||||
|
||||
# 检查是否只包含picid标记
|
||||
picid_pattern = r"\[picid:[^\]]+\]"
|
||||
picid_matches = re.findall(picid_pattern, target)
|
||||
|
||||
|
||||
# 移除所有picid标记后检查是否还有文字内容
|
||||
text_without_picids = re.sub(picid_pattern, "", target).strip()
|
||||
|
||||
|
||||
has_only_pics = len(picid_matches) > 0 and not text_without_picids
|
||||
has_text = bool(text_without_picids)
|
||||
|
||||
|
||||
# 提取图片部分(转换为[图片:描述]格式)
|
||||
pic_part = ""
|
||||
if picid_matches:
|
||||
@@ -411,7 +409,7 @@ class PrivateReplyer:
|
||||
else:
|
||||
pic_descriptions.append(f"[图片:{description}]")
|
||||
pic_part = "".join(pic_descriptions)
|
||||
|
||||
|
||||
return has_only_pics, has_text, pic_part, text_without_picids
|
||||
|
||||
async def build_keywords_reaction_prompt(self, target: Optional[str]) -> str:
|
||||
@@ -517,25 +515,27 @@ class PrivateReplyer:
|
||||
|
||||
# 获取基础personality
|
||||
prompt_personality = global_config.personality.personality
|
||||
|
||||
|
||||
# 检查是否需要随机替换为状态
|
||||
if (global_config.personality.states and
|
||||
global_config.personality.state_probability > 0 and
|
||||
random.random() < global_config.personality.state_probability):
|
||||
if (
|
||||
global_config.personality.states
|
||||
and global_config.personality.state_probability > 0
|
||||
and random.random() < global_config.personality.state_probability
|
||||
):
|
||||
# 随机选择一个状态替换personality
|
||||
selected_state = random.choice(global_config.personality.states)
|
||||
prompt_personality = selected_state
|
||||
|
||||
|
||||
prompt_personality = f"{prompt_personality};"
|
||||
return f"你的名字是{bot_name}{bot_nickname},你{prompt_personality}"
|
||||
|
||||
def _parse_chat_prompt_config_to_chat_id(self, chat_prompt_str: str) -> Optional[tuple[str, str]]:
|
||||
"""
|
||||
解析聊天prompt配置字符串并生成对应的 chat_id 和 prompt内容
|
||||
|
||||
|
||||
Args:
|
||||
chat_prompt_str: 格式为 "platform:id:type:prompt内容" 的字符串
|
||||
|
||||
|
||||
Returns:
|
||||
tuple: (chat_id, prompt_content),如果解析失败则返回 None
|
||||
"""
|
||||
@@ -571,10 +571,10 @@ class PrivateReplyer:
|
||||
def get_chat_prompt_for_chat(self, chat_id: str) -> str:
|
||||
"""
|
||||
根据聊天流ID获取匹配的额外prompt(仅匹配private类型)
|
||||
|
||||
|
||||
Args:
|
||||
chat_id: 聊天流ID(哈希值)
|
||||
|
||||
|
||||
Returns:
|
||||
str: 匹配的额外prompt内容,如果没有匹配则返回空字符串
|
||||
"""
|
||||
@@ -584,21 +584,21 @@ class PrivateReplyer:
|
||||
for chat_prompt_str in global_config.experimental.chat_prompts:
|
||||
if not isinstance(chat_prompt_str, str):
|
||||
continue
|
||||
|
||||
|
||||
# 解析配置字符串,检查类型是否为private
|
||||
parts = chat_prompt_str.split(":", 3)
|
||||
if len(parts) != 4:
|
||||
continue
|
||||
|
||||
|
||||
stream_type = parts[2]
|
||||
# 只匹配private类型
|
||||
if stream_type != "private":
|
||||
continue
|
||||
|
||||
|
||||
result = self._parse_chat_prompt_config_to_chat_id(chat_prompt_str)
|
||||
if result is None:
|
||||
continue
|
||||
|
||||
|
||||
config_chat_id, prompt_content = result
|
||||
if config_chat_id == chat_id:
|
||||
logger.debug(f"匹配到私聊prompt配置,chat_id: {chat_id}, prompt: {prompt_content[:50]}...")
|
||||
@@ -647,13 +647,11 @@ class PrivateReplyer:
|
||||
sender = person_name
|
||||
target = reply_message.processed_plain_text
|
||||
|
||||
|
||||
|
||||
target = replace_user_references(target, chat_stream.platform, replace_bot_name=True)
|
||||
|
||||
|
||||
# 在picid替换之前分析内容类型(防止prompt注入)
|
||||
has_only_pics, has_text, pic_part, text_part = self._analyze_target_content(target)
|
||||
|
||||
|
||||
# 将[picid:xxx]替换为具体的图片描述
|
||||
target = self._replace_picids_with_descriptions(target)
|
||||
|
||||
@@ -662,7 +660,7 @@ class PrivateReplyer:
|
||||
timestamp=time.time(),
|
||||
limit=global_config.chat.max_context_size,
|
||||
)
|
||||
|
||||
|
||||
dialogue_prompt = build_readable_messages(
|
||||
message_list_before_now_long,
|
||||
replace_bot_name=True,
|
||||
@@ -710,9 +708,7 @@ class PrivateReplyer:
|
||||
self._time_and_run_task(
|
||||
self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits"
|
||||
),
|
||||
self._time_and_run_task(
|
||||
self.build_relation_info(chat_talking_prompt_short, sender), "relation_info"
|
||||
),
|
||||
self._time_and_run_task(self.build_relation_info(chat_talking_prompt_short, sender), "relation_info"),
|
||||
self._time_and_run_task(
|
||||
self.build_tool_info(chat_talking_prompt_short, sender, target, enable_tool=enable_tool), "tool_info"
|
||||
),
|
||||
@@ -852,15 +848,13 @@ class PrivateReplyer:
|
||||
|
||||
sender, target = self._parse_reply_target(reply_to)
|
||||
target = replace_user_references(target, chat_stream.platform, replace_bot_name=True)
|
||||
|
||||
|
||||
# 在picid替换之前分析内容类型(防止prompt注入)
|
||||
has_only_pics, has_text, pic_part, text_part = self._analyze_target_content(target)
|
||||
|
||||
|
||||
# 将[picid:xxx]替换为具体的图片描述
|
||||
target = self._replace_picids_with_descriptions(target)
|
||||
|
||||
|
||||
|
||||
message_list_before_now_half = get_raw_msg_before_timestamp_with_chat(
|
||||
chat_id=chat_id,
|
||||
timestamp=time.time(),
|
||||
@@ -900,9 +894,7 @@ class PrivateReplyer:
|
||||
)
|
||||
elif has_text and pic_part:
|
||||
# 既有图片又有文字
|
||||
reply_target_block = (
|
||||
f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。"
|
||||
)
|
||||
reply_target_block = f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,你想要在群里发言或者回复这条消息。"
|
||||
else:
|
||||
# 只包含文字
|
||||
reply_target_block = (
|
||||
@@ -919,7 +911,9 @@ class PrivateReplyer:
|
||||
reply_target_block = f"现在{sender}发送的图片:{pic_part}。引起了你的注意,针对这条消息回复。"
|
||||
elif has_text and pic_part:
|
||||
# 既有图片又有文字
|
||||
reply_target_block = f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,针对这条消息回复。"
|
||||
reply_target_block = (
|
||||
f"现在{sender}发送了图片:{pic_part},并说:{text_part}。引起了你的注意,针对这条消息回复。"
|
||||
)
|
||||
else:
|
||||
# 只包含文字
|
||||
reply_target_block = f"现在{sender}说的:{text_part}。引起了你的注意,针对这条消息回复。"
|
||||
@@ -1010,7 +1004,7 @@ class PrivateReplyer:
|
||||
content, (reasoning_content, model_name, tool_calls) = await self.express_model.generate_response_async(
|
||||
prompt
|
||||
)
|
||||
|
||||
|
||||
content = content.strip()
|
||||
|
||||
logger.info(f"使用 {model_name} 生成回复内容: {content}")
|
||||
@@ -1102,6 +1096,3 @@ def weighted_sample_no_replacement(items, weights, k) -> list:
|
||||
pool.pop(idx)
|
||||
break
|
||||
return selected
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user