主要修改: 1. 服务端新增 Thread 模型,用于存储对话列表信息,但不保存实际的历史记录 2. langgraph 配置了 InMemorySaver,添加 thread_id 参数,消息对话保存在内存中(服务重启后丢失) 3. 添加获取历史记录的 API 接口,从内存中获取 4. 添加 Graph 的单例模式,get_runnable_agent 导致的重复创建 Agent 实例的情况。 5. 优化 Agent 管理页面,更容易配置,更容易调试 6. 添加独立页面的侧边栏。
106 lines
4.0 KiB
Python
106 lines
4.0 KiB
Python
from sqlalchemy import Column, Integer, String, DateTime, JSON, Float, ForeignKey, Text
|
||
from sqlalchemy.orm import relationship
|
||
from sqlalchemy.sql import func
|
||
import time
|
||
|
||
from server.models import Base
|
||
|
||
class KnowledgeDatabase(Base):
|
||
"""知识库模型"""
|
||
__tablename__ = 'knowledge_databases'
|
||
|
||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||
db_id = Column(String, nullable=False, unique=True, index=True) # 数据库ID
|
||
name = Column(String, nullable=False) # 数据库名称
|
||
description = Column(Text, nullable=True) # 描述
|
||
embed_model = Column(String, nullable=True) # 嵌入模型名称
|
||
dimension = Column(Integer, nullable=True) # 向量维度
|
||
meta_info = Column(JSON, nullable=True) # 元数据
|
||
created_at = Column(DateTime, default=func.now()) # 创建时间
|
||
|
||
# 关系
|
||
files = relationship("KnowledgeFile", back_populates="database", cascade="all, delete-orphan")
|
||
|
||
def to_dict(self):
|
||
"""转换为字典格式,确保meta_info映射为metadata"""
|
||
result = {
|
||
"id": self.id,
|
||
"db_id": self.db_id,
|
||
"name": self.name,
|
||
"description": self.description,
|
||
"embed_model": self.embed_model,
|
||
"dimension": self.dimension,
|
||
"metadata": self.meta_info or {}, # 确保映射正确
|
||
"created_at": self.created_at.isoformat() if self.created_at else None
|
||
}
|
||
|
||
# 添加文件信息
|
||
if self.files:
|
||
result["files"] = {file.file_id: file.to_dict() for file in self.files}
|
||
else:
|
||
result["files"] = {}
|
||
|
||
return result
|
||
|
||
class KnowledgeFile(Base):
|
||
"""知识库文件模型"""
|
||
__tablename__ = 'knowledge_files'
|
||
|
||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||
file_id = Column(String, nullable=False, index=True) # 文件ID
|
||
database_id = Column(String, ForeignKey('knowledge_databases.db_id'), nullable=False) # 所属数据库ID
|
||
filename = Column(String, nullable=False) # 文件名
|
||
path = Column(String, nullable=False) # 文件路径
|
||
file_type = Column(String, nullable=False) # 文件类型
|
||
status = Column(String, nullable=False) # 处理状态
|
||
created_at = Column(DateTime, default=func.now()) # 创建时间
|
||
|
||
# 关系
|
||
database = relationship("KnowledgeDatabase", back_populates="files")
|
||
nodes = relationship("KnowledgeNode", back_populates="file", cascade="all, delete-orphan")
|
||
|
||
def to_dict(self):
|
||
"""转换为字典格式"""
|
||
result = {
|
||
"file_id": self.file_id,
|
||
"filename": self.filename,
|
||
"path": self.path,
|
||
"type": self.file_type,
|
||
"status": self.status,
|
||
"created_at": self.created_at.timestamp() if self.created_at else time.time()
|
||
}
|
||
|
||
# 添加节点信息
|
||
if self.nodes:
|
||
result["nodes"] = [node.to_dict() for node in self.nodes]
|
||
else:
|
||
result["nodes"] = []
|
||
|
||
return result
|
||
|
||
class KnowledgeNode(Base):
|
||
"""知识块模型"""
|
||
__tablename__ = 'knowledge_nodes'
|
||
|
||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||
file_id = Column(String, ForeignKey('knowledge_files.file_id'), nullable=False) # 所属文件ID
|
||
text = Column(Text, nullable=False) # 文本内容
|
||
hash = Column(String, nullable=True) # 文本哈希值
|
||
start_char_idx = Column(Integer, nullable=True) # 开始字符索引
|
||
end_char_idx = Column(Integer, nullable=True) # 结束字符索引
|
||
meta_info = Column(JSON, nullable=True) # 元数据
|
||
|
||
# 关系
|
||
file = relationship("KnowledgeFile", back_populates="nodes")
|
||
|
||
def to_dict(self):
|
||
"""转换为字典格式,确保meta_info映射为metadata"""
|
||
return {
|
||
"id": self.id,
|
||
"file_id": self.file_id,
|
||
"text": self.text,
|
||
"hash": self.hash,
|
||
"start_char_idx": self.start_char_idx,
|
||
"end_char_idx": self.end_char_idx,
|
||
"metadata": self.meta_info or {} # 确保映射正确
|
||
} |