feat:修改maisaka
This commit is contained in:
@@ -3,19 +3,24 @@ MaiSaka LLM 服务 - 使用主项目 LLM 系统
|
||||
将主项目的 LLMRequest 适配为 MaiSaka 需要的接口
|
||||
"""
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional, Literal
|
||||
from typing import Any, List, Literal, Optional
|
||||
import json
|
||||
|
||||
from rich.console import Group
|
||||
from rich.panel import Panel
|
||||
from rich.pretty import Pretty
|
||||
from rich.text import Text
|
||||
|
||||
from src.common.logger import get_logger
|
||||
from src.config.config import config_manager
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.prompt.prompt_manager import prompt_manager
|
||||
from src.llm_models.payload_content.message import MessageBuilder, RoleType
|
||||
from src.llm_models.payload_content.tool_option import ToolCall as ToolCallOption, ToolOption
|
||||
from builtin_tools import get_builtin_tools
|
||||
|
||||
import config
|
||||
from src.llm_models.utils_model import LLMRequest
|
||||
from src.prompt.prompt_manager import prompt_manager
|
||||
from . import config
|
||||
from .config import console
|
||||
from .builtin_tools import get_builtin_tools
|
||||
|
||||
logger = get_logger("maisaka_llm")
|
||||
|
||||
@@ -123,10 +128,6 @@ class MaiSakaLLMService:
|
||||
tools_section += "\n• read_file(filename) — 读取 mai_files 目录下的文件内容。"
|
||||
if config.ENABLE_LIST_FILES:
|
||||
tools_section += "\n• list_files() — 获取 mai_files 目录下所有文件的元信息列表。"
|
||||
if config.ENABLE_QQ_TOOLS:
|
||||
tools_section += "\n• get_qq_chat_info(chat, limit) — 获取指定 QQ 聊天的聊天记录。"
|
||||
tools_section += "\n• send_info(chat, message) — 发送消息到指定的 QQ 聊天。"
|
||||
tools_section += "\n• list_qq_chats() — 获取所有可用的 QQ 聊天列表。"
|
||||
|
||||
chat_prompt.add_context("file_tools_section", tools_section if tools_section else "")
|
||||
import asyncio
|
||||
@@ -203,6 +204,108 @@ class MaiSakaLLMService:
|
||||
"""设置额外的工具定义(如 MCP 工具)"""
|
||||
self._extra_tools = list(tools)
|
||||
|
||||
@staticmethod
|
||||
def _get_role_badge_style(role: str) -> str:
|
||||
"""为不同 role 返回不同的标签样式。"""
|
||||
if role == "system":
|
||||
return "bold white on blue"
|
||||
if role == "user":
|
||||
return "bold black on green"
|
||||
if role == "assistant":
|
||||
return "bold black on yellow"
|
||||
if role == "tool":
|
||||
return "bold white on magenta"
|
||||
return "bold white on bright_black"
|
||||
|
||||
@staticmethod
|
||||
def _render_message_content(content: Any) -> object:
|
||||
"""把消息内容转成适合 Rich 输出的 renderable。"""
|
||||
if isinstance(content, str):
|
||||
return Text(content)
|
||||
|
||||
if isinstance(content, list):
|
||||
parts: list[object] = []
|
||||
for item in content:
|
||||
if isinstance(item, dict) and item.get("type") == "text" and isinstance(item.get("text"), str):
|
||||
parts.append(Text(item["text"]))
|
||||
else:
|
||||
parts.append(Pretty(item, expand_all=True))
|
||||
return Group(*parts) if parts else Text("")
|
||||
|
||||
if content is None:
|
||||
return Text("")
|
||||
|
||||
return Pretty(content, expand_all=True)
|
||||
|
||||
@staticmethod
|
||||
def _format_tool_call_for_display(tool_call: Any) -> dict[str, Any]:
|
||||
"""将 tool call 转成适合 CLI 展示的结构。"""
|
||||
if isinstance(tool_call, dict):
|
||||
function_info = tool_call.get("function", {})
|
||||
return {
|
||||
"id": tool_call.get("id"),
|
||||
"name": function_info.get("name", tool_call.get("name")),
|
||||
"arguments": function_info.get("arguments", tool_call.get("arguments")),
|
||||
}
|
||||
|
||||
return {
|
||||
"id": getattr(tool_call, "call_id", getattr(tool_call, "id", None)),
|
||||
"name": getattr(tool_call, "func_name", getattr(tool_call, "name", None)),
|
||||
"arguments": getattr(tool_call, "args", getattr(tool_call, "arguments", None)),
|
||||
}
|
||||
|
||||
def _render_message_panel(self, message: Any, index: int) -> Panel:
|
||||
"""渲染主循环 prompt 中的一条消息。"""
|
||||
if isinstance(message, dict):
|
||||
raw_role = message.get("role", "unknown")
|
||||
content = message.get("content")
|
||||
tool_calls = message.get("tool_calls")
|
||||
tool_call_id = message.get("tool_call_id")
|
||||
else:
|
||||
raw_role = getattr(message, "role", "unknown")
|
||||
content = getattr(message, "content", None)
|
||||
tool_calls = getattr(message, "tool_calls", None)
|
||||
tool_call_id = getattr(message, "tool_call_id", None)
|
||||
|
||||
role = raw_role.value if hasattr(raw_role, "value") else str(raw_role)
|
||||
title = Text.assemble(
|
||||
Text(f" {role.upper()} ", style=self._get_role_badge_style(role)),
|
||||
Text(f" #{index}", style="muted"),
|
||||
)
|
||||
|
||||
parts: list[object] = []
|
||||
if content not in (None, "", []):
|
||||
parts.append(Text(" message ", style="bold cyan"))
|
||||
parts.append(self._render_message_content(content))
|
||||
|
||||
if tool_calls:
|
||||
parts.append(Text(" tool_calls ", style="bold magenta"))
|
||||
parts.append(
|
||||
Pretty(
|
||||
[self._format_tool_call_for_display(tool_call) for tool_call in tool_calls],
|
||||
expand_all=True,
|
||||
)
|
||||
)
|
||||
|
||||
if tool_call_id:
|
||||
parts.append(
|
||||
Text.assemble(
|
||||
Text(" tool_call_id ", style="bold magenta"),
|
||||
Text(" "),
|
||||
Text(str(tool_call_id), style="magenta"),
|
||||
)
|
||||
)
|
||||
|
||||
if not parts:
|
||||
parts.append(Text("[empty message]", style="muted"))
|
||||
|
||||
return Panel(
|
||||
Group(*parts),
|
||||
title=title,
|
||||
border_style="dim",
|
||||
padding=(0, 1),
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _tool_option_to_dict(tool: "ToolOption") -> dict:
|
||||
"""将 ToolOption 对象转换为主项目期望的 dict 格式
|
||||
@@ -287,11 +390,14 @@ class MaiSakaLLMService:
|
||||
|
||||
# 打印消息列表
|
||||
built_messages = message_factory(None)
|
||||
print("\n" + "=" * 60)
|
||||
print("MaiSaka LLM Request - chat_loop_step:")
|
||||
for msg in built_messages:
|
||||
print(f" {msg}")
|
||||
print("=" * 60 + "\n")
|
||||
console.print(
|
||||
Panel(
|
||||
Group(*[self._render_message_panel(msg, index + 1) for index, msg in enumerate(built_messages)]),
|
||||
title="MaiSaka LLM Request - chat_loop_step",
|
||||
border_style="cyan",
|
||||
padding=(0, 1),
|
||||
)
|
||||
)
|
||||
|
||||
response, (reasoning, model, tool_calls) = await self._llm_chat.generate_response_with_message_async(
|
||||
message_factory=message_factory,
|
||||
@@ -423,10 +529,11 @@ class MaiSakaLLMService:
|
||||
|
||||
prompt = "\n".join(prompt_parts)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("MaiSaka LLM Request - analyze_cognition:")
|
||||
print(f" {prompt}")
|
||||
print("=" * 60 + "\n")
|
||||
if config.SHOW_ANALYZE_COGNITION_PROMPT:
|
||||
print("\n" + "=" * 60)
|
||||
print("MaiSaka LLM Request - analyze_cognition:")
|
||||
print(f" {prompt}")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
try:
|
||||
response, _ = await self._llm_utils.generate_response_async(
|
||||
@@ -458,10 +565,11 @@ class MaiSakaLLMService:
|
||||
|
||||
prompt = "\n".join(prompt_parts)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("MaiSaka LLM Request - analyze_timing:")
|
||||
print(f" {prompt}")
|
||||
print("=" * 60 + "\n")
|
||||
if config.SHOW_ANALYZE_TIMING_PROMPT:
|
||||
print("\n" + "=" * 60)
|
||||
print("MaiSaka LLM Request - analyze_timing:")
|
||||
print(f" {prompt}")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
try:
|
||||
response, _ = await self._llm_utils.generate_response_async(
|
||||
@@ -518,7 +626,7 @@ class MaiSakaLLMService:
|
||||
可供 Replyer 类直接调用
|
||||
"""
|
||||
from datetime import datetime
|
||||
from replyer import format_chat_history
|
||||
from .replyer import format_chat_history
|
||||
|
||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user