added memmory
This commit is contained in:
@@ -47,9 +47,18 @@ POMODORO_TOOL_NAMES = frozenset({
|
||||
"get_pomodoro_history",
|
||||
})
|
||||
|
||||
MEMORY_TOOL_NAMES = frozenset({
|
||||
"remember_fact",
|
||||
"recall_memories",
|
||||
"forget_memory",
|
||||
"update_profile",
|
||||
"update_session_summary",
|
||||
})
|
||||
|
||||
# Не засорять чат служебными ответами
|
||||
TOOLS_SKIP_CHAT_NOTICE = frozenset({
|
||||
"get_pomodoro_status",
|
||||
"recall_memories",
|
||||
})
|
||||
|
||||
|
||||
@@ -63,7 +72,12 @@ def format_tool_notice(tool_name: str, raw_result: str) -> str | None:
|
||||
return None
|
||||
|
||||
if isinstance(data, dict) and "error" in data:
|
||||
prefix = "⏱" if tool_name in POMODORO_TOOL_NAMES else "📋"
|
||||
if tool_name in POMODORO_TOOL_NAMES:
|
||||
prefix = "⏱"
|
||||
elif tool_name in MEMORY_TOOL_NAMES:
|
||||
prefix = "🧠"
|
||||
else:
|
||||
prefix = "📋"
|
||||
return f"{prefix} {data['error']}"
|
||||
|
||||
if tool_name == "reset_pomodoro_cycle":
|
||||
@@ -109,6 +123,21 @@ def format_tool_notice(tool_name: str, raw_result: str) -> str | None:
|
||||
lines.append(f"- `{p.get('slug')}`: {p.get('name')} · Gitea: {gitea}")
|
||||
return "\n".join(lines)
|
||||
|
||||
if tool_name == "remember_fact" and data.get("ok"):
|
||||
action = "обновлено" if data.get("action") == "updated" else "сохранено"
|
||||
return f"🧠 **Память {action}** · #{data.get('memory_id')}: {data.get('content')}"
|
||||
|
||||
if tool_name == "forget_memory" and data.get("ok"):
|
||||
return f"🧠 **Забыто** · #{data.get('memory_id')}: {data.get('forgotten')}"
|
||||
|
||||
if tool_name == "update_profile" and data.get("ok"):
|
||||
profile = data.get("profile") or {}
|
||||
parts = [f"{k}={v}" for k, v in profile.items() if v]
|
||||
return f"🧠 **Профиль обновлён** · {', '.join(parts) or 'пусто'}"
|
||||
|
||||
if tool_name == "update_session_summary" and data.get("ok"):
|
||||
return "🧠 **Сводка чата сохранена**"
|
||||
|
||||
return None
|
||||
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ from app.chat.notices import (
|
||||
format_pomodoro_context,
|
||||
format_tool_notice,
|
||||
)
|
||||
from app.memory.context import format_memory_context, get_memory_snapshot
|
||||
from app.projects.context import format_projects_context, get_projects_snapshot
|
||||
from app.db.models import ChatSession, Message
|
||||
from app.llm.client import LLMClient
|
||||
@@ -18,6 +19,7 @@ from app.pomodoro.service import PomodoroService
|
||||
from app.tools.registry import TOOL_DEFINITIONS, execute_tool
|
||||
|
||||
MAX_TOOL_ROUNDS = 5
|
||||
MAX_HISTORY_MESSAGES = 40
|
||||
|
||||
|
||||
class ChatService:
|
||||
@@ -48,23 +50,31 @@ class ChatService:
|
||||
self.db.commit()
|
||||
return True
|
||||
|
||||
def _build_system_prompt(self) -> str:
|
||||
def _build_system_prompt(self, session_id: int | None = None) -> str:
|
||||
status = PomodoroService(self.db).get_status()
|
||||
memory_snapshot = get_memory_snapshot(self.db, session_id)
|
||||
projects_snapshot = get_projects_snapshot(self.db)
|
||||
return (
|
||||
f"{self.character.get_system_prompt()}\n\n"
|
||||
f"{format_memory_context(memory_snapshot)}\n\n"
|
||||
f"{format_pomodoro_context(status)}\n\n"
|
||||
f"{format_projects_context(projects_snapshot)}"
|
||||
)
|
||||
|
||||
def _build_messages(self, session: ChatSession) -> list[dict[str, Any]]:
|
||||
system_prompt = self._build_system_prompt(session.id)
|
||||
all_chat = [m for m in session.messages if m.role != "notice"]
|
||||
if len(all_chat) > MAX_HISTORY_MESSAGES:
|
||||
system_prompt += (
|
||||
f"\n\n[История чата: в контексте последние {MAX_HISTORY_MESSAGES} "
|
||||
f"из {len(all_chat)} сообщений. Раннее — в сводке сессии, если сохранена.]"
|
||||
)
|
||||
messages: list[dict[str, Any]] = [
|
||||
{"role": "system", "content": self._build_system_prompt()}
|
||||
{"role": "system", "content": system_prompt}
|
||||
]
|
||||
for msg in session.messages:
|
||||
if msg.role == "notice":
|
||||
continue
|
||||
chat_messages = all_chat[-MAX_HISTORY_MESSAGES:] if len(all_chat) > MAX_HISTORY_MESSAGES else all_chat
|
||||
|
||||
for msg in chat_messages:
|
||||
content = msg.content or None
|
||||
entry: dict[str, Any] = {"role": msg.role, "content": content}
|
||||
if msg.tool_calls_json:
|
||||
@@ -136,7 +146,9 @@ class ChatService:
|
||||
for tool_call in tool_calls:
|
||||
fn = tool_call["function"]
|
||||
args = LLMClient.parse_tool_arguments(fn.get("arguments", ""))
|
||||
result = await execute_tool(self.db, fn["name"], args)
|
||||
result = await execute_tool(
|
||||
self.db, fn["name"], args, session_id=session_id
|
||||
)
|
||||
tool_message = {
|
||||
"role": "tool",
|
||||
"tool_call_id": tool_call["id"],
|
||||
|
||||
Reference in New Issue
Block a user