feat:移除旧的maisaka cli逻辑
This commit is contained in:
@@ -14,6 +14,7 @@ from src.core.tooling import ToolExecutionResult
|
||||
|
||||
from ..context_messages import SessionBackedMessage
|
||||
from ..message_adapter import format_speaker_content
|
||||
from ..planner_message_utils import build_planner_prefix, build_session_backed_text_message
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..reasoning_engine import MaisakaReasoningEngine
|
||||
@@ -141,20 +142,9 @@ class BuiltinToolRuntimeContext:
|
||||
|
||||
bot_name = global_config.bot.nickname.strip() or "MaiSaka"
|
||||
reply_timestamp = datetime.now()
|
||||
planner_prefix = (
|
||||
f"[时间]{reply_timestamp.strftime('%H:%M:%S')}\n"
|
||||
f"[用户]{bot_name}\n"
|
||||
"[用户群昵称]\n"
|
||||
"[msg_id]\n"
|
||||
"[发言内容]"
|
||||
)
|
||||
history_message = SessionBackedMessage(
|
||||
raw_message=MessageSequence([TextComponent(f"{planner_prefix}{reply_text}")]),
|
||||
visible_text=format_speaker_content(
|
||||
bot_name,
|
||||
reply_text,
|
||||
reply_timestamp,
|
||||
),
|
||||
history_message = build_session_backed_text_message(
|
||||
speaker_name=bot_name,
|
||||
text=reply_text,
|
||||
timestamp=reply_timestamp,
|
||||
source_kind="guided_reply",
|
||||
)
|
||||
@@ -170,12 +160,9 @@ class BuiltinToolRuntimeContext:
|
||||
|
||||
bot_name = global_config.bot.nickname.strip() or "MaiSaka"
|
||||
reply_timestamp = datetime.now()
|
||||
planner_prefix = (
|
||||
f"[时间]{reply_timestamp.strftime('%H:%M:%S')}\n"
|
||||
f"[用户]{bot_name}\n"
|
||||
"[用户群昵称]\n"
|
||||
"[msg_id]\n"
|
||||
"[发言内容]"
|
||||
planner_prefix = build_planner_prefix(
|
||||
timestamp=reply_timestamp,
|
||||
user_name=bot_name,
|
||||
)
|
||||
history_message = SessionBackedMessage(
|
||||
raw_message=MessageSequence(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
from typing import Optional
|
||||
|
||||
from src.chat.replyer.replyer_manager import replyer_manager
|
||||
from src.cli.maisaka_cli_sender import CLI_PLATFORM_NAME, render_cli_message
|
||||
from src.common.logger import get_logger
|
||||
from src.core.tooling import ToolExecutionContext, ToolExecutionResult, ToolInvocation, ToolSpec
|
||||
from src.services import send_service
|
||||
@@ -134,17 +135,22 @@ async def handle_tool(
|
||||
combined_reply_text = "".join(reply_segments)
|
||||
try:
|
||||
sent = False
|
||||
for index, segment in enumerate(reply_segments):
|
||||
sent = await send_service.text_to_stream(
|
||||
text=segment,
|
||||
stream_id=tool_ctx.runtime.session_id,
|
||||
set_reply=quote_reply if index == 0 else False,
|
||||
reply_message=target_message if quote_reply and index == 0 else None,
|
||||
selected_expressions=reply_result.selected_expression_ids or None,
|
||||
typing=index > 0,
|
||||
)
|
||||
if not sent:
|
||||
break
|
||||
if tool_ctx.runtime.chat_stream.platform == CLI_PLATFORM_NAME:
|
||||
for segment in reply_segments:
|
||||
render_cli_message(segment)
|
||||
sent = True
|
||||
else:
|
||||
for index, segment in enumerate(reply_segments):
|
||||
sent = await send_service.text_to_stream(
|
||||
text=segment,
|
||||
stream_id=tool_ctx.runtime.session_id,
|
||||
set_reply=quote_reply if index == 0 else False,
|
||||
reply_message=target_message if quote_reply and index == 0 else None,
|
||||
selected_expressions=reply_result.selected_expression_ids or None,
|
||||
typing=index > 0,
|
||||
)
|
||||
if not sent:
|
||||
break
|
||||
except Exception:
|
||||
logger.exception(
|
||||
f"{tool_ctx.runtime.log_prefix} 发送文字消息时发生异常,目标消息编号={target_message_id}"
|
||||
|
||||
@@ -40,6 +40,7 @@ from src.services.llm_service import LLMServiceClient
|
||||
from .builtin_tool import get_builtin_tools
|
||||
from .context_messages import AssistantMessage, LLMContextMessage, SessionBackedMessage, ToolResultMessage
|
||||
from .message_adapter import format_speaker_content
|
||||
from .planner_message_utils import build_session_backed_text_message
|
||||
from .prompt_cli_renderer import PromptCLIVisualizer
|
||||
|
||||
|
||||
@@ -920,37 +921,4 @@ class MaisakaChatLoopService:
|
||||
|
||||
if first_valid_index == 0:
|
||||
return selected_history
|
||||
return selected_history[first_valid_index:]
|
||||
|
||||
@staticmethod
|
||||
def build_chat_context(user_text: str) -> List[LLMContextMessage]:
|
||||
"""根据用户输入构造最小对话上下文。
|
||||
|
||||
Args:
|
||||
user_text: 用户输入文本。
|
||||
|
||||
Returns:
|
||||
List[LLMContextMessage]: 构造好的上下文消息列表。
|
||||
"""
|
||||
|
||||
timestamp = datetime.now()
|
||||
visible_text = format_speaker_content(
|
||||
global_config.maisaka.user_name.strip() or "用户",
|
||||
user_text,
|
||||
timestamp,
|
||||
)
|
||||
planner_prefix = (
|
||||
f"[时间]{timestamp.strftime('%H:%M:%S')}\n"
|
||||
f"[用户]{global_config.maisaka.user_name.strip() or '用户'}\n"
|
||||
"[用户群昵称]\n"
|
||||
"[msg_id]\n"
|
||||
"[发言内容]"
|
||||
)
|
||||
return [
|
||||
SessionBackedMessage(
|
||||
raw_message=MessageSequence([TextComponent(f"{planner_prefix}{user_text}")]),
|
||||
visible_text=visible_text,
|
||||
timestamp=timestamp,
|
||||
source_kind="user",
|
||||
)
|
||||
]
|
||||
return selected_history[first_valid_index:]
|
||||
109
src/maisaka/planner_message_utils.py
Normal file
109
src/maisaka/planner_message_utils.py
Normal file
@@ -0,0 +1,109 @@
|
||||
"""Maisaka 规划器消息构造工具。"""
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from src.chat.message_receive.message import SessionMessage
|
||||
from src.common.data_models.message_component_data_model import MessageSequence, TextComponent
|
||||
|
||||
from .context_messages import SessionBackedMessage
|
||||
from .message_adapter import format_speaker_content
|
||||
|
||||
|
||||
def build_planner_prefix(
|
||||
*,
|
||||
timestamp: datetime,
|
||||
user_name: str,
|
||||
group_card: str = "",
|
||||
message_id: Optional[str] = None,
|
||||
include_message_id: bool = True,
|
||||
) -> str:
|
||||
"""构造 Maisaka 规划器使用的统一消息前缀。
|
||||
|
||||
Args:
|
||||
timestamp: 消息时间。
|
||||
user_name: 展示给规划器的用户名。
|
||||
group_card: 群昵称。
|
||||
message_id: 消息 ID。
|
||||
include_message_id: 是否输出 `msg_id` 段。
|
||||
|
||||
Returns:
|
||||
str: 拼接完成的规划器前缀。
|
||||
"""
|
||||
|
||||
prefix_parts = [
|
||||
f"[时间]{timestamp.strftime('%H:%M:%S')}\n",
|
||||
f"[用户名]{user_name}\n",
|
||||
f"[用户群昵称]{group_card}\n",
|
||||
]
|
||||
if include_message_id:
|
||||
prefix_parts.append(f"[msg_id]{message_id or ''}\n")
|
||||
prefix_parts.append("[发言内容]")
|
||||
return "".join(prefix_parts)
|
||||
|
||||
|
||||
def build_planner_user_prefix_from_session_message(message: SessionMessage) -> str:
|
||||
"""根据真实会话消息构造规划器前缀。
|
||||
|
||||
Args:
|
||||
message: 原始会话消息。
|
||||
|
||||
Returns:
|
||||
str: 规划器前缀字符串。
|
||||
"""
|
||||
|
||||
user_info = message.message_info.user_info
|
||||
user_name = user_info.user_nickname or user_info.user_id
|
||||
return build_planner_prefix(
|
||||
timestamp=message.timestamp,
|
||||
user_name=user_name,
|
||||
group_card=user_info.user_cardname or "",
|
||||
message_id=message.message_id,
|
||||
include_message_id=not message.is_notify and bool(message.message_id),
|
||||
)
|
||||
|
||||
|
||||
def build_session_backed_text_message(
|
||||
*,
|
||||
speaker_name: str,
|
||||
text: str,
|
||||
timestamp: datetime,
|
||||
source_kind: str,
|
||||
group_card: str = "",
|
||||
message_id: Optional[str] = None,
|
||||
include_message_id: bool = True,
|
||||
) -> SessionBackedMessage:
|
||||
"""构造带规划器前缀的纯文本历史消息。
|
||||
|
||||
Args:
|
||||
speaker_name: 发言者名称。
|
||||
text: 发言内容。
|
||||
timestamp: 发言时间。
|
||||
source_kind: 上下文来源类型。
|
||||
group_card: 群昵称。
|
||||
message_id: 消息 ID。
|
||||
include_message_id: 是否输出 `msg_id` 段。
|
||||
|
||||
Returns:
|
||||
SessionBackedMessage: 可直接写入历史的上下文消息。
|
||||
"""
|
||||
|
||||
planner_prefix = build_planner_prefix(
|
||||
timestamp=timestamp,
|
||||
user_name=speaker_name,
|
||||
group_card=group_card,
|
||||
message_id=message_id,
|
||||
include_message_id=include_message_id,
|
||||
)
|
||||
return SessionBackedMessage(
|
||||
raw_message=MessageSequence([TextComponent(f"{planner_prefix}{text}")]),
|
||||
visible_text=format_speaker_content(
|
||||
speaker_name,
|
||||
text,
|
||||
timestamp,
|
||||
message_id if include_message_id else None,
|
||||
),
|
||||
timestamp=timestamp,
|
||||
message_id=message_id,
|
||||
source_kind=source_kind,
|
||||
)
|
||||
@@ -33,6 +33,7 @@ from .message_adapter import (
|
||||
clone_message_sequence,
|
||||
format_speaker_content,
|
||||
)
|
||||
from .planner_message_utils import build_planner_user_prefix_from_session_message
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .runtime import MaisakaHeartFlowChatting
|
||||
@@ -226,7 +227,7 @@ class MaisakaReasoningEngine:
|
||||
|
||||
async def _build_message_sequence(self, message: SessionMessage) -> tuple[MessageSequence, str]:
|
||||
message_sequence = MessageSequence([])
|
||||
planner_prefix = self._build_planner_user_prefix(message)
|
||||
planner_prefix = build_planner_user_prefix_from_session_message(message)
|
||||
|
||||
appended_component = False
|
||||
if global_config.maisaka.direct_image_input:
|
||||
@@ -255,22 +256,6 @@ class MaisakaReasoningEngine:
|
||||
|
||||
return message_sequence, legacy_visible_text
|
||||
|
||||
@staticmethod
|
||||
def _build_planner_user_prefix(message: SessionMessage) -> str:
|
||||
user_info = message.message_info.user_info
|
||||
timestamp_text = message.timestamp.strftime("%H:%M:%S")
|
||||
user_name = user_info.user_nickname or user_info.user_id
|
||||
group_card = user_info.user_cardname or ""
|
||||
prefix_parts = [
|
||||
f"[时间]{timestamp_text}\n",
|
||||
f"[用户]{user_name}\n",
|
||||
f"[用户群昵称]{group_card}\n",
|
||||
]
|
||||
if not message.is_notify and message.message_id:
|
||||
prefix_parts.append(f"[msg_id]{message.message_id}\n")
|
||||
prefix_parts.append("[发言内容]")
|
||||
return "".join(prefix_parts)
|
||||
|
||||
def _build_legacy_visible_text(self, message: SessionMessage, source_sequence: MessageSequence) -> str:
|
||||
user_info = message.message_info.user_info
|
||||
speaker_name = user_info.user_cardname or user_info.user_nickname or user_info.user_id
|
||||
|
||||
Reference in New Issue
Block a user