feat: 重命名Kokoro Flow Chatter V2为Kokoro Flow Chatter,更新相关模块和配置
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Kokoro Flow Chatter V2 - 私聊特化的心流聊天器
|
Kokoro Flow Chatter - 私聊特化的心流聊天器
|
||||||
|
|
||||||
重构版本,核心设计理念:
|
重构版本,核心设计理念:
|
||||||
1. Chatter 职责极简化:只负责"收到消息 → 规划执行"
|
1. Chatter 职责极简化:只负责"收到消息 → 规划执行"
|
||||||
@@ -18,7 +18,7 @@ from .models import (
|
|||||||
LLMResponse,
|
LLMResponse,
|
||||||
)
|
)
|
||||||
from .session import KokoroSession, SessionManager, get_session_manager
|
from .session import KokoroSession, SessionManager, get_session_manager
|
||||||
from .chatter import KokoroFlowChatterV2
|
from .chatter import KokoroFlowChatter
|
||||||
from .replyer import generate_response
|
from .replyer import generate_response
|
||||||
from .proactive_thinker import (
|
from .proactive_thinker import (
|
||||||
ProactiveThinker,
|
ProactiveThinker,
|
||||||
@@ -27,12 +27,12 @@ from .proactive_thinker import (
|
|||||||
stop_proactive_thinker,
|
stop_proactive_thinker,
|
||||||
)
|
)
|
||||||
from .config import (
|
from .config import (
|
||||||
KokoroFlowChatterV2Config,
|
KokoroFlowChatterConfig,
|
||||||
get_config,
|
get_config,
|
||||||
load_config,
|
load_config,
|
||||||
reload_config,
|
reload_config,
|
||||||
)
|
)
|
||||||
from .plugin import KokoroFlowChatterV2Plugin
|
from .plugin import KokoroFlowChatterPlugin
|
||||||
from src.plugin_system.base.plugin_metadata import PluginMetadata
|
from src.plugin_system.base.plugin_metadata import PluginMetadata
|
||||||
|
|
||||||
__plugin_meta__ = PluginMetadata(
|
__plugin_meta__ = PluginMetadata(
|
||||||
@@ -59,7 +59,7 @@ __all__ = [
|
|||||||
"SessionManager",
|
"SessionManager",
|
||||||
"get_session_manager",
|
"get_session_manager",
|
||||||
# Core Components
|
# Core Components
|
||||||
"KokoroFlowChatterV2",
|
"KokoroFlowChatter",
|
||||||
"generate_response",
|
"generate_response",
|
||||||
# Proactive Thinker
|
# Proactive Thinker
|
||||||
"ProactiveThinker",
|
"ProactiveThinker",
|
||||||
@@ -67,11 +67,11 @@ __all__ = [
|
|||||||
"start_proactive_thinker",
|
"start_proactive_thinker",
|
||||||
"stop_proactive_thinker",
|
"stop_proactive_thinker",
|
||||||
# Config
|
# Config
|
||||||
"KokoroFlowChatterV2Config",
|
"KokoroFlowChatterConfig",
|
||||||
"get_config",
|
"get_config",
|
||||||
"load_config",
|
"load_config",
|
||||||
"reload_config",
|
"reload_config",
|
||||||
# Plugin
|
# Plugin
|
||||||
"KokoroFlowChatterV2Plugin",
|
"KokoroFlowChatterPlugin",
|
||||||
"__plugin_meta__",
|
"__plugin_meta__",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
KFC V2 回复动作模块
|
KFC 回复动作模块
|
||||||
|
|
||||||
KFC 的 reply 动作与 AFC 不同:
|
KFC 的 reply 动作与 AFC 不同:
|
||||||
- 不调用 LLM 生成回复,content 由 Replyer 提前生成
|
- 不调用 LLM 生成回复,content 由 Replyer 提前生成
|
||||||
@@ -17,12 +17,12 @@ logger = get_logger("kfc_reply_action")
|
|||||||
|
|
||||||
class KFCReplyAction(BaseAction):
|
class KFCReplyAction(BaseAction):
|
||||||
"""KFC Reply 动作 - 发送已生成的回复内容
|
"""KFC Reply 动作 - 发送已生成的回复内容
|
||||||
|
|
||||||
特点:
|
特点:
|
||||||
- 不调用 LLM,直接发送 content 参数中的内容
|
- 不调用 LLM,直接发送 content 参数中的内容
|
||||||
- content 由 Replyer 提前生成
|
- content 由 Replyer 提前生成
|
||||||
- 仅限 KokoroFlowChatterV2 使用
|
- 仅限 KokoroFlowChatter 使用
|
||||||
|
|
||||||
注意:使用 kfc_reply 作为动作名称以避免与 AFC 的 reply 动作冲突
|
注意:使用 kfc_reply 作为动作名称以避免与 AFC 的 reply 动作冲突
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -35,8 +35,8 @@ class KFCReplyAction(BaseAction):
|
|||||||
mode_enable = ChatMode.ALL
|
mode_enable = ChatMode.ALL
|
||||||
parallel_action = False
|
parallel_action = False
|
||||||
|
|
||||||
# Chatter 限制:仅允许 KokoroFlowChatterV2 使用
|
# Chatter 限制:仅允许 KokoroFlowChatter 使用
|
||||||
chatter_allow: ClassVar[list[str]] = ["KokoroFlowChatterV2"]
|
chatter_allow: ClassVar[list[str]] = ["KokoroFlowChatter"]
|
||||||
|
|
||||||
# 动作参数定义
|
# 动作参数定义
|
||||||
action_parameters: ClassVar = {
|
action_parameters: ClassVar = {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Kokoro Flow Chatter V2 - Chatter 主类
|
Kokoro Flow Chatter - Chatter 主类
|
||||||
|
|
||||||
极简设计,只负责:
|
极简设计,只负责:
|
||||||
1. 收到消息
|
1. 收到消息
|
||||||
@@ -25,30 +25,30 @@ from .session import get_session_manager
|
|||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
logger = get_logger("kfc_v2_chatter")
|
logger = get_logger("kfc_chatter")
|
||||||
|
|
||||||
# 控制台颜色
|
# 控制台颜色
|
||||||
SOFT_PURPLE = "\033[38;5;183m"
|
SOFT_PURPLE = "\033[38;5;183m"
|
||||||
RESET = "\033[0m"
|
RESET = "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
class KokoroFlowChatterV2(BaseChatter):
|
class KokoroFlowChatter(BaseChatter):
|
||||||
"""
|
"""
|
||||||
Kokoro Flow Chatter V2 - 私聊特化的心流聊天器
|
Kokoro Flow Chatter - 私聊特化的心流聊天器
|
||||||
|
|
||||||
核心设计:
|
核心设计:
|
||||||
- Chatter 只负责 "收到消息 → 规划执行" 的流程
|
- Chatter 只负责 "收到消息 → 规划执行" 的流程
|
||||||
- 无论 Session 之前是什么状态,流程都一样
|
- 无论 Session 之前是什么状态,流程都一样
|
||||||
- 区别只体现在提示词中
|
- 区别只体现在提示词中
|
||||||
|
|
||||||
不负责:
|
不负责:
|
||||||
- 等待超时处理(由 ProactiveThinker 负责)
|
- 等待超时处理(由 ProactiveThinker 负责)
|
||||||
- 连续思考(由 ProactiveThinker 负责)
|
- 连续思考(由 ProactiveThinker 负责)
|
||||||
- 主动发起对话(由 ProactiveThinker 负责)
|
- 主动发起对话(由 ProactiveThinker 负责)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
chatter_name: str = "KokoroFlowChatterV2"
|
chatter_name: str = "KokoroFlowChatter"
|
||||||
chatter_description: str = "心流聊天器 V2 - 私聊特化的深度情感交互处理器"
|
chatter_description: str = "心流聊天器 - 私聊特化的深度情感交互处理器"
|
||||||
chat_types: ClassVar[list[ChatType]] = [ChatType.PRIVATE]
|
chat_types: ClassVar[list[ChatType]] = [ChatType.PRIVATE]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
@@ -73,7 +73,7 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
"failed_responses": 0,
|
"failed_responses": 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(f"{SOFT_PURPLE}[KFC V2]{RESET} 初始化完成: stream_id={stream_id}")
|
logger.info(f"{SOFT_PURPLE}[KFC]{RESET} 初始化完成: stream_id={stream_id}")
|
||||||
|
|
||||||
async def execute(self, context: StreamContext) -> dict:
|
async def execute(self, context: StreamContext) -> dict:
|
||||||
"""
|
"""
|
||||||
@@ -114,7 +114,13 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
# 4. 确定 situation_type(根据之前的等待状态)
|
# 4. 确定 situation_type(根据之前的等待状态)
|
||||||
situation_type = self._determine_situation_type(session)
|
situation_type = self._determine_situation_type(session)
|
||||||
|
|
||||||
# 5. 记录用户消息到 mental_log
|
# 5. **立即**结束等待状态,防止 ProactiveThinker 并发处理
|
||||||
|
# 在调用 LLM 之前就结束等待,避免 ProactiveThinker 检测到超时后也开始处理
|
||||||
|
if session.status == SessionStatus.WAITING:
|
||||||
|
session.end_waiting()
|
||||||
|
await self.session_manager.save_session(user_id)
|
||||||
|
|
||||||
|
# 6. 记录用户消息到 mental_log
|
||||||
for msg in unread_messages:
|
for msg in unread_messages:
|
||||||
msg_content = msg.processed_plain_text or msg.display_message or ""
|
msg_content = msg.processed_plain_text or msg.display_message or ""
|
||||||
msg_user_name = msg.user_info.user_nickname if msg.user_info else user_name
|
msg_user_name = msg.user_info.user_nickname if msg.user_info else user_name
|
||||||
@@ -127,17 +133,17 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
timestamp=msg.time,
|
timestamp=msg.time,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 6. 加载可用动作(通过 ActionModifier 过滤)
|
# 7. 加载可用动作(通过 ActionModifier 过滤)
|
||||||
from src.chat.planner_actions.action_modifier import ActionModifier
|
from src.chat.planner_actions.action_modifier import ActionModifier
|
||||||
|
|
||||||
action_modifier = ActionModifier(self.action_manager, self.stream_id)
|
action_modifier = ActionModifier(self.action_manager, self.stream_id)
|
||||||
await action_modifier.modify_actions(chatter_name="KokoroFlowChatterV2")
|
await action_modifier.modify_actions(chatter_name="KokoroFlowChatter")
|
||||||
available_actions = self.action_manager.get_using_actions()
|
available_actions = self.action_manager.get_using_actions()
|
||||||
|
|
||||||
# 7. 获取聊天流
|
# 8. 获取聊天流
|
||||||
chat_stream = await self._get_chat_stream()
|
chat_stream = await self._get_chat_stream()
|
||||||
|
|
||||||
# 8. 调用 Replyer 生成响应
|
# 9. 调用 Replyer 生成响应
|
||||||
response = await generate_response(
|
response = await generate_response(
|
||||||
session=session,
|
session=session,
|
||||||
user_name=user_name,
|
user_name=user_name,
|
||||||
@@ -146,7 +152,7 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
available_actions=available_actions,
|
available_actions=available_actions,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 9. 执行动作
|
# 10. 执行动作作
|
||||||
exec_results = []
|
exec_results = []
|
||||||
has_reply = False
|
has_reply = False
|
||||||
for action in response.actions:
|
for action in response.actions:
|
||||||
@@ -157,13 +163,13 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
reasoning=response.thought,
|
reasoning=response.thought,
|
||||||
action_data=action.params,
|
action_data=action.params,
|
||||||
thinking_id=None,
|
thinking_id=None,
|
||||||
log_prefix="[KFC V2]",
|
log_prefix="[KFC]",
|
||||||
)
|
)
|
||||||
exec_results.append(result)
|
exec_results.append(result)
|
||||||
if result.get("success") and action.type in ("kfc_reply", "respond"):
|
if result.get("success") and action.type in ("kfc_reply", "respond"):
|
||||||
has_reply = True
|
has_reply = True
|
||||||
|
|
||||||
# 10. 记录 Bot 规划到 mental_log
|
# 11. 记录 Bot 规划到 mental_log
|
||||||
session.add_bot_planning(
|
session.add_bot_planning(
|
||||||
thought=response.thought,
|
thought=response.thought,
|
||||||
actions=[a.to_dict() for a in response.actions],
|
actions=[a.to_dict() for a in response.actions],
|
||||||
@@ -171,7 +177,7 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
max_wait_seconds=response.max_wait_seconds,
|
max_wait_seconds=response.max_wait_seconds,
|
||||||
)
|
)
|
||||||
|
|
||||||
# 11. 更新 Session 状态
|
# 12. 更新 Session 状态
|
||||||
if response.max_wait_seconds > 0:
|
if response.max_wait_seconds > 0:
|
||||||
session.start_waiting(
|
session.start_waiting(
|
||||||
expected_reaction=response.expected_reaction,
|
expected_reaction=response.expected_reaction,
|
||||||
@@ -180,20 +186,20 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
else:
|
else:
|
||||||
session.end_waiting()
|
session.end_waiting()
|
||||||
|
|
||||||
# 12. 标记消息为已读
|
# 13. 标记消息为已读
|
||||||
for msg in unread_messages:
|
for msg in unread_messages:
|
||||||
context.mark_message_as_read(str(msg.message_id))
|
context.mark_message_as_read(str(msg.message_id))
|
||||||
|
|
||||||
# 13. 保存 Session
|
# 14. 保存 Session
|
||||||
await self.session_manager.save_session(user_id)
|
await self.session_manager.save_session(user_id)
|
||||||
|
|
||||||
# 14. 更新统计
|
# 15. 更新统计
|
||||||
self._stats["messages_processed"] += len(unread_messages)
|
self._stats["messages_processed"] += len(unread_messages)
|
||||||
if has_reply:
|
if has_reply:
|
||||||
self._stats["successful_responses"] += 1
|
self._stats["successful_responses"] += 1
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"{SOFT_PURPLE}[KFC V2]{RESET} 处理完成: "
|
f"{SOFT_PURPLE}[KFC]{RESET} 处理完成: "
|
||||||
f"user={user_name}, situation={situation_type}, "
|
f"user={user_name}, situation={situation_type}, "
|
||||||
f"actions={[a.type for a in response.actions]}, "
|
f"actions={[a.type for a in response.actions]}, "
|
||||||
f"wait={response.max_wait_seconds}s"
|
f"wait={response.max_wait_seconds}s"
|
||||||
@@ -209,7 +215,7 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._stats["failed_responses"] += 1
|
self._stats["failed_responses"] += 1
|
||||||
logger.error(f"[KFC V2] 处理失败: {e}")
|
logger.error(f"[KFC] 处理失败: {e}")
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
return self._build_result(success=False, message=str(e), error=True)
|
return self._build_result(success=False, message=str(e), error=True)
|
||||||
@@ -244,7 +250,7 @@ class KokoroFlowChatterV2(BaseChatter):
|
|||||||
if chat_manager:
|
if chat_manager:
|
||||||
return await chat_manager.get_stream(self.stream_id)
|
return await chat_manager.get_stream(self.stream_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[KFC V2] 获取 chat_stream 失败: {e}")
|
logger.warning(f"[KFC] 获取 chat_stream 失败: {e}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _build_result(
|
def _build_result(
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ class SessionConfig:
|
|||||||
"""会话配置"""
|
"""会话配置"""
|
||||||
|
|
||||||
# Session 持久化目录(相对于 data/)
|
# Session 持久化目录(相对于 data/)
|
||||||
session_dir: str = "kokoro_flow_chatter_v2/sessions"
|
session_dir: str = "kokoro_flow_chatter/sessions"
|
||||||
|
|
||||||
# Session 自动过期时间(秒),超过此时间未活动自动清理
|
# Session 自动过期时间(秒),超过此时间未活动自动清理
|
||||||
session_expire_seconds: int = 86400 * 7 # 7 天
|
session_expire_seconds: int = 86400 * 7 # 7 天
|
||||||
@@ -94,8 +94,8 @@ class LLMConfig:
|
|||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class KokoroFlowChatterV2Config:
|
class KokoroFlowChatterConfig:
|
||||||
"""Kokoro Flow Chatter V2 总配置"""
|
"""Kokoro Flow Chatter 总配置"""
|
||||||
|
|
||||||
# 是否启用
|
# 是否启用
|
||||||
enabled: bool = True
|
enabled: bool = True
|
||||||
@@ -123,10 +123,10 @@ class KokoroFlowChatterV2Config:
|
|||||||
|
|
||||||
|
|
||||||
# 全局配置单例
|
# 全局配置单例
|
||||||
_config: Optional[KokoroFlowChatterV2Config] = None
|
_config: Optional[KokoroFlowChatterConfig] = None
|
||||||
|
|
||||||
|
|
||||||
def get_config() -> KokoroFlowChatterV2Config:
|
def get_config() -> KokoroFlowChatterConfig:
|
||||||
"""获取全局配置"""
|
"""获取全局配置"""
|
||||||
global _config
|
global _config
|
||||||
if _config is None:
|
if _config is None:
|
||||||
@@ -134,19 +134,19 @@ def get_config() -> KokoroFlowChatterV2Config:
|
|||||||
return _config
|
return _config
|
||||||
|
|
||||||
|
|
||||||
def load_config() -> KokoroFlowChatterV2Config:
|
def load_config() -> KokoroFlowChatterConfig:
|
||||||
"""从全局配置加载 KFC V2 配置"""
|
"""从全局配置加载 KFC 配置"""
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
|
|
||||||
config = KokoroFlowChatterV2Config()
|
config = KokoroFlowChatterConfig()
|
||||||
|
|
||||||
# 尝试从全局配置读取
|
# 尝试从全局配置读取
|
||||||
if not global_config:
|
if not global_config:
|
||||||
return config
|
return config
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hasattr(global_config, 'kokoro_flow_chatter_v2'):
|
if hasattr(global_config, 'kokoro_flow_chatter'):
|
||||||
kfc_cfg = getattr(global_config, 'kokoro_flow_chatter_v2')
|
kfc_cfg = getattr(global_config, 'kokoro_flow_chatter')
|
||||||
|
|
||||||
# 基础配置
|
# 基础配置
|
||||||
if hasattr(kfc_cfg, 'enabled'):
|
if hasattr(kfc_cfg, 'enabled'):
|
||||||
@@ -191,7 +191,7 @@ def load_config() -> KokoroFlowChatterV2Config:
|
|||||||
if hasattr(kfc_cfg, 'session'):
|
if hasattr(kfc_cfg, 'session'):
|
||||||
sess_cfg = kfc_cfg.session
|
sess_cfg = kfc_cfg.session
|
||||||
config.session = SessionConfig(
|
config.session = SessionConfig(
|
||||||
session_dir=getattr(sess_cfg, 'session_dir', "kokoro_flow_chatter_v2/sessions"),
|
session_dir=getattr(sess_cfg, 'session_dir', "kokoro_flow_chatter/sessions"),
|
||||||
session_expire_seconds=getattr(sess_cfg, 'session_expire_seconds', 86400 * 7),
|
session_expire_seconds=getattr(sess_cfg, 'session_expire_seconds', 86400 * 7),
|
||||||
max_mental_log_entries=getattr(sess_cfg, 'max_mental_log_entries', 100),
|
max_mental_log_entries=getattr(sess_cfg, 'max_mental_log_entries', 100),
|
||||||
)
|
)
|
||||||
@@ -208,13 +208,13 @@ def load_config() -> KokoroFlowChatterV2Config:
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
logger = get_logger("kfc_v2_config")
|
logger = get_logger("kfc_config")
|
||||||
logger.warning(f"加载 KFC V2 配置失败,使用默认值: {e}")
|
logger.warning(f"加载 KFC 配置失败,使用默认值: {e}")
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
def reload_config() -> KokoroFlowChatterV2Config:
|
def reload_config() -> KokoroFlowChatterConfig:
|
||||||
"""重新加载配置"""
|
"""重新加载配置"""
|
||||||
global _config
|
global _config
|
||||||
_config = load_config()
|
_config = load_config()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
"""
|
"""
|
||||||
Kokoro Flow Chatter V2 - 插件注册
|
Kokoro Flow Chatter - 插件注册
|
||||||
|
|
||||||
注册 Chatter
|
注册 Chatter
|
||||||
"""
|
"""
|
||||||
@@ -11,25 +11,25 @@ from src.plugin_system.base.base_plugin import BasePlugin
|
|||||||
from src.plugin_system.base.component_types import ChatterInfo
|
from src.plugin_system.base.component_types import ChatterInfo
|
||||||
from src.plugin_system import register_plugin
|
from src.plugin_system import register_plugin
|
||||||
|
|
||||||
from .chatter import KokoroFlowChatterV2
|
from .chatter import KokoroFlowChatter
|
||||||
from .config import get_config
|
from .config import get_config
|
||||||
from .proactive_thinker import start_proactive_thinker, stop_proactive_thinker
|
from .proactive_thinker import start_proactive_thinker, stop_proactive_thinker
|
||||||
|
|
||||||
logger = get_logger("kfc_v2_plugin")
|
logger = get_logger("kfc_plugin")
|
||||||
|
|
||||||
|
|
||||||
@register_plugin
|
@register_plugin
|
||||||
class KokoroFlowChatterV2Plugin(BasePlugin):
|
class KokoroFlowChatterPlugin(BasePlugin):
|
||||||
"""
|
"""
|
||||||
Kokoro Flow Chatter V2 插件
|
Kokoro Flow Chatter 插件
|
||||||
|
|
||||||
专为私聊设计的增强 Chatter:
|
专为私聊设计的增强 Chatter:
|
||||||
- 线性叙事提示词架构
|
- 线性叙事提示词架构
|
||||||
- 等待机制与心理状态演变
|
- 等待机制与心理状态演变
|
||||||
- 主动思考能力
|
- 主动思考能力
|
||||||
"""
|
"""
|
||||||
|
|
||||||
plugin_name: str = "kokoro_flow_chatter_v2"
|
plugin_name: str = "kokoro_flow_chatter"
|
||||||
enable_plugin: bool = True
|
enable_plugin: bool = True
|
||||||
plugin_priority: int = 50 # 高于默认 Chatter
|
plugin_priority: int = 50 # 高于默认 Chatter
|
||||||
dependencies: ClassVar[list[str]] = []
|
dependencies: ClassVar[list[str]] = []
|
||||||
@@ -44,28 +44,28 @@ class KokoroFlowChatterV2Plugin(BasePlugin):
|
|||||||
config = get_config()
|
config = get_config()
|
||||||
|
|
||||||
if not config.enabled:
|
if not config.enabled:
|
||||||
logger.info("[KFC V2] 插件已禁用")
|
logger.info("[KFC] 插件已禁用")
|
||||||
return
|
return
|
||||||
|
|
||||||
logger.info("[KFC V2] 插件已加载")
|
logger.info("[KFC] 插件已加载")
|
||||||
|
|
||||||
# 启动主动思考器
|
# 启动主动思考器
|
||||||
if config.proactive.enabled:
|
if config.proactive.enabled:
|
||||||
try:
|
try:
|
||||||
await start_proactive_thinker()
|
await start_proactive_thinker()
|
||||||
logger.info("[KFC V2] 主动思考器已启动")
|
logger.info("[KFC] 主动思考器已启动")
|
||||||
self._is_started = True
|
self._is_started = True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[KFC V2] 启动主动思考器失败: {e}")
|
logger.error(f"[KFC] 启动主动思考器失败: {e}")
|
||||||
|
|
||||||
async def on_plugin_unloaded(self):
|
async def on_plugin_unloaded(self):
|
||||||
"""插件卸载时"""
|
"""插件卸载时"""
|
||||||
try:
|
try:
|
||||||
await stop_proactive_thinker()
|
await stop_proactive_thinker()
|
||||||
logger.info("[KFC V2] 主动思考器已停止")
|
logger.info("[KFC] 主动思考器已停止")
|
||||||
self._is_started = False
|
self._is_started = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"[KFC V2] 停止主动思考器失败: {e}")
|
logger.warning(f"[KFC] 停止主动思考器失败: {e}")
|
||||||
|
|
||||||
def get_plugin_components(self):
|
def get_plugin_components(self):
|
||||||
"""返回组件列表"""
|
"""返回组件列表"""
|
||||||
@@ -79,24 +79,24 @@ class KokoroFlowChatterV2Plugin(BasePlugin):
|
|||||||
try:
|
try:
|
||||||
# 注册 Chatter
|
# 注册 Chatter
|
||||||
components.append((
|
components.append((
|
||||||
KokoroFlowChatterV2.get_chatter_info(),
|
KokoroFlowChatter.get_chatter_info(),
|
||||||
KokoroFlowChatterV2,
|
KokoroFlowChatter,
|
||||||
))
|
))
|
||||||
logger.debug("[KFC V2] 成功加载 KokoroFlowChatterV2 组件")
|
logger.debug("[KFC] 成功加载 KokoroFlowChatter 组件")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[KFC V2] 加载 Chatter 组件失败: {e}")
|
logger.error(f"[KFC] 加载 Chatter 组件失败: {e}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 注册 KFC 专属 Reply 动作
|
# 注册 KFC 专属 Reply 动作
|
||||||
from .actions.reply import KFCReplyAction
|
from .actions.reply import KFCReplyAction
|
||||||
|
|
||||||
components.append((
|
components.append((
|
||||||
KFCReplyAction.get_action_info(),
|
KFCReplyAction.get_action_info(),
|
||||||
KFCReplyAction,
|
KFCReplyAction,
|
||||||
))
|
))
|
||||||
logger.debug("[KFC V2] 成功加载 KFCReplyAction 组件")
|
logger.debug("[KFC] 成功加载 KFCReplyAction 组件")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"[KFC V2] 加载 Reply 动作失败: {e}")
|
logger.error(f"[KFC] 加载 Reply 动作失败: {e}")
|
||||||
|
|
||||||
return components
|
return components
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ class KokoroFlowChatterV2Plugin(BasePlugin):
|
|||||||
"""获取插件信息"""
|
"""获取插件信息"""
|
||||||
return {
|
return {
|
||||||
"name": self.plugin_name,
|
"name": self.plugin_name,
|
||||||
"display_name": "Kokoro Flow Chatter V2",
|
"display_name": "Kokoro Flow Chatter",
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"author": "MoFox",
|
"author": "MoFox",
|
||||||
"description": "专为私聊设计的增强 Chatter",
|
"description": "专为私聊设计的增强 Chatter",
|
||||||
|
|||||||
@@ -80,13 +80,16 @@ class PromptBuilder:
|
|||||||
session, user_name, situation_type, extra_context
|
session, user_name, situation_type, extra_context
|
||||||
)
|
)
|
||||||
|
|
||||||
# 5. 构建可用动作
|
# 5. 构建聊天历史总览
|
||||||
|
chat_history_block = await self._build_chat_history_block(chat_stream)
|
||||||
|
|
||||||
|
# 6. 构建可用动作
|
||||||
actions_block = self._build_actions_block(available_actions)
|
actions_block = self._build_actions_block(available_actions)
|
||||||
|
|
||||||
# 6. 获取输出格式
|
# 7. 获取输出格式
|
||||||
output_format = await self._get_output_format()
|
output_format = await self._get_output_format()
|
||||||
|
|
||||||
# 7. 使用统一的 prompt 管理系统格式化
|
# 8. 使用统一的 prompt 管理系统格式化
|
||||||
prompt = await global_prompt_manager.format_prompt(
|
prompt = await global_prompt_manager.format_prompt(
|
||||||
PROMPT_NAMES["main"],
|
PROMPT_NAMES["main"],
|
||||||
user_name=user_name,
|
user_name=user_name,
|
||||||
@@ -94,6 +97,7 @@ class PromptBuilder:
|
|||||||
relation_block=relation_block,
|
relation_block=relation_block,
|
||||||
activity_stream=activity_stream or "(这是你们第一次聊天)",
|
activity_stream=activity_stream or "(这是你们第一次聊天)",
|
||||||
current_situation=current_situation,
|
current_situation=current_situation,
|
||||||
|
chat_history_block=chat_history_block,
|
||||||
available_actions=actions_block,
|
available_actions=actions_block,
|
||||||
output_format=output_format,
|
output_format=output_format,
|
||||||
)
|
)
|
||||||
@@ -155,6 +159,57 @@ class PromptBuilder:
|
|||||||
|
|
||||||
return f"你与 {user_name} 还不太熟悉,这是早期的交流阶段。"
|
return f"你与 {user_name} 还不太熟悉,这是早期的交流阶段。"
|
||||||
|
|
||||||
|
async def _build_chat_history_block(
|
||||||
|
self,
|
||||||
|
chat_stream: Optional["ChatStream"],
|
||||||
|
) -> str:
|
||||||
|
"""
|
||||||
|
构建聊天历史总览块
|
||||||
|
|
||||||
|
从 chat_stream 获取历史消息,格式化为可读的聊天记录
|
||||||
|
类似于 AFC 的已读历史板块
|
||||||
|
"""
|
||||||
|
if not chat_stream:
|
||||||
|
return "(暂无聊天记录)"
|
||||||
|
|
||||||
|
try:
|
||||||
|
from src.chat.utils.chat_message_builder import build_readable_messages_with_id
|
||||||
|
from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat
|
||||||
|
from src.common.data_models.database_data_model import DatabaseMessages
|
||||||
|
|
||||||
|
stream_context = chat_stream.context
|
||||||
|
|
||||||
|
# 获取已读消息
|
||||||
|
history_messages = stream_context.history_messages if stream_context else []
|
||||||
|
|
||||||
|
if not history_messages:
|
||||||
|
# 如果内存中没有历史消息,从数据库加载
|
||||||
|
fallback_messages_dicts = await get_raw_msg_before_timestamp_with_chat(
|
||||||
|
chat_id=chat_stream.stream_id,
|
||||||
|
timestamp=time.time(),
|
||||||
|
limit=30, # 限制数量,私聊不需要太多
|
||||||
|
)
|
||||||
|
history_messages = [
|
||||||
|
DatabaseMessages(**msg_dict) for msg_dict in fallback_messages_dicts
|
||||||
|
]
|
||||||
|
|
||||||
|
if not history_messages:
|
||||||
|
return "(暂无聊天记录)"
|
||||||
|
|
||||||
|
# 构建可读消息
|
||||||
|
chat_content, _ = await build_readable_messages_with_id(
|
||||||
|
messages=[msg.flatten() for msg in history_messages[-30:]], # 最多30条
|
||||||
|
timestamp_mode="normal_no_YMD",
|
||||||
|
truncate=False,
|
||||||
|
show_actions=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
return chat_content if chat_content else "(暂无聊天记录)"
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"构建聊天历史块失败: {e}")
|
||||||
|
return "(获取聊天记录失败)"
|
||||||
|
|
||||||
async def _build_activity_stream(
|
async def _build_activity_stream(
|
||||||
self,
|
self,
|
||||||
session: KokoroSession,
|
session: KokoroSession,
|
||||||
@@ -285,6 +340,12 @@ class PromptBuilder:
|
|||||||
"""构建当前情况描述"""
|
"""构建当前情况描述"""
|
||||||
current_time = datetime.now().strftime("%Y年%m月%d日 %H:%M")
|
current_time = datetime.now().strftime("%Y年%m月%d日 %H:%M")
|
||||||
|
|
||||||
|
# 如果之前没有设置等待时间(max_wait_seconds == 0),视为 new_message
|
||||||
|
if situation_type in ("reply_in_time", "reply_late"):
|
||||||
|
max_wait = session.waiting_config.max_wait_seconds
|
||||||
|
if max_wait <= 0:
|
||||||
|
situation_type = "new_message"
|
||||||
|
|
||||||
if situation_type == "new_message":
|
if situation_type == "new_message":
|
||||||
return await global_prompt_manager.format_prompt(
|
return await global_prompt_manager.format_prompt(
|
||||||
PROMPT_NAMES["situation_new_message"],
|
PROMPT_NAMES["situation_new_message"],
|
||||||
|
|||||||
@@ -28,10 +28,15 @@ KFC_V2_MAIN_PROMPT = Prompt(
|
|||||||
## 4. 当前情况
|
## 4. 当前情况
|
||||||
{current_situation}
|
{current_situation}
|
||||||
|
|
||||||
## 5. 你可以做的事情
|
## 5. 聊天历史总览
|
||||||
|
以下是你和 {user_name} 的聊天记录,帮助你更好地理解对话上下文:
|
||||||
|
|
||||||
|
{chat_history_block}
|
||||||
|
|
||||||
|
## 6. 你可以做的事情
|
||||||
{available_actions}
|
{available_actions}
|
||||||
|
|
||||||
## 6. 你的回复格式
|
## 7. 你的回复格式
|
||||||
{output_format}
|
{output_format}
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ async def generate_response(
|
|||||||
success, raw_response, reasoning, model_name = await llm_api.generate_with_model(
|
success, raw_response, reasoning, model_name = await llm_api.generate_with_model(
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
model_config=replyer_config,
|
model_config=replyer_config,
|
||||||
request_type="kokoro_flow_chatter_v2",
|
request_type="kokoro_flow_chatter",
|
||||||
)
|
)
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ class SessionManager:
|
|||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
data_dir: str = "data/kokoro_flow_chatter_v2/sessions",
|
data_dir: str = "data/kokoro_flow_chatter/sessions",
|
||||||
max_session_age_days: int = 30,
|
max_session_age_days: int = 30,
|
||||||
):
|
):
|
||||||
if hasattr(self, "_initialized") and self._initialized:
|
if hasattr(self, "_initialized") and self._initialized:
|
||||||
|
|||||||
@@ -140,14 +140,7 @@ class PokeAction(BaseAction):
|
|||||||
|
|
||||||
# === 基本信息(必须填写)===
|
# === 基本信息(必须填写)===
|
||||||
action_name = "poke_user"
|
action_name = "poke_user"
|
||||||
action_description = """可以让你戳其他用户,为互动增添一份小小的乐趣。
|
action_description = "可以让你戳其他用户,为互动增添一份小小的乐趣。"
|
||||||
判定条件:
|
|
||||||
1. **互动时机**: 这是一个有趣的互动方式,可以在想提醒某人,或者单纯想开个玩笑时使用。
|
|
||||||
2. **用户请求**: 当用户明确要求使用戳一戳时。
|
|
||||||
3. **上下文需求**: 当上下文明确需要你戳一个或多个人时。
|
|
||||||
4. **频率与情绪**: 如果最近已经戳过,或者感觉对方情绪不高,请避免使用,不要打扰到别人哦。
|
|
||||||
|
|
||||||
请根据上述规则,回答“是”或“否”。"""
|
|
||||||
activation_type = ActionActivationType.ALWAYS
|
activation_type = ActionActivationType.ALWAYS
|
||||||
parallel_action = True
|
parallel_action = True
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user