fix:提供了预制菜UI来修改配置文件

This commit is contained in:
SengokuCola
2025-04-07 14:07:00 +08:00
parent ff46d5a7d2
commit a2eb877d9d
5 changed files with 1590 additions and 27 deletions

1
.gitignore vendored
View File

@@ -4,6 +4,7 @@ mongodb/
NapCat.Framework.Windows.Once/ NapCat.Framework.Windows.Once/
log/ log/
logs/ logs/
run_ad.bat
MaiBot-Napcat-Adapter-main MaiBot-Napcat-Adapter-main
/test /test
/src/test /src/test

View File

@@ -18,6 +18,7 @@ from .chat_observer import ChatObserver
from .pfc_KnowledgeFetcher import KnowledgeFetcher from .pfc_KnowledgeFetcher import KnowledgeFetcher
from .reply_checker import ReplyChecker from .reply_checker import ReplyChecker
from .pfc_utils import get_items_from_json from .pfc_utils import get_items_from_json
from src.individuality.individuality import Individuality
import time import time
logger = get_module_logger("pfc") logger = get_module_logger("pfc")
@@ -51,7 +52,7 @@ class ActionPlanner:
max_tokens=1000, max_tokens=1000,
request_type="action_planning" request_type="action_planning"
) )
self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.personality_info = Individuality.get_instance().get_prompt(type = "personality", x_person = 2, level = 2)
self.name = global_config.BOT_NICKNAME self.name = global_config.BOT_NICKNAME
self.chat_observer = ChatObserver.get_instance(stream_id) self.chat_observer = ChatObserver.get_instance(stream_id)
@@ -67,7 +68,6 @@ class ActionPlanner:
Args: Args:
goal: 对话目标 goal: 对话目标
method: 实现方式
reasoning: 目标原因 reasoning: 目标原因
action_history: 行动历史记录 action_history: 行动历史记录
@@ -166,11 +166,14 @@ class GoalAnalyzer:
request_type="conversation_goal" request_type="conversation_goal"
) )
self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.personality_info = Individuality.get_instance().get_prompt(type = "personality", x_person = 2, level = 2)
self.name = global_config.BOT_NICKNAME self.name = global_config.BOT_NICKNAME
self.nick_name = global_config.BOT_ALIAS_NAMES self.nick_name = global_config.BOT_ALIAS_NAMES
self.chat_observer = ChatObserver.get_instance(stream_id) self.chat_observer = ChatObserver.get_instance(stream_id)
# 多目标存储结构
self.goals = [] # 存储多个目标
self.max_goals = 3 # 同时保持的最大目标数量
self.current_goal_and_reason = None self.current_goal_and_reason = None
async def analyze_goal(self) -> Tuple[str, str, str]: async def analyze_goal(self) -> Tuple[str, str, str]:
@@ -198,11 +201,28 @@ class GoalAnalyzer:
personality_text = f"你的名字是{self.name}{self.personality_info}" personality_text = f"你的名字是{self.name}{self.personality_info}"
prompt = f"""{personality_text}。现在你在参与一场QQ聊天请分析以下聊天记录并根据你的性格特征确定一个明确的对话目标。 # 构建当前已有目标的文本
这个目标应该反映出对话的意图和期望的结果。 existing_goals_text = ""
if self.goals:
existing_goals_text = "当前已有的对话目标:\n"
for i, (goal, _, reason) in enumerate(self.goals):
existing_goals_text += f"{i+1}. 目标: {goal}, 原因: {reason}\n"
prompt = f"""{personality_text}。现在你在参与一场QQ聊天请分析以下聊天记录并根据你的性格特征确定多个明确的对话目标。
这些目标应该反映出对话的不同方面和意图。
{existing_goals_text}
聊天记录: 聊天记录:
{chat_history_text} {chat_history_text}
请以JSON格式输出包含以下字段
请分析当前对话并确定最适合的对话目标。你可以:
1. 保持现有目标不变
2. 修改现有目标
3. 添加新目标
4. 删除不再相关的目标
请以JSON格式输出一个当前最主要的对话目标包含以下字段
1. goal: 对话目标(简短的一句话) 1. goal: 对话目标(简短的一句话)
2. reasoning: 对话原因,为什么设定这个目标(简要解释) 2. reasoning: 对话原因,为什么设定这个目标(简要解释)
@@ -232,6 +252,15 @@ class GoalAnalyzer:
# 使用默认的方法 # 使用默认的方法
method = "以友好的态度回应" method = "以友好的态度回应"
# 更新目标列表
await self._update_goals(goal, method, reasoning)
# 返回当前最主要的目标
if self.goals:
current_goal, current_method, current_reasoning = self.goals[0]
return current_goal, current_method, current_reasoning
else:
return goal, method, reasoning return goal, method, reasoning
except Exception as e: except Exception as e:
@@ -243,7 +272,68 @@ class GoalAnalyzer:
# 所有重试都失败后的默认返回 # 所有重试都失败后的默认返回
return "保持友好的对话", "以友好的态度回应", "确保对话顺利进行" return "保持友好的对话", "以友好的态度回应", "确保对话顺利进行"
async def analyze_conversation(self,goal,reasoning): async def _update_goals(self, new_goal: str, method: str, reasoning: str):
"""更新目标列表
Args:
new_goal: 新的目标
method: 实现目标的方法
reasoning: 目标的原因
"""
# 检查新目标是否与现有目标相似
for i, (existing_goal, _, _) in enumerate(self.goals):
if self._calculate_similarity(new_goal, existing_goal) > 0.7: # 相似度阈值
# 更新现有目标
self.goals[i] = (new_goal, method, reasoning)
# 将此目标移到列表前面(最主要的位置)
self.goals.insert(0, self.goals.pop(i))
return
# 添加新目标到列表前面
self.goals.insert(0, (new_goal, method, reasoning))
# 限制目标数量
if len(self.goals) > self.max_goals:
self.goals.pop() # 移除最老的目标
def _calculate_similarity(self, goal1: str, goal2: str) -> float:
"""简单计算两个目标之间的相似度
这里使用一个简单的实现,实际可以使用更复杂的文本相似度算法
Args:
goal1: 第一个目标
goal2: 第二个目标
Returns:
float: 相似度得分 (0-1)
"""
# 简单实现:检查重叠字数比例
words1 = set(goal1)
words2 = set(goal2)
overlap = len(words1.intersection(words2))
total = len(words1.union(words2))
return overlap / total if total > 0 else 0
async def get_all_goals(self) -> List[Tuple[str, str, str]]:
"""获取所有当前目标
Returns:
List[Tuple[str, str, str]]: 目标列表,每项为(目标, 方法, 原因)
"""
return self.goals.copy()
async def get_alternative_goals(self) -> List[Tuple[str, str, str]]:
"""获取除了当前主要目标外的其他备选目标
Returns:
List[Tuple[str, str, str]]: 备选目标列表
"""
if len(self.goals) <= 1:
return []
return self.goals[1:].copy()
async def analyze_conversation(self, goal, reasoning):
messages = self.chat_observer.get_message_history() messages = self.chat_observer.get_message_history()
chat_history_text = "" chat_history_text = ""
for msg in messages: for msg in messages:
@@ -293,6 +383,16 @@ class GoalAnalyzer:
if not success: if not success:
return False, False, "确保对话顺利进行" return False, False, "确保对话顺利进行"
# 如果当前目标达成,从目标列表中移除
if result["goal_achieved"] and not result["stop_conversation"]:
for i, (g, _, _) in enumerate(self.goals):
if g == goal:
self.goals.pop(i)
# 如果还有其他目标,不停止对话
if self.goals:
result["stop_conversation"] = False
break
return result["goal_achieved"], result["stop_conversation"], result["reason"] return result["goal_achieved"], result["stop_conversation"], result["reason"]
except Exception as e: except Exception as e:
@@ -304,7 +404,7 @@ class Waiter:
"""快 速 等 待""" """快 速 等 待"""
def __init__(self, stream_id: str): def __init__(self, stream_id: str):
self.chat_observer = ChatObserver.get_instance(stream_id) self.chat_observer = ChatObserver.get_instance(stream_id)
self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.personality_info = Individuality.get_instance().get_prompt(type = "personality", x_person = 2, level = 2)
self.name = global_config.BOT_NICKNAME self.name = global_config.BOT_NICKNAME
async def wait(self) -> bool: async def wait(self) -> bool:
@@ -318,8 +418,8 @@ class Waiter:
await asyncio.sleep(1) await asyncio.sleep(1)
logger.info("等待中...") logger.info("等待中...")
# 检查是否超过60秒 # 检查是否超过60秒
if time.time() - wait_start_time > 60: if time.time() - wait_start_time > 300:
logger.info("等待超过60秒结束对话") logger.info("等待超过300秒结束对话")
return True return True
logger.info("等待结束") logger.info("等待结束")
return False return False
@@ -335,7 +435,7 @@ class ReplyGenerator:
max_tokens=300, max_tokens=300,
request_type="reply_generation" request_type="reply_generation"
) )
self.personality_info = " ".join(global_config.PROMPT_PERSONALITY) self.personality_info = Individuality.get_instance().get_prompt(type = "personality", x_person = 2, level = 2)
self.name = global_config.BOT_NICKNAME self.name = global_config.BOT_NICKNAME
self.chat_observer = ChatObserver.get_instance(stream_id) self.chat_observer = ChatObserver.get_instance(stream_id)
self.reply_checker = ReplyChecker(stream_id) self.reply_checker = ReplyChecker(stream_id)
@@ -645,6 +745,38 @@ class Conversation:
if not is_suitable: if not is_suitable:
logger.warning(f"生成的回复不合适,原因: {reason}") logger.warning(f"生成的回复不合适,原因: {reason}")
if need_replan: if need_replan:
# 尝试切换到其他备选目标
alternative_goals = await self.goal_analyzer.get_alternative_goals()
if alternative_goals:
# 有备选目标,尝试使用下一个目标
self.current_goal, self.current_method, self.goal_reasoning = alternative_goals[0]
logger.info(f"切换到备选目标: {self.current_goal}")
# 使用新目标生成回复
self.generated_reply = await self.reply_generator.generate(
self.current_goal,
self.current_method,
[self._convert_to_message(msg) for msg in messages],
self.knowledge_cache
)
# 检查使用新目标生成的回复是否合适
is_suitable, reason, _ = await self.reply_generator.check_reply(
self.generated_reply,
self.current_goal
)
if is_suitable:
# 如果新目标的回复合适,调整目标优先级
await self.goal_analyzer._update_goals(
self.current_goal,
self.current_method,
self.goal_reasoning
)
else:
# 如果新目标还是不合适,重新思考目标
self.state = ConversationState.RETHINKING
self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal()
return
else:
# 没有备选目标,重新分析
self.state = ConversationState.RETHINKING self.state = ConversationState.RETHINKING
self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal() self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal()
return return
@@ -662,6 +794,22 @@ class Conversation:
if not is_suitable: if not is_suitable:
logger.warning(f"生成的回复不合适,原因: {reason}") logger.warning(f"生成的回复不合适,原因: {reason}")
if need_replan: if need_replan:
# 尝试切换到其他备选目标
alternative_goals = await self.goal_analyzer.get_alternative_goals()
if alternative_goals:
# 有备选目标,尝试使用下一个目标
self.current_goal, self.current_method, self.goal_reasoning = alternative_goals[0]
logger.info(f"切换到备选目标: {self.current_goal}")
# 使用新目标生成回复
self.generated_reply = await self.reply_generator.generate(
self.current_goal,
self.current_method,
[self._convert_to_message(msg) for msg in messages],
self.knowledge_cache
)
is_suitable = True # 假设使用新目标后回复是合适的
else:
# 没有备选目标,重新分析
self.state = ConversationState.RETHINKING self.state = ConversationState.RETHINKING
self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal() self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal()
return return
@@ -705,6 +853,28 @@ class Conversation:
if not is_suitable: if not is_suitable:
logger.warning(f"生成的回复不合适,原因: {reason}") logger.warning(f"生成的回复不合适,原因: {reason}")
if need_replan: if need_replan:
# 尝试切换到其他备选目标
alternative_goals = await self.goal_analyzer.get_alternative_goals()
if alternative_goals:
# 有备选目标,尝试使用
self.current_goal, self.current_method, self.goal_reasoning = alternative_goals[0]
logger.info(f"切换到备选目标: {self.current_goal}")
# 使用新目标获取知识并生成回复
knowledge, sources = await self.knowledge_fetcher.fetch(
self.current_goal,
[self._convert_to_message(msg) for msg in messages]
)
if knowledge != "未找到相关知识":
self.knowledge_cache[sources] = knowledge
self.generated_reply = await self.reply_generator.generate(
self.current_goal,
self.current_method,
[self._convert_to_message(msg) for msg in messages],
self.knowledge_cache
)
else:
# 没有备选目标,重新分析
self.state = ConversationState.RETHINKING self.state = ConversationState.RETHINKING
self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal() self.current_goal, self.current_method, self.goal_reasoning = await self.goal_analyzer.analyze_goal()
return return
@@ -727,6 +897,16 @@ class Conversation:
elif action == "judge_conversation": elif action == "judge_conversation":
self.state = ConversationState.JUDGING self.state = ConversationState.JUDGING
self.goal_achieved, self.stop_conversation, self.reason = await self.goal_analyzer.analyze_conversation(self.current_goal, self.goal_reasoning) self.goal_achieved, self.stop_conversation, self.reason = await self.goal_analyzer.analyze_conversation(self.current_goal, self.goal_reasoning)
# 如果当前目标达成但还有其他目标
if self.goal_achieved and not self.stop_conversation:
alternative_goals = await self.goal_analyzer.get_alternative_goals()
if alternative_goals:
# 切换到下一个目标
self.current_goal, self.current_method, self.goal_reasoning = alternative_goals[0]
logger.info(f"当前目标已达成,切换到新目标: {self.current_goal}")
return
if self.stop_conversation: if self.stop_conversation:
await self._stop_conversation() await self._stop_conversation()

1382
temp_utils_ui/temp_ui.py Normal file

File diff suppressed because it is too large Load Diff

View File

BIN
配置文件修改器.exe Normal file

Binary file not shown.