解决合并冲突:又是Merge这一块
This commit is contained in:
@@ -13,7 +13,7 @@ from src.config.api_ada_configs import TaskConfig
|
|||||||
from src.individuality.individuality import get_individuality
|
from src.individuality.individuality import get_individuality
|
||||||
from src.llm_models.utils_model import LLMRequest
|
from src.llm_models.utils_model import LLMRequest
|
||||||
from src.chat.message_receive.message import UserInfo, Seg, MessageRecv, MessageSending
|
from src.chat.message_receive.message import UserInfo, Seg, MessageRecv, MessageSending
|
||||||
from src.chat.message_receive.chat_stream import ChatStream
|
from src.chat.message_receive.chat_stream import ChatStream, get_chat_manager
|
||||||
from src.chat.message_receive.uni_message_sender import HeartFCSender
|
from src.chat.message_receive.uni_message_sender import HeartFCSender
|
||||||
from src.chat.utils.timer_calculator import Timer # <--- Import Timer
|
from src.chat.utils.timer_calculator import Timer # <--- Import Timer
|
||||||
from src.chat.utils.utils import get_chat_type_and_target_info
|
from src.chat.utils.utils import get_chat_type_and_target_info
|
||||||
@@ -22,6 +22,7 @@ from src.chat.utils.chat_message_builder import (
|
|||||||
build_readable_messages,
|
build_readable_messages,
|
||||||
get_raw_msg_before_timestamp_with_chat,
|
get_raw_msg_before_timestamp_with_chat,
|
||||||
replace_user_references_sync,
|
replace_user_references_sync,
|
||||||
|
build_readable_messages_with_id,
|
||||||
)
|
)
|
||||||
from src.chat.express.expression_selector import expression_selector
|
from src.chat.express.expression_selector import expression_selector
|
||||||
from src.chat.memory_system.memory_activator import MemoryActivator
|
from src.chat.memory_system.memory_activator import MemoryActivator
|
||||||
@@ -84,6 +85,7 @@ def init_prompt():
|
|||||||
{relation_info_block}
|
{relation_info_block}
|
||||||
{extra_info_block}
|
{extra_info_block}
|
||||||
|
|
||||||
|
{cross_context_block}
|
||||||
|
|
||||||
{identity}
|
{identity}
|
||||||
|
|
||||||
@@ -154,6 +156,7 @@ If you need to use the search tool, please directly call the function "lpmm_sear
|
|||||||
{relation_info_block}
|
{relation_info_block}
|
||||||
{extra_info_block}
|
{extra_info_block}
|
||||||
|
|
||||||
|
{cross_context_block}
|
||||||
{identity}
|
{identity}
|
||||||
如果有人说你是人机,你可以用一种阴阳怪气的口吻来回应
|
如果有人说你是人机,你可以用一种阴阳怪气的口吻来回应
|
||||||
{schedule_block}
|
{schedule_block}
|
||||||
@@ -227,15 +230,94 @@ class DefaultReplyer:
|
|||||||
self.heart_fc_sender = HeartFCSender()
|
self.heart_fc_sender = HeartFCSender()
|
||||||
self.memory_activator = MemoryActivator()
|
self.memory_activator = MemoryActivator()
|
||||||
# 使用纯向量瞬时记忆系统V2,支持自定义保留时间
|
# 使用纯向量瞬时记忆系统V2,支持自定义保留时间
|
||||||
self.instant_memory = VectorInstantMemoryV2(
|
self.instant_memory = VectorInstantMemoryV2(chat_id=self.chat_stream.stream_id, retention_hours=1)
|
||||||
chat_id=self.chat_stream.stream_id,
|
|
||||||
retention_hours=1
|
|
||||||
)
|
|
||||||
|
|
||||||
from src.plugin_system.core.tool_use import ToolExecutor # 延迟导入ToolExecutor,不然会循环依赖
|
from src.plugin_system.core.tool_use import ToolExecutor # 延迟导入ToolExecutor,不然会循环依赖
|
||||||
|
|
||||||
self.tool_executor = ToolExecutor(chat_id=self.chat_stream.stream_id, enable_cache=False)
|
self.tool_executor = ToolExecutor(chat_id=self.chat_stream.stream_id, enable_cache=False)
|
||||||
|
|
||||||
|
async def _build_cross_context_block(self, current_chat_id: str, target_user_info: Optional[Dict[str, Any]]) -> str:
|
||||||
|
"""构建跨群聊上下文"""
|
||||||
|
if not global_config.cross_context.enable:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 找到当前群聊所在的共享组
|
||||||
|
target_group = None
|
||||||
|
current_stream = get_chat_manager().get_stream(current_chat_id)
|
||||||
|
if not current_stream or not current_stream.group_info:
|
||||||
|
return ""
|
||||||
|
current_chat_raw_id = current_stream.group_info.group_id
|
||||||
|
|
||||||
|
for group in global_config.cross_context.groups:
|
||||||
|
if str(current_chat_raw_id) in group.chat_ids:
|
||||||
|
target_group = group
|
||||||
|
break
|
||||||
|
|
||||||
|
if not target_group:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
# 根据prompt_mode选择策略
|
||||||
|
prompt_mode = global_config.personality.prompt_mode
|
||||||
|
other_chat_raw_ids = [chat_id for chat_id in target_group.chat_ids if chat_id != str(current_chat_raw_id)]
|
||||||
|
|
||||||
|
cross_context_messages = []
|
||||||
|
|
||||||
|
if prompt_mode == "normal":
|
||||||
|
# normal模式:获取其他群聊的最近N条消息
|
||||||
|
for chat_raw_id in other_chat_raw_ids:
|
||||||
|
stream_id = get_chat_manager().get_stream_id(current_stream.platform, chat_raw_id, is_group=True)
|
||||||
|
if not stream_id:
|
||||||
|
continue
|
||||||
|
|
||||||
|
messages = get_raw_msg_before_timestamp_with_chat(
|
||||||
|
chat_id=stream_id,
|
||||||
|
timestamp=time.time(),
|
||||||
|
limit=5, # 可配置
|
||||||
|
)
|
||||||
|
if messages:
|
||||||
|
chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id
|
||||||
|
formatted_messages, _ = build_readable_messages_with_id(messages, timestamp_mode="relative")
|
||||||
|
cross_context_messages.append(f"[以下是来自“{chat_name}”的近期消息]\n{formatted_messages}")
|
||||||
|
|
||||||
|
elif prompt_mode == "s4u":
|
||||||
|
# s4u模式:获取当前发言用户在其他群聊的消息
|
||||||
|
if target_user_info:
|
||||||
|
user_id = target_user_info.get("user_id")
|
||||||
|
|
||||||
|
if user_id:
|
||||||
|
for chat_raw_id in other_chat_raw_ids:
|
||||||
|
stream_id = get_chat_manager().get_stream_id(
|
||||||
|
current_stream.platform, chat_raw_id, is_group=True
|
||||||
|
)
|
||||||
|
if not stream_id:
|
||||||
|
continue
|
||||||
|
|
||||||
|
messages = get_raw_msg_before_timestamp_with_chat(
|
||||||
|
chat_id=stream_id,
|
||||||
|
timestamp=time.time(),
|
||||||
|
limit=20, # 获取更多消息以供筛选
|
||||||
|
)
|
||||||
|
user_messages = [msg for msg in messages if msg.get("user_id") == user_id][
|
||||||
|
-5:
|
||||||
|
] # 筛选并取最近5条
|
||||||
|
|
||||||
|
if user_messages:
|
||||||
|
chat_name = get_chat_manager().get_stream_name(stream_id) or stream_id
|
||||||
|
user_name = (
|
||||||
|
target_user_info.get("person_name") or target_user_info.get("user_nickname") or user_id
|
||||||
|
)
|
||||||
|
formatted_messages, _ = build_readable_messages_with_id(
|
||||||
|
user_messages, timestamp_mode="relative"
|
||||||
|
)
|
||||||
|
cross_context_messages.append(
|
||||||
|
f"[以下是“{user_name}”在“{chat_name}”的近期发言]\n{formatted_messages}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not cross_context_messages:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
return "# 跨群上下文参考\n" + "\n\n".join(cross_context_messages) + "\n"
|
||||||
|
|
||||||
def _select_weighted_models_config(self) -> Tuple[TaskConfig, float]:
|
def _select_weighted_models_config(self) -> Tuple[TaskConfig, float]:
|
||||||
"""使用加权随机选择来挑选一个模型配置"""
|
"""使用加权随机选择来挑选一个模型配置"""
|
||||||
configs = self.model_set
|
configs = self.model_set
|
||||||
@@ -494,27 +576,22 @@ class DefaultReplyer:
|
|||||||
try:
|
try:
|
||||||
from src.chat.memory_system.async_memory_optimizer import (
|
from src.chat.memory_system.async_memory_optimizer import (
|
||||||
retrieve_memory_nonblocking,
|
retrieve_memory_nonblocking,
|
||||||
store_memory_nonblocking
|
store_memory_nonblocking,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 异步存储聊天历史(非阻塞)
|
# 异步存储聊天历史(非阻塞)
|
||||||
asyncio.create_task(store_memory_nonblocking(
|
asyncio.create_task(
|
||||||
chat_id=self.chat_stream.stream_id,
|
store_memory_nonblocking(chat_id=self.chat_stream.stream_id, content=chat_history)
|
||||||
content=chat_history
|
)
|
||||||
))
|
|
||||||
|
|
||||||
# 尝试从缓存获取瞬时记忆
|
# 尝试从缓存获取瞬时记忆
|
||||||
instant_memory = await retrieve_memory_nonblocking(
|
instant_memory = await retrieve_memory_nonblocking(chat_id=self.chat_stream.stream_id, query=target)
|
||||||
chat_id=self.chat_stream.stream_id,
|
|
||||||
query=target
|
|
||||||
)
|
|
||||||
|
|
||||||
# 如果没有缓存结果,快速检索一次
|
# 如果没有缓存结果,快速检索一次
|
||||||
if instant_memory is None:
|
if instant_memory is None:
|
||||||
try:
|
try:
|
||||||
instant_memory = await asyncio.wait_for(
|
instant_memory = await asyncio.wait_for(
|
||||||
self.instant_memory.get_memory_for_context(target),
|
self.instant_memory.get_memory_for_context(target), timeout=1.5
|
||||||
timeout=1.5
|
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.warning("瞬时记忆检索超时,使用空结果")
|
logger.warning("瞬时记忆检索超时,使用空结果")
|
||||||
@@ -533,7 +610,7 @@ class DefaultReplyer:
|
|||||||
try:
|
try:
|
||||||
instant_memory = await asyncio.wait_for(
|
instant_memory = await asyncio.wait_for(
|
||||||
self.instant_memory.get_memory_for_context(target),
|
self.instant_memory.get_memory_for_context(target),
|
||||||
timeout=1.0 # 最保守的1秒超时
|
timeout=1.0, # 最保守的1秒超时
|
||||||
)
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.warning("瞬时记忆检索超时,跳过记忆获取")
|
logger.warning("瞬时记忆检索超时,跳过记忆获取")
|
||||||
@@ -885,7 +962,12 @@ class DefaultReplyer:
|
|||||||
show_actions=True,
|
show_actions=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 并行执行五个构建任务
|
# 获取目标用户信息,用于s4u模式
|
||||||
|
target_user_info = None
|
||||||
|
if sender:
|
||||||
|
target_user_info = await person_info_manager.get_person_info_by_name(sender)
|
||||||
|
|
||||||
|
# 并行执行六个构建任务
|
||||||
task_results = await asyncio.gather(
|
task_results = await asyncio.gather(
|
||||||
self._time_and_run_task(
|
self._time_and_run_task(
|
||||||
self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits"
|
self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits"
|
||||||
@@ -896,6 +978,7 @@ class DefaultReplyer:
|
|||||||
self.build_tool_info(chat_talking_prompt_short, reply_to, enable_tool=enable_tool), "tool_info"
|
self.build_tool_info(chat_talking_prompt_short, reply_to, enable_tool=enable_tool), "tool_info"
|
||||||
),
|
),
|
||||||
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, reply_to), "prompt_info"),
|
self._time_and_run_task(self.get_prompt_info(chat_talking_prompt_short, reply_to), "prompt_info"),
|
||||||
|
self._time_and_run_task(self._build_cross_context_block(chat_id, target_user_info), "cross_context"),
|
||||||
)
|
)
|
||||||
|
|
||||||
# 任务名称中英文映射
|
# 任务名称中英文映射
|
||||||
@@ -922,7 +1005,8 @@ class DefaultReplyer:
|
|||||||
relation_info = results_dict["relation_info"]
|
relation_info = results_dict["relation_info"]
|
||||||
memory_block = results_dict["memory_block"]
|
memory_block = results_dict["memory_block"]
|
||||||
tool_info = results_dict["tool_info"]
|
tool_info = results_dict["tool_info"]
|
||||||
prompt_info = results_dict["prompt_info"] # 直接使用格式化后的结果
|
prompt_info = results_dict["prompt_info"]
|
||||||
|
cross_context_block = results_dict["cross_context"]
|
||||||
|
|
||||||
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
keywords_reaction_prompt = await self.build_keywords_reaction_prompt(target)
|
||||||
|
|
||||||
@@ -1074,13 +1158,14 @@ class DefaultReplyer:
|
|||||||
identity=identity_block,
|
identity=identity_block,
|
||||||
schedule_block=schedule_block,
|
schedule_block=schedule_block,
|
||||||
action_descriptions=action_descriptions,
|
action_descriptions=action_descriptions,
|
||||||
time_block=time_block, # 保留time_block参数
|
time_block=time_block,
|
||||||
chat_info=chat_info,
|
chat_info=chat_info,
|
||||||
reply_target_block=reply_target_block,
|
reply_target_block=reply_target_block,
|
||||||
mood_state=mood_prompt,
|
mood_state=mood_prompt,
|
||||||
config_expression_style=config_expression_style,
|
config_expression_style=config_expression_style,
|
||||||
keywords_reaction_prompt=keywords_reaction_prompt,
|
keywords_reaction_prompt=keywords_reaction_prompt,
|
||||||
moderation_prompt=moderation_prompt_block,
|
moderation_prompt=moderation_prompt_block,
|
||||||
|
cross_context_block=cross_context_block,
|
||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
@@ -1095,7 +1180,7 @@ class DefaultReplyer:
|
|||||||
test_prompt = await global_prompt_manager.get_prompt_async(template_name)
|
test_prompt = await global_prompt_manager.get_prompt_async(template_name)
|
||||||
logger.debug(f"[Prompt模式调试] 找到s4u模板 {template_name}, 内容预览: {test_prompt[:100]}...")
|
logger.debug(f"[Prompt模式调试] 找到s4u模板 {template_name}, 内容预览: {test_prompt[:100]}...")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
#理论上我觉得这玩意没多大可能炸就是了
|
# 理论上我觉得这玩意没多大可能炸就是了
|
||||||
logger.error(f"[Prompt模式调试] s4u模板 {template_name} 不存在或获取失败: {e}")
|
logger.error(f"[Prompt模式调试] s4u模板 {template_name} 不存在或获取失败: {e}")
|
||||||
|
|
||||||
result = await global_prompt_manager.format_prompt(
|
result = await global_prompt_manager.format_prompt(
|
||||||
@@ -1119,6 +1204,7 @@ class DefaultReplyer:
|
|||||||
reply_style=global_config.personality.reply_style,
|
reply_style=global_config.personality.reply_style,
|
||||||
keywords_reaction_prompt=keywords_reaction_prompt,
|
keywords_reaction_prompt=keywords_reaction_prompt,
|
||||||
moderation_prompt=moderation_prompt_block,
|
moderation_prompt=moderation_prompt_block,
|
||||||
|
cross_context_block=cross_context_block,
|
||||||
)
|
)
|
||||||
logger.debug(f"[Prompt模式调试] s4u format_prompt调用完成,结果预览: {result[:200]}...")
|
logger.debug(f"[Prompt模式调试] s4u format_prompt调用完成,结果预览: {result[:200]}...")
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ from src.config.official_configs import (
|
|||||||
AntiPromptInjectionConfig,
|
AntiPromptInjectionConfig,
|
||||||
PluginsConfig,
|
PluginsConfig,
|
||||||
WakeUpSystemConfig,
|
WakeUpSystemConfig,
|
||||||
MonthlyPlanSystemConfig
|
MonthlyPlanSystemConfig,
|
||||||
|
CrossContextConfig
|
||||||
)
|
)
|
||||||
|
|
||||||
from .api_ada_configs import (
|
from .api_ada_configs import (
|
||||||
@@ -392,6 +393,7 @@ class Config(ValidatedConfigBase):
|
|||||||
plugins: PluginsConfig = Field(default_factory=lambda: PluginsConfig(), description="插件配置")
|
plugins: PluginsConfig = Field(default_factory=lambda: PluginsConfig(), description="插件配置")
|
||||||
wakeup_system: WakeUpSystemConfig = Field(default_factory=lambda: WakeUpSystemConfig(), description="唤醒度系统配置")
|
wakeup_system: WakeUpSystemConfig = Field(default_factory=lambda: WakeUpSystemConfig(), description="唤醒度系统配置")
|
||||||
monthly_plan_system: MonthlyPlanSystemConfig = Field(default_factory=lambda: MonthlyPlanSystemConfig(), description="月层计划系统配置")
|
monthly_plan_system: MonthlyPlanSystemConfig = Field(default_factory=lambda: MonthlyPlanSystemConfig(), description="月层计划系统配置")
|
||||||
|
cross_context: CrossContextConfig = Field(default_factory=lambda: CrossContextConfig(), description="跨群聊上下文共享配置")
|
||||||
|
|
||||||
|
|
||||||
class APIAdapterConfig(ValidatedConfigBase):
|
class APIAdapterConfig(ValidatedConfigBase):
|
||||||
|
|||||||
@@ -685,3 +685,15 @@ class MonthlyPlanSystemConfig(ValidatedConfigBase):
|
|||||||
generation_threshold: int = Field(default=10, ge=0, description="启动时,如果当月计划少于此数量,则触发LLM生成")
|
generation_threshold: int = Field(default=10, ge=0, description="启动时,如果当月计划少于此数量,则触发LLM生成")
|
||||||
plans_per_generation: int = Field(default=5, ge=1, description="每次调用LLM期望生成的计划数量")
|
plans_per_generation: int = Field(default=5, ge=1, description="每次调用LLM期望生成的计划数量")
|
||||||
deletion_probability_on_use: float = Field(default=0.5, ge=0.0, le=1.0, description="计划被使用后,被删除的概率")
|
deletion_probability_on_use: float = Field(default=0.5, ge=0.0, le=1.0, description="计划被使用后,被删除的概率")
|
||||||
|
|
||||||
|
|
||||||
|
class ContextGroup(ValidatedConfigBase):
|
||||||
|
"""上下文共享组配置"""
|
||||||
|
name: str = Field(..., description="共享组的名称")
|
||||||
|
chat_ids: List[str] = Field(..., description="属于该组的聊天ID列表")
|
||||||
|
|
||||||
|
|
||||||
|
class CrossContextConfig(ValidatedConfigBase):
|
||||||
|
"""跨群聊上下文共享配置"""
|
||||||
|
enable: bool = Field(default=False, description="是否启用跨群聊上下文共享功能")
|
||||||
|
groups: List[ContextGroup] = Field(default_factory=list, description="上下文共享组列表")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class NoReplyAction(BaseAction):
|
|||||||
|
|
||||||
focus_activation_type = ActionActivationType.ALWAYS # 修复:在focus模式下应该始终可用
|
focus_activation_type = ActionActivationType.ALWAYS # 修复:在focus模式下应该始终可用
|
||||||
normal_activation_type = ActionActivationType.ALWAYS # 修复:在normal模式下应该始终可用
|
normal_activation_type = ActionActivationType.ALWAYS # 修复:在normal模式下应该始终可用
|
||||||
mode_enable = ChatMode.FOCUS
|
mode_enable = ChatMode.FOCUS # 修复:只在专注模式下有用
|
||||||
parallel_action = False
|
parallel_action = False
|
||||||
|
|
||||||
# 动作基本信息
|
# 动作基本信息
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class ReplyAction(BaseAction):
|
|||||||
|
|
||||||
focus_activation_type = ActionActivationType.ALWAYS
|
focus_activation_type = ActionActivationType.ALWAYS
|
||||||
normal_activation_type = ActionActivationType.ALWAYS
|
normal_activation_type = ActionActivationType.ALWAYS
|
||||||
mode_enable = ChatMode.FOCUS | ChatMode.NORMAL
|
mode_enable = ChatMode.ALL
|
||||||
parallel_action = False
|
parallel_action = False
|
||||||
|
|
||||||
# 动作基本信息
|
# 动作基本信息
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[inner]
|
[inner]
|
||||||
version = "6.4.1"
|
version = "6.4.2"
|
||||||
|
|
||||||
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
#----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读----
|
||||||
#如果你想要修改配置文件,请递增version的值
|
#如果你想要修改配置文件,请递增version的值
|
||||||
@@ -428,3 +428,24 @@ group_mention_increment = 2.0 #"群聊艾特增加的唤醒度"
|
|||||||
decay_rate = 0.2 #"每次衰减的唤醒度数值"
|
decay_rate = 0.2 #"每次衰减的唤醒度数值"
|
||||||
decay_interval = 30.0 #"唤醒度衰减间隔(秒)"
|
decay_interval = 30.0 #"唤醒度衰减间隔(秒)"
|
||||||
angry_duration = 300.0 #"愤怒状态持续时间(秒)"
|
angry_duration = 300.0 #"愤怒状态持续时间(秒)"
|
||||||
|
|
||||||
|
[cross_context] # 跨群聊上下文共享配置
|
||||||
|
# 这是总开关,用于一键启用或禁用此功能
|
||||||
|
enable = false
|
||||||
|
|
||||||
|
# 在这里定义您的“共享组”
|
||||||
|
# 只有在同一个组内的群聊才会共享上下文
|
||||||
|
# 注意:这里的chat_ids需要填写群号,而不是哈希过的ID
|
||||||
|
[[cross_context.groups]]
|
||||||
|
name = "项目A技术讨论组"
|
||||||
|
chat_ids = [
|
||||||
|
"111111", # 假设这是“开发群”的ID
|
||||||
|
"222222" # 假设这是“产品群”的ID
|
||||||
|
]
|
||||||
|
|
||||||
|
[[cross_context.groups]]
|
||||||
|
name = "日常闲聊组"
|
||||||
|
chat_ids = [
|
||||||
|
"333333", # 假设这是“吹水群”的ID
|
||||||
|
"444444" # 假设这是“游戏群”的ID
|
||||||
|
]
|
||||||
Reference in New Issue
Block a user