feat: 添加数据库迁移、清空聊天记录按钮 - 复用SAVE_HISTORY接口
This commit is contained in:
@ -74,5 +74,13 @@ class BackendClient:
|
||||
)
|
||||
return self._server.send(packet).body.get("history", [])
|
||||
|
||||
def clear_history(self) -> Dict:
|
||||
packet = Packet(
|
||||
id=self._next_id(),
|
||||
type=PacketType.SAVE_HISTORY,
|
||||
body={"messages": [{"action": "clear"}]}
|
||||
)
|
||||
return self._server.send(packet).body
|
||||
|
||||
def shutdown(self) -> None:
|
||||
self._server.shutdown()
|
||||
|
||||
@ -71,18 +71,20 @@ class EmbeddedGraphDB:
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_relation_type ON relations(relation_type)")
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_relation_status ON relations(status)")
|
||||
|
||||
# 创建聊天记录表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS chat_records (
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE type='table' AND name='chat_records'
|
||||
""")
|
||||
if not cursor.fetchone():
|
||||
cursor.execute("""
|
||||
CREATE TABLE chat_records (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
role TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
# 创建聊天记录索引
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_chat_created ON chat_records(created_at)")
|
||||
cursor.execute("CREATE INDEX idx_chat_created ON chat_records(created_at)")
|
||||
|
||||
self.conn.commit()
|
||||
|
||||
@ -445,6 +447,13 @@ class EmbeddedGraphDB:
|
||||
""", (limit,))
|
||||
return [{"role": row[0], "content": row[1]} for row in cursor.fetchall()]
|
||||
|
||||
def clear_chat_records(self) -> Dict:
|
||||
"""清空聊天记录(保留图数据库)"""
|
||||
cursor = self.conn.cursor()
|
||||
cursor.execute("DELETE FROM chat_records")
|
||||
self.conn.commit()
|
||||
return {"cleared": True}
|
||||
|
||||
def close(self):
|
||||
"""关闭数据库连接"""
|
||||
if self.conn:
|
||||
|
||||
@ -345,6 +345,9 @@ class BackendServer:
|
||||
|
||||
def _handle_save_history(self, body: Dict) -> Dict:
|
||||
messages = body.get("messages", [])
|
||||
if messages and messages[0].get("action") == "clear":
|
||||
self._graph.clear_chat_records()
|
||||
return {"status": "history_cleared"}
|
||||
result = self._graph.save_chat_records(messages)
|
||||
return {"status": "history_saved"}
|
||||
|
||||
|
||||
@ -198,3 +198,21 @@ def test_get_chat_records_default_limit(db):
|
||||
|
||||
history_default = db.get_chat_records()
|
||||
assert len(history_default) == 100
|
||||
|
||||
|
||||
def test_clear_chat_records(db):
|
||||
"""测试清空聊天记录"""
|
||||
db.save_chat_records([
|
||||
{"role": "user", "content": "测试1"},
|
||||
{"role": "assistant", "content": "回复1"},
|
||||
{"role": "user", "content": "测试2"},
|
||||
])
|
||||
|
||||
history = db.get_chat_records()
|
||||
assert len(history) == 3
|
||||
|
||||
result = db.clear_chat_records()
|
||||
assert result["cleared"] is True
|
||||
|
||||
history_after = db.get_chat_records()
|
||||
assert len(history_after) == 0
|
||||
|
||||
14
ui/app.py
14
ui/app.py
@ -144,6 +144,20 @@ class GraphMemoryApp(App):
|
||||
|
||||
asyncio.create_task(self._process(user_input))
|
||||
|
||||
def on_input_box_clear_history(self, event) -> None:
|
||||
"""处理清空聊天记录事件"""
|
||||
if not self._backend_client:
|
||||
self.notify("后端未初始化", title="错误", severity="error")
|
||||
return
|
||||
|
||||
self._backend_client.clear_history()
|
||||
|
||||
from .widgets.message_history import MessageHistory
|
||||
history = self.query_one(MessageHistory)
|
||||
history.clear_messages()
|
||||
|
||||
self.notify("聊天记录已清空,AI记忆保持不变", title="提示", severity="information")
|
||||
|
||||
async def _process(self, user_input: str) -> None:
|
||||
from .widgets.message_history import MessageHistory
|
||||
from .widgets.status_bar import StatusBar
|
||||
|
||||
@ -14,6 +14,11 @@ class InputBox(Container):
|
||||
self.content = content
|
||||
super().__init__()
|
||||
|
||||
class ClearHistory(Message):
|
||||
"""清空聊天记录事件"""
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
super().__init__(**kwargs)
|
||||
self._history: list[str] = []
|
||||
@ -26,6 +31,7 @@ class InputBox(Container):
|
||||
id="input-textarea"
|
||||
)
|
||||
with Horizontal(classes="input-buttons"):
|
||||
yield Button("清空", id="clear-button", variant="default")
|
||||
yield Button("发送", id="send-button", variant="primary")
|
||||
|
||||
def on_mount(self) -> None:
|
||||
@ -38,6 +44,8 @@ class InputBox(Container):
|
||||
"""处理按钮点击"""
|
||||
if event.button.id == "send-button":
|
||||
self._send_message()
|
||||
elif event.button.id == "clear-button":
|
||||
self.post_message(self.ClearHistory())
|
||||
|
||||
def on_key(self, event) -> None:
|
||||
"""处理按键事件"""
|
||||
|
||||
Reference in New Issue
Block a user