添加长期存储,流式检查
Some checks failed
构建并部署 AI Agent 服务 / deploy (push) Has been cancelled

This commit is contained in:
2026-04-17 01:26:05 +08:00
parent 602d551fd1
commit 404efde282
37 changed files with 794 additions and 2095 deletions

View File

@@ -28,11 +28,14 @@ class ThreadHistoryService:
try:
# 查询 checkpoints 表获取用户的线程列表
async with self.checkpointer.conn.cursor() as cur:
# 查询每个线程的最新 checkpoint 和创建时间
# 在较新的 LangGraph 版本中AsyncPostgresSaver 创建的 checkpoints 表
# 没有 created_at 列,而是使用 checkpoint_id 作为时间排序依据。
# 我们可以直接按 thread_id 去重,并用 checkpoint_id 排序。
# 另外,用户的 metadata 存储在 metadata JSONB 列中。
query = """
SELECT
thread_id,
MAX(created_at) as last_updated
MAX(checkpoint_id) as last_updated
FROM checkpoints
WHERE metadata->>'user_id' = %s
GROUP BY thread_id
@@ -49,17 +52,20 @@ class ThreadHistoryService:
# 获取该线程的状态
state = await self.checkpointer.aget_tuple({"configurable": {"thread_id": thread_id}})
if state and state.values:
messages = state.values.get("messages", [])
summary = self._extract_summary(messages)
message_count = len([m for m in messages if hasattr(m, 'type') and m.type in ["human", "ai"]])
if state and hasattr(state, 'checkpoint') and isinstance(state.checkpoint, dict):
messages = state.checkpoint.get("channel_values", {}).get("messages", [])
threads.append({
"thread_id": thread_id,
"last_updated": row['last_updated'].isoformat() if row['last_updated'] else "",
"summary": summary,
"message_count": message_count
})
if messages:
summary = self._extract_summary(messages)
message_count = len([m for m in messages if hasattr(m, 'type') and m.type in ["human", "ai"]])
threads.append({
"thread_id": thread_id,
# checkpoint_id 是一个类似于 uuid 的字符串,其中可能包含时间戳信息,也可以直接作为唯一标识
"last_updated": row['last_updated'] if row['last_updated'] else "",
"summary": summary,
"message_count": message_count
})
return threads
@@ -80,10 +86,13 @@ class ThreadHistoryService:
try:
state = await self.checkpointer.aget_tuple({"configurable": {"thread_id": thread_id}})
if state is None or not state.values:
if state is None:
return []
messages = state.values.get("messages", [])
messages = state.checkpoint.get("channel_values", {}).get("messages", []) if hasattr(state, 'checkpoint') and isinstance(state.checkpoint, dict) else []
if not messages:
return []
# 转换 LangChain 消息对象为字典
result = []