config_config替换成memory_config
This commit is contained in:
@@ -11,7 +11,7 @@ from app.core.response_utils import success
|
||||
from app.db import get_db
|
||||
from app.dependencies import get_current_user
|
||||
from app.models.user_model import User
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.schemas.memory_reflection_schemas import Memory_Reflection
|
||||
from app.services.memory_reflection_service import (
|
||||
@@ -50,7 +50,7 @@ async def save_reflection_config(
|
||||
|
||||
api_logger.info(f"用户 {current_user.username} 保存反思配置,config_id: {config_id}")
|
||||
|
||||
data_config = DataConfigRepository.update_reflection_config(
|
||||
memory_config = MemoryConfigRepository.update_reflection_config(
|
||||
db,
|
||||
config_id=config_id,
|
||||
enable_self_reflexion=request.reflection_enabled,
|
||||
@@ -63,17 +63,17 @@ async def save_reflection_config(
|
||||
)
|
||||
|
||||
db.commit()
|
||||
db.refresh(data_config)
|
||||
db.refresh(memory_config)
|
||||
|
||||
reflection_result={
|
||||
"config_id": data_config.config_id,
|
||||
"enable_self_reflexion": data_config.enable_self_reflexion,
|
||||
"iteration_period": data_config.iteration_period,
|
||||
"reflexion_range": data_config.reflexion_range,
|
||||
"baseline": data_config.baseline,
|
||||
"reflection_model_id": data_config.reflection_model_id,
|
||||
"memory_verify": data_config.memory_verify,
|
||||
"quality_assessment": data_config.quality_assessment}
|
||||
"config_id": memory_config.config_id,
|
||||
"enable_self_reflexion": memory_config.enable_self_reflexion,
|
||||
"iteration_period": memory_config.iteration_period,
|
||||
"reflexion_range": memory_config.reflexion_range,
|
||||
"baseline": memory_config.baseline,
|
||||
"reflection_model_id": memory_config.reflection_model_id,
|
||||
"memory_verify": memory_config.memory_verify,
|
||||
"quality_assessment": memory_config.quality_assessment}
|
||||
|
||||
return success(data=reflection_result, msg="反思配置成功")
|
||||
|
||||
@@ -111,14 +111,14 @@ async def start_workspace_reflection(
|
||||
reflection_results = []
|
||||
|
||||
for data in result['apps_detailed_info']:
|
||||
if data['data_configs'] == []:
|
||||
if data['memory_configs'] == []:
|
||||
continue
|
||||
|
||||
releases = data['releases']
|
||||
data_configs = data['data_configs']
|
||||
memory_configs = data['memory_configs']
|
||||
end_users = data['end_users']
|
||||
|
||||
for base, config, user in zip(releases, data_configs, end_users):
|
||||
for base, config, user in zip(releases, memory_configs, end_users):
|
||||
# 安全地转换为整数,处理空字符串和None的情况
|
||||
print(base['config'])
|
||||
try:
|
||||
@@ -160,10 +160,10 @@ async def start_reflection_configs(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db),
|
||||
) -> dict:
|
||||
"""通过config_id查询data_config表中的反思配置信息"""
|
||||
"""通过config_id查询memory_config表中的反思配置信息"""
|
||||
try:
|
||||
api_logger.info(f"用户 {current_user.username} 查询反思配置,config_id: {config_id}")
|
||||
result = DataConfigRepository.query_reflection_config_by_id(db, config_id)
|
||||
result = MemoryConfigRepository.query_reflection_config_by_id(db, config_id)
|
||||
# 构建返回数据
|
||||
reflection_config = {
|
||||
"config_id": result.config_id,
|
||||
@@ -200,8 +200,8 @@ async def reflection_run(
|
||||
|
||||
api_logger.info(f"用户 {current_user.username} 查询反思配置,config_id: {config_id}")
|
||||
|
||||
# 使用DataConfigRepository查询反思配置
|
||||
result = DataConfigRepository.query_reflection_config_by_id(db, config_id)
|
||||
# 使用MemoryConfigRepository查询反思配置
|
||||
result = MemoryConfigRepository.query_reflection_config_by_id(db, config_id)
|
||||
if not result:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND,
|
||||
|
||||
@@ -1021,3 +1021,59 @@ async def search_chunk_by_chunk_id(
|
||||
return {"chunks": chunks}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# 测试混合检索功能
|
||||
from app.schemas.memory_config_schema import MemoryConfig
|
||||
from app.db import get_db
|
||||
from app.services.memory_config_service import MemoryConfigService
|
||||
|
||||
# 从数据库获取真实配置
|
||||
db = next(get_db())
|
||||
try:
|
||||
config_service = MemoryConfigService(db)
|
||||
|
||||
# 使用 config_id=17 获取配置
|
||||
memory_config = config_service.load_memory_config(config_id=17)
|
||||
|
||||
if not memory_config:
|
||||
print("错误:找不到 config_id=17 的配置")
|
||||
print("请先在数据库中创建配置,或修改 config_id")
|
||||
exit(1)
|
||||
|
||||
print(f"✓ 成功加载配置: {memory_config.config_name}")
|
||||
print(f" - Workspace: {memory_config.workspace_name}")
|
||||
print(f" - LLM Model: {memory_config.llm_model_name}")
|
||||
print(f" - Embedding Model: {memory_config.embedding_model_name}")
|
||||
print(f" - Storage Type: {memory_config.storage_type}")
|
||||
print()
|
||||
|
||||
# 修改这里的参数进行测试
|
||||
test_end_user_id = "021886bc-fab9-4fd5-b607-497b262e0381" # 修改为你的 end_user_id
|
||||
test_query = "小明擅长什么?" # 修改为你的查询
|
||||
|
||||
print(f"开始测试检索...")
|
||||
print(f" - Query: {test_query}")
|
||||
print(f" - End User ID: {test_end_user_id}")
|
||||
print(f" - Search Type: hybrid")
|
||||
print()
|
||||
|
||||
results = asyncio.run(run_hybrid_search(
|
||||
query_text=test_query,
|
||||
search_type="hybrid", # 可选: "keyword", "embedding", "hybrid"
|
||||
end_user_id=test_end_user_id,
|
||||
limit=10,
|
||||
include=["statements", "entities", "chunks", "summaries"],
|
||||
output_path=None,
|
||||
memory_config=memory_config,
|
||||
rerank_alpha=0.6,
|
||||
use_forgetting_rerank=False,
|
||||
use_llm_rerank=False
|
||||
))
|
||||
|
||||
except Exception as e:
|
||||
print(f"错误: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
finally:
|
||||
db.close()
|
||||
@@ -569,32 +569,32 @@ class ExtractionOrchestrator:
|
||||
if dialog_data_list and hasattr(dialog_data_list[0], 'config_id'):
|
||||
config_id = dialog_data_list[0].config_id
|
||||
|
||||
# 加载DataConfig
|
||||
data_config = None
|
||||
# 加载MemoryConfig
|
||||
memory_config = None
|
||||
if config_id:
|
||||
try:
|
||||
from app.db import SessionLocal
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
|
||||
db = SessionLocal()
|
||||
try:
|
||||
data_config = DataConfigRepository.get_by_id(db, config_id)
|
||||
memory_config = MemoryConfigRepository.get_by_id(db, config_id)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
if data_config and not data_config.emotion_enabled:
|
||||
if memory_config and not memory_config.emotion_enabled:
|
||||
logger.info("情绪提取已在配置中禁用,跳过情绪提取")
|
||||
return [{} for _ in dialog_data_list]
|
||||
|
||||
except Exception as e:
|
||||
logger.warning(f"加载DataConfig失败: {e},将跳过情绪提取")
|
||||
logger.warning(f"加载MemoryConfig失败: {e},将跳过情绪提取")
|
||||
return [{} for _ in dialog_data_list]
|
||||
else:
|
||||
logger.info("未找到config_id,跳过情绪提取")
|
||||
return [{} for _ in dialog_data_list]
|
||||
|
||||
# 如果配置未启用情绪提取,直接返回空映射
|
||||
if not data_config or not data_config.emotion_enabled:
|
||||
if not memory_config or not memory_config.emotion_enabled:
|
||||
logger.info("情绪提取未启用,跳过")
|
||||
return [{} for _ in dialog_data_list]
|
||||
|
||||
@@ -608,7 +608,7 @@ class ExtractionOrchestrator:
|
||||
total_statements += 1
|
||||
# 只处理用户的陈述句 (role 为 "user")
|
||||
if hasattr(statement, 'speaker') and statement.speaker == "user":
|
||||
all_statements.append((statement, data_config))
|
||||
all_statements.append((statement, memory_config))
|
||||
statement_metadata.append((d_idx, statement.id))
|
||||
filtered_statements += 1
|
||||
|
||||
@@ -617,7 +617,7 @@ class ExtractionOrchestrator:
|
||||
# 初始化情绪提取服务
|
||||
from app.services.emotion_extraction_service import EmotionExtractionService
|
||||
emotion_service = EmotionExtractionService(
|
||||
llm_id=data_config.emotion_model_id if data_config.emotion_model_id else None
|
||||
llm_id=memory_config.emotion_model_id if memory_config.emotion_model_id else None
|
||||
)
|
||||
|
||||
# 全局并行处理所有陈述句
|
||||
|
||||
@@ -13,7 +13,7 @@ import logging
|
||||
from typing import Optional, Dict, Any
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.core.memory.storage_services.forgetting_engine.actr_calculator import ACTRCalculator
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ def load_actr_config_from_db(
|
||||
"""
|
||||
从数据库加载 ACT-R 配置参数
|
||||
|
||||
从 PostgreSQL 的 data_config 表读取配置参数,
|
||||
从 PostgreSQL 的 memory_config 表读取配置参数,
|
||||
并计算派生参数(如 forgetting_rate)。
|
||||
|
||||
Args:
|
||||
@@ -99,7 +99,7 @@ def load_actr_config_from_db(
|
||||
|
||||
# 从数据库加载配置
|
||||
try:
|
||||
repository = DataConfigRepository()
|
||||
repository = MemoryConfigRepository()
|
||||
db_config = repository.get_by_id(db, config_id)
|
||||
|
||||
if db_config is None:
|
||||
|
||||
@@ -539,11 +539,11 @@ class ForgettingStrategy:
|
||||
LLM 客户端实例,如果无法获取则返回 None
|
||||
"""
|
||||
try:
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
|
||||
|
||||
# 从数据库读取配置
|
||||
repository = DataConfigRepository()
|
||||
repository = MemoryConfigRepository()
|
||||
db_config = repository.get_by_id(db, config_id)
|
||||
|
||||
if db_config is None or db_config.llm_id is None:
|
||||
|
||||
@@ -22,7 +22,7 @@ class MemoryReadNode(BaseNode):
|
||||
raise RuntimeError("End user id is required")
|
||||
|
||||
return await MemoryAgentService().read_memory(
|
||||
group_id=end_user_id,
|
||||
end_user_id=end_user_id,
|
||||
message=self._render_template(self.typed_config.message, state),
|
||||
config_id=str(self.typed_config.config_id),
|
||||
search_switch=self.typed_config.search_switch,
|
||||
|
||||
@@ -18,7 +18,7 @@ from .appshare_model import AppShare
|
||||
from .release_share_model import ReleaseShare
|
||||
from .conversation_model import Conversation, Message
|
||||
from .api_key_model import ApiKey, ApiKeyLog, ApiKeyType
|
||||
from .data_config_model import DataConfig
|
||||
from .memory_config_model import MemoryConfig
|
||||
from .multi_agent_model import MultiAgentConfig, AgentInvocation
|
||||
from .workflow_model import WorkflowConfig, WorkflowExecution, WorkflowNodeExecution
|
||||
from .retrieval_info import RetrievalInfo
|
||||
@@ -57,7 +57,7 @@ __all__ = [
|
||||
"ApiKey",
|
||||
"ApiKeyLog",
|
||||
"ApiKeyType",
|
||||
"DataConfig",
|
||||
"MemoryConfig",
|
||||
"MultiAgentConfig",
|
||||
"AgentInvocation",
|
||||
"WorkflowConfig",
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
import datetime
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, Integer, Float
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from app.db import Base
|
||||
|
||||
|
||||
class DataConfig(Base):
|
||||
"""数据配置表 - 用于存储记忆系统的配置参数"""
|
||||
__tablename__ = "data_config"
|
||||
|
||||
# 主键
|
||||
config_id = Column(Integer, primary_key=True, autoincrement=True, comment="配置ID")
|
||||
|
||||
# 基本信息
|
||||
config_name = Column(String, nullable=False, comment="配置名称")
|
||||
config_desc = Column(String, nullable=True, comment="配置描述")
|
||||
|
||||
# 组织信息
|
||||
workspace_id = Column(UUID(as_uuid=True), nullable=True, comment="工作空间ID")
|
||||
group_id = Column(String, nullable=True, comment="组ID")
|
||||
user_id = Column(String, nullable=True, comment="用户ID")
|
||||
apply_id = Column(String, nullable=True, comment="应用ID")
|
||||
|
||||
# 模型选择(从workspace继承)
|
||||
llm_id = Column(String, nullable=True, comment="LLM模型配置ID")
|
||||
embedding_id = Column(String, nullable=True, comment="嵌入模型配置ID")
|
||||
rerank_id = Column(String, nullable=True, comment="重排序模型配置ID")
|
||||
|
||||
# 记忆萃取引擎配置
|
||||
enable_llm_dedup_blockwise = Column(Boolean, default=True, comment="启用LLM决策去重")
|
||||
enable_llm_disambiguation = Column(Boolean, default=True, comment="启用LLM决策消歧")
|
||||
deep_retrieval = Column(Boolean, default=True, comment="深度检索开关")
|
||||
|
||||
# 阈值配置 (0-1 之间的浮点数)
|
||||
t_type_strict = Column(Float, default=0.8, comment="类型严格阈值")
|
||||
t_name_strict = Column(Float, default=0.8, comment="名称严格阈值")
|
||||
t_overall = Column(Float, default=0.8, comment="综合阈值")
|
||||
|
||||
# 状态配置
|
||||
state = Column(Boolean, default=False, comment="配置使用状态")
|
||||
|
||||
# 分块策略
|
||||
chunker_strategy = Column(String, default="RecursiveChunker", comment="分块策略")
|
||||
|
||||
# 剪枝配置
|
||||
pruning_enabled = Column(Boolean, default=False, comment="是否启动智能语义剪枝")
|
||||
pruning_scene = Column(String, nullable=True, comment="智能剪枝场景:education/online_service/outbound")
|
||||
pruning_threshold = Column(Float, nullable=True, comment="智能语义剪枝阈值(0-0.9)")
|
||||
|
||||
# 自我反思配置
|
||||
enable_self_reflexion = Column(Boolean, default=False, comment="是否启用自我反思")
|
||||
iteration_period = Column(String, default="3", comment="反思迭代周期")
|
||||
reflexion_range = Column(String, default="partial", comment="反思范围:部分/全部")
|
||||
baseline = Column(String, default="TIME", comment="基线:时间/事实/时间和事实")
|
||||
reflection_model_id = Column(String, nullable=True, comment="反思模型ID")
|
||||
memory_verify = Column(Boolean, default=True, comment="记忆验证")
|
||||
quality_assessment = Column(Boolean, default=True, comment="质量评估")
|
||||
|
||||
# 遗忘引擎配置
|
||||
statement_granularity = Column(Integer, default=2, comment="陈述提取颗粒度,挡位 1/2/3")
|
||||
include_dialogue_context = Column(Boolean, default=False, comment="是否包含对话上下文")
|
||||
max_context = Column(Integer, default=1000, comment="对话语境中包含字符的最大数量")
|
||||
lambda_time = Column("lambda_time", Float, default=0.5, comment="最低保持度,0-1 小数")
|
||||
lambda_mem = Column("lambda_mem", Float, default=0.5, comment="遗忘率,0-1 小数")
|
||||
offset = Column("offset", Float, default=0.0, comment="偏移度,0-1 小数")
|
||||
|
||||
# ACT-R 遗忘引擎配置
|
||||
decay_constant = Column(Float, default=0.5, comment="ACT-R衰减常数d,默认0.5")
|
||||
forgetting_threshold = Column(Float, default=0.3, comment="遗忘阈值,默认0.3")
|
||||
forgetting_interval_hours = Column(Integer, default=24, comment="遗忘周期间隔(小时),默认24")
|
||||
enable_llm_summary = Column(Boolean, default=True, comment="是否使用LLM生成摘要,默认True")
|
||||
max_merge_batch_size = Column(Integer, default=100, comment="单次最大融合节点对数,默认100")
|
||||
max_history_length = Column(Integer, default=100, comment="访问历史最大长度,默认100")
|
||||
min_days_since_access = Column(Integer, default=30, comment="最小未访问天数,默认30")
|
||||
|
||||
# 情绪引擎配置
|
||||
emotion_enabled = Column(Boolean, default=True, comment="是否启用情绪提取")
|
||||
emotion_model_id = Column(String, nullable=True, comment="情绪分析专用模型ID")
|
||||
emotion_extract_keywords = Column(Boolean, default=True, comment="是否提取情绪关键词")
|
||||
emotion_min_intensity = Column(Float, default=0.1, comment="最小情绪强度阈值")
|
||||
emotion_enable_subject = Column(Boolean, default=True, comment="是否启用主体分类")
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, default=datetime.datetime.now, comment="创建时间")
|
||||
updated_at = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment="更新时间")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<DataConfig(config_id={self.config_id}, config_name={self.config_name})>"
|
||||
@@ -1,39 +1,88 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Memory Configuration Model - Backward Compatibility
|
||||
import datetime
|
||||
from sqlalchemy import Column, String, Boolean, DateTime, Integer, Float
|
||||
from sqlalchemy.dialects.postgresql import UUID
|
||||
from app.db import Base
|
||||
|
||||
This module provides backward compatibility for imports.
|
||||
All classes have been moved to app.schemas.memory_config_schema.
|
||||
|
||||
DEPRECATED: Import from app.schemas.memory_config_schema instead.
|
||||
"""
|
||||
class MemoryConfig(Base):
|
||||
"""记忆配置表 - 用于存储记忆系统的配置参数"""
|
||||
__tablename__ = "memory_config"
|
||||
|
||||
# Re-export for backward compatibility
|
||||
from app.schemas.memory_config_schema import (
|
||||
ConfigurationError,
|
||||
InvalidConfigError,
|
||||
MemoryConfig,
|
||||
MemoryConfigValidation,
|
||||
ModelInactiveError,
|
||||
ModelNotFoundError,
|
||||
ModelValidation,
|
||||
WorkspaceNotFoundError,
|
||||
WorkspaceValidation,
|
||||
validate_memory_config_data,
|
||||
validate_model_data,
|
||||
validate_workspace_data,
|
||||
)
|
||||
# 主键
|
||||
config_id = Column(Integer, primary_key=True, autoincrement=True, comment="配置ID")
|
||||
|
||||
__all__ = [
|
||||
"ConfigurationError",
|
||||
"InvalidConfigError",
|
||||
"MemoryConfig",
|
||||
"MemoryConfigValidation",
|
||||
"ModelInactiveError",
|
||||
"ModelNotFoundError",
|
||||
"ModelValidation",
|
||||
"WorkspaceNotFoundError",
|
||||
"WorkspaceValidation",
|
||||
"validate_memory_config_data",
|
||||
"validate_model_data",
|
||||
"validate_workspace_data",
|
||||
]
|
||||
# 基本信息
|
||||
config_name = Column(String, nullable=False, comment="配置名称")
|
||||
config_desc = Column(String, nullable=True, comment="配置描述")
|
||||
|
||||
# 组织信息
|
||||
workspace_id = Column(UUID(as_uuid=True), nullable=True, comment="工作空间ID")
|
||||
group_id = Column(String, nullable=True, comment="组ID")
|
||||
user_id = Column(String, nullable=True, comment="用户ID")
|
||||
apply_id = Column(String, nullable=True, comment="应用ID")
|
||||
|
||||
# 模型选择(从workspace继承)
|
||||
llm_id = Column(String, nullable=True, comment="LLM模型配置ID")
|
||||
embedding_id = Column(String, nullable=True, comment="嵌入模型配置ID")
|
||||
rerank_id = Column(String, nullable=True, comment="重排序模型配置ID")
|
||||
|
||||
# 记忆萃取引擎配置
|
||||
enable_llm_dedup_blockwise = Column(Boolean, default=True, comment="启用LLM决策去重")
|
||||
enable_llm_disambiguation = Column(Boolean, default=True, comment="启用LLM决策消歧")
|
||||
deep_retrieval = Column(Boolean, default=True, comment="深度检索开关")
|
||||
|
||||
# 阈值配置 (0-1 之间的浮点数)
|
||||
t_type_strict = Column(Float, default=0.8, comment="类型严格阈值")
|
||||
t_name_strict = Column(Float, default=0.8, comment="名称严格阈值")
|
||||
t_overall = Column(Float, default=0.8, comment="综合阈值")
|
||||
|
||||
# 状态配置
|
||||
state = Column(Boolean, default=False, comment="配置使用状态")
|
||||
|
||||
# 分块策略
|
||||
chunker_strategy = Column(String, default="RecursiveChunker", comment="分块策略")
|
||||
|
||||
# 剪枝配置
|
||||
pruning_enabled = Column(Boolean, default=False, comment="是否启动智能语义剪枝")
|
||||
pruning_scene = Column(String, nullable=True, comment="智能剪枝场景:education/online_service/outbound")
|
||||
pruning_threshold = Column(Float, nullable=True, comment="智能语义剪枝阈值(0-0.9)")
|
||||
|
||||
# 自我反思配置
|
||||
enable_self_reflexion = Column(Boolean, default=False, comment="是否启用自我反思")
|
||||
iteration_period = Column(String, default="3", comment="反思迭代周期")
|
||||
reflexion_range = Column(String, default="partial", comment="反思范围:部分/全部")
|
||||
baseline = Column(String, default="TIME", comment="基线:时间/事实/时间和事实")
|
||||
reflection_model_id = Column(String, nullable=True, comment="反思模型ID")
|
||||
memory_verify = Column(Boolean, default=True, comment="记忆验证")
|
||||
quality_assessment = Column(Boolean, default=True, comment="质量评估")
|
||||
|
||||
# 遗忘引擎配置
|
||||
statement_granularity = Column(Integer, default=2, comment="陈述提取颗粒度,挡位 1/2/3")
|
||||
include_dialogue_context = Column(Boolean, default=False, comment="是否包含对话上下文")
|
||||
max_context = Column(Integer, default=1000, comment="对话语境中包含字符的最大数量")
|
||||
lambda_time = Column("lambda_time", Float, default=0.5, comment="最低保持度,0-1 小数")
|
||||
lambda_mem = Column("lambda_mem", Float, default=0.5, comment="遗忘率,0-1 小数")
|
||||
offset = Column("offset", Float, default=0.0, comment="偏移度,0-1 小数")
|
||||
|
||||
# ACT-R 遗忘引擎配置
|
||||
decay_constant = Column(Float, default=0.5, comment="ACT-R衰减常数d,默认0.5")
|
||||
forgetting_threshold = Column(Float, default=0.3, comment="遗忘阈值,默认0.3")
|
||||
forgetting_interval_hours = Column(Integer, default=24, comment="遗忘周期间隔(小时),默认24")
|
||||
enable_llm_summary = Column(Boolean, default=True, comment="是否使用LLM生成摘要,默认True")
|
||||
max_merge_batch_size = Column(Integer, default=100, comment="单次最大融合节点对数,默认100")
|
||||
max_history_length = Column(Integer, default=100, comment="访问历史最大长度,默认100")
|
||||
min_days_since_access = Column(Integer, default=30, comment="最小未访问天数,默认30")
|
||||
|
||||
# 情绪引擎配置
|
||||
emotion_enabled = Column(Boolean, default=True, comment="是否启用情绪提取")
|
||||
emotion_model_id = Column(String, nullable=True, comment="情绪分析专用模型ID")
|
||||
emotion_extract_keywords = Column(Boolean, default=True, comment="是否提取情绪关键词")
|
||||
emotion_min_intensity = Column(Float, default=0.1, comment="最小情绪强度阈值")
|
||||
emotion_enable_subject = Column(Boolean, default=True, comment="是否启用主体分类")
|
||||
|
||||
# 时间戳
|
||||
created_at = Column(DateTime, default=datetime.datetime.now, comment="创建时间")
|
||||
updated_at = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now, comment="更新时间")
|
||||
|
||||
def __repr__(self):
|
||||
return f"<MemoryConfig(config_id={self.config_id}, config_name={self.config_name})>"
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""数据配置Repository模块
|
||||
"""记忆配置Repository模块
|
||||
|
||||
本模块提供data_config表的数据访问层,使用SQLAlchemy ORM进行数据库操作。
|
||||
本模块提供memory_config表的数据访问层,使用SQLAlchemy ORM进行数据库操作。
|
||||
包括CRUD操作和Neo4j Cypher查询常量。
|
||||
|
||||
Classes:
|
||||
DataConfigRepository: 数据配置仓储类,提供CRUD操作
|
||||
MemoryConfigRepository: 记忆配置仓储类,提供CRUD操作
|
||||
"""
|
||||
|
||||
import uuid
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
from app.core.exceptions import BusinessException
|
||||
from app.core.logging_config import get_config_logger, get_db_logger
|
||||
from app.models.data_config_model import DataConfig
|
||||
from app.models.memory_config_model import MemoryConfig
|
||||
from app.schemas.memory_storage_schema import (
|
||||
ConfigKey,
|
||||
ConfigParamsCreate,
|
||||
@@ -28,11 +28,11 @@ db_logger = get_db_logger()
|
||||
# 获取配置专用日志器
|
||||
config_logger = get_config_logger()
|
||||
|
||||
TABLE_NAME = "data_config"
|
||||
class DataConfigRepository:
|
||||
"""数据配置Repository
|
||||
TABLE_NAME = "memory_config"
|
||||
class MemoryConfigRepository:
|
||||
"""记忆配置Repository
|
||||
|
||||
提供data_config表的数据访问方法,包括:
|
||||
提供memory_config表的数据访问方法,包括:
|
||||
- SQLAlchemy ORM 数据库操作
|
||||
- Neo4j Cypher查询常量
|
||||
"""
|
||||
@@ -115,7 +115,7 @@ class DataConfigRepository:
|
||||
reflection_model_id: str,
|
||||
memory_verify: bool,
|
||||
quality_assessment: bool
|
||||
) -> DataConfig:
|
||||
) -> MemoryConfig:
|
||||
"""构建反思配置更新语句(SQLAlchemy text() 命名参数)
|
||||
|
||||
Args:
|
||||
@@ -130,28 +130,28 @@ class DataConfigRepository:
|
||||
config_id: 配置ID
|
||||
|
||||
Returns:
|
||||
Data
|
||||
MemoryConfig
|
||||
|
||||
Raises:
|
||||
ValueError: 没有字段需要更新时抛出
|
||||
"""
|
||||
db_logger.debug(f"构建反思配置更新语句: config_id={config_id}")
|
||||
stmt = select(DataConfig).where(DataConfig.config_id == config_id)
|
||||
data_config_obj = db.scalars(stmt).first()
|
||||
if not data_config_obj:
|
||||
stmt = select(MemoryConfig).where(MemoryConfig.config_id == config_id)
|
||||
memory_config_obj = db.scalars(stmt).first()
|
||||
if not memory_config_obj:
|
||||
raise BusinessException
|
||||
data_config_obj.enable_self_reflexion = enable_self_reflexion
|
||||
data_config_obj.iteration_period = iteration_period
|
||||
data_config_obj.reflexion_range = reflexion_range
|
||||
data_config_obj.baseline = baseline
|
||||
data_config_obj.reflection_model_id = reflection_model_id
|
||||
data_config_obj.memory_verify = memory_verify
|
||||
data_config_obj.quality_assessment = quality_assessment
|
||||
memory_config_obj.enable_self_reflexion = enable_self_reflexion
|
||||
memory_config_obj.iteration_period = iteration_period
|
||||
memory_config_obj.reflexion_range = reflexion_range
|
||||
memory_config_obj.baseline = baseline
|
||||
memory_config_obj.reflection_model_id = reflection_model_id
|
||||
memory_config_obj.memory_verify = memory_verify
|
||||
memory_config_obj.quality_assessment = quality_assessment
|
||||
|
||||
return data_config_obj
|
||||
return memory_config_obj
|
||||
|
||||
@staticmethod
|
||||
def query_reflection_config_by_id(db: Session, config_id: int) -> DataConfig:
|
||||
def query_reflection_config_by_id(db: Session, config_id: int) -> MemoryConfig:
|
||||
"""构建反思配置查询语句,通过config_id查询反思配置(SQLAlchemy text() 命名参数)
|
||||
|
||||
Args:
|
||||
@@ -162,13 +162,13 @@ class DataConfigRepository:
|
||||
Tuple[str, Dict]: (SQL查询字符串, 参数字典)
|
||||
"""
|
||||
db_logger.debug(f"构建反思配置查询语句: config_id={config_id}")
|
||||
stmt = select(DataConfig).where(DataConfig.config_id == config_id)
|
||||
data_config = db.scalars(stmt).first()
|
||||
if not data_config:
|
||||
stmt = select(MemoryConfig).where(MemoryConfig.config_id == config_id)
|
||||
memory_config = db.scalars(stmt).first()
|
||||
if not memory_config:
|
||||
raise RuntimeError("reflection config not found")
|
||||
return data_config
|
||||
return memory_config
|
||||
@staticmethod
|
||||
def query_reflection_config_by_workspace_id(db: Session, workspace_id: uuid.UUID) -> DataConfig:
|
||||
def query_reflection_config_by_workspace_id(db: Session, workspace_id: uuid.UUID) -> MemoryConfig:
|
||||
"""构建查询所有配置的语句(SQLAlchemy text() 命名参数)
|
||||
|
||||
Args:
|
||||
@@ -180,11 +180,11 @@ class DataConfigRepository:
|
||||
"""
|
||||
db_logger.debug(f"构建查询所有配置语句: workspace_id={workspace_id}")
|
||||
|
||||
stmt = select(DataConfig).where(DataConfig.workspace_id == workspace_id)
|
||||
data_config = db.scalars(stmt).first()
|
||||
if not data_config:
|
||||
stmt = select(MemoryConfig).where(MemoryConfig.workspace_id == workspace_id)
|
||||
memory_config = db.scalars(stmt).first()
|
||||
if not memory_config:
|
||||
raise RuntimeError("reflection config not found")
|
||||
return data_config
|
||||
return memory_config
|
||||
|
||||
|
||||
@staticmethod
|
||||
@@ -208,20 +208,20 @@ class DataConfigRepository:
|
||||
return query, params
|
||||
|
||||
@staticmethod
|
||||
def create(db: Session, params: ConfigParamsCreate) -> DataConfig:
|
||||
"""创建数据配置
|
||||
def create(db: Session, params: ConfigParamsCreate) -> MemoryConfig:
|
||||
"""创建记忆配置
|
||||
|
||||
Args:
|
||||
db: 数据库会话
|
||||
params: 配置参数创建模型
|
||||
|
||||
Returns:
|
||||
DataConfig: 创建的配置对象
|
||||
MemoryConfig: 创建的配置对象
|
||||
"""
|
||||
db_logger.debug(f"创建数据配置: config_name={params.config_name}, workspace_id={params.workspace_id}")
|
||||
db_logger.debug(f"创建记忆配置: config_name={params.config_name}, workspace_id={params.workspace_id}")
|
||||
|
||||
try:
|
||||
db_config = DataConfig(
|
||||
db_config = MemoryConfig(
|
||||
config_name=params.config_name,
|
||||
config_desc=params.config_desc,
|
||||
workspace_id=params.workspace_id,
|
||||
@@ -232,16 +232,16 @@ class DataConfigRepository:
|
||||
db.add(db_config)
|
||||
db.flush() # 获取自增ID但不提交事务
|
||||
|
||||
db_logger.info(f"数据配置已添加到会话: {db_config.config_name} (ID: {db_config.config_id})")
|
||||
db_logger.info(f"记忆配置已添加到会话: {db_config.config_name} (ID: {db_config.config_id})")
|
||||
return db_config
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
db_logger.error(f"创建数据配置失败: {params.config_name} - {str(e)}")
|
||||
db_logger.error(f"创建记忆配置失败: {params.config_name} - {str(e)}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def update(db: Session, update: ConfigUpdate) -> Optional[DataConfig]:
|
||||
def update(db: Session, update: ConfigUpdate) -> Optional[MemoryConfig]:
|
||||
"""更新基础配置
|
||||
|
||||
Args:
|
||||
@@ -249,17 +249,17 @@ class DataConfigRepository:
|
||||
update: 配置更新模型
|
||||
|
||||
Returns:
|
||||
Optional[DataConfig]: 更新后的配置对象,不存在则返回None
|
||||
Optional[MemoryConfig]: 更新后的配置对象,不存在则返回None
|
||||
|
||||
Raises:
|
||||
ValueError: 没有字段需要更新时抛出
|
||||
"""
|
||||
db_logger.debug(f"更新数据配置: config_id={update.config_id}")
|
||||
db_logger.debug(f"更新记忆配置: config_id={update.config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == update.config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == update.config_id).first()
|
||||
if not db_config:
|
||||
db_logger.warning(f"数据配置不存在: config_id={update.config_id}")
|
||||
db_logger.warning(f"记忆配置不存在: config_id={update.config_id}")
|
||||
return None
|
||||
|
||||
# 更新字段
|
||||
@@ -277,17 +277,17 @@ class DataConfigRepository:
|
||||
db.commit()
|
||||
db.refresh(db_config)
|
||||
|
||||
db_logger.info(f"数据配置更新成功: {db_config.config_name} (ID: {update.config_id})")
|
||||
db_logger.info(f"记忆配置更新成功: {db_config.config_name} (ID: {update.config_id})")
|
||||
return db_config
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
db_logger.error(f"更新数据配置失败: config_id={update.config_id} - {str(e)}")
|
||||
db_logger.error(f"更新记忆配置失败: config_id={update.config_id} - {str(e)}")
|
||||
raise
|
||||
|
||||
|
||||
@staticmethod
|
||||
def update_extracted(db: Session, update: ConfigUpdateExtracted) -> Optional[DataConfig]:
|
||||
def update_extracted(db: Session, update: ConfigUpdateExtracted) -> Optional[MemoryConfig]:
|
||||
"""更新记忆萃取引擎配置
|
||||
|
||||
Args:
|
||||
@@ -295,7 +295,7 @@ class DataConfigRepository:
|
||||
update: 萃取配置更新模型
|
||||
|
||||
Returns:
|
||||
Optional[DataConfig]: 更新后的配置对象,不存在则返回None
|
||||
Optional[MemoryConfig]: 更新后的配置对象,不存在则返回None
|
||||
|
||||
Raises:
|
||||
ValueError: 没有字段需要更新时抛出
|
||||
@@ -303,9 +303,9 @@ class DataConfigRepository:
|
||||
db_logger.debug(f"更新萃取配置: config_id={update.config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == update.config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == update.config_id).first()
|
||||
if not db_config:
|
||||
db_logger.warning(f"数据配置不存在: config_id={update.config_id}")
|
||||
db_logger.warning(f"记忆配置不存在: config_id={update.config_id}")
|
||||
return None
|
||||
|
||||
# 更新字段映射
|
||||
@@ -360,7 +360,7 @@ class DataConfigRepository:
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def update_forget(db: Session, update: ConfigUpdateForget) -> Optional[DataConfig]:
|
||||
def update_forget(db: Session, update: ConfigUpdateForget) -> Optional[MemoryConfig]:
|
||||
"""更新遗忘引擎配置
|
||||
|
||||
Args:
|
||||
@@ -368,7 +368,7 @@ class DataConfigRepository:
|
||||
update: 遗忘配置更新模型
|
||||
|
||||
Returns:
|
||||
Optional[DataConfig]: 更新后的配置对象,不存在则返回None
|
||||
Optional[MemoryConfig]: 更新后的配置对象,不存在则返回None
|
||||
|
||||
Raises:
|
||||
ValueError: 没有字段需要更新时抛出
|
||||
@@ -376,9 +376,9 @@ class DataConfigRepository:
|
||||
db_logger.debug(f"更新遗忘配置: config_id={update.config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == update.config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == update.config_id).first()
|
||||
if not db_config:
|
||||
db_logger.warning(f"数据配置不存在: config_id={update.config_id}")
|
||||
db_logger.warning(f"记忆配置不存在: config_id={update.config_id}")
|
||||
return None
|
||||
|
||||
# 更新字段
|
||||
@@ -421,7 +421,7 @@ class DataConfigRepository:
|
||||
db_logger.debug(f"查询萃取配置: config_id={config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == config_id).first()
|
||||
if not db_config:
|
||||
db_logger.debug(f"萃取配置不存在: config_id={config_id}")
|
||||
return None
|
||||
@@ -470,7 +470,7 @@ class DataConfigRepository:
|
||||
db_logger.debug(f"查询遗忘配置: config_id={config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == config_id).first()
|
||||
if not db_config:
|
||||
db_logger.debug(f"遗忘配置不存在: config_id={config_id}")
|
||||
return None
|
||||
@@ -489,39 +489,39 @@ class DataConfigRepository:
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def get_by_id(db: Session, config_id: int) -> Optional[DataConfig]:
|
||||
"""根据ID获取数据配置
|
||||
def get_by_id(db: Session, config_id: int) -> Optional[MemoryConfig]:
|
||||
"""根据ID获取记忆配置
|
||||
|
||||
Args:
|
||||
db: 数据库会话
|
||||
config_id: 配置ID
|
||||
|
||||
Returns:
|
||||
Optional[DataConfig]: 配置对象,不存在则返回None
|
||||
Optional[MemoryConfig]: 配置对象,不存在则返回None
|
||||
"""
|
||||
db_logger.debug(f"根据ID查询数据配置: config_id={config_id}")
|
||||
db_logger.debug(f"根据ID查询记忆配置: config_id={config_id}")
|
||||
|
||||
try:
|
||||
config = db.query(DataConfig).filter(DataConfig.config_id == config_id).first()
|
||||
config = db.query(MemoryConfig).filter(MemoryConfig.config_id == config_id).first()
|
||||
|
||||
if config:
|
||||
db_logger.debug(f"数据配置查询成功: {config.config_name} (ID: {config_id})")
|
||||
db_logger.debug(f"记忆配置查询成功: {config.config_name} (ID: {config_id})")
|
||||
else:
|
||||
db_logger.debug(f"数据配置不存在: config_id={config_id}")
|
||||
db_logger.debug(f"记忆配置不存在: config_id={config_id}")
|
||||
return config
|
||||
except Exception as e:
|
||||
db_logger.error(f"根据ID查询数据配置失败: config_id={config_id} - {str(e)}")
|
||||
db_logger.error(f"根据ID查询记忆配置失败: config_id={config_id} - {str(e)}")
|
||||
raise
|
||||
@staticmethod
|
||||
def get_config_with_workspace(db: Session, config_id: int) -> Optional[tuple]:
|
||||
"""Get data config and its associated workspace information
|
||||
"""Get memory config and its associated workspace information
|
||||
|
||||
Args:
|
||||
db: Database session
|
||||
config_id: Configuration ID
|
||||
|
||||
Returns:
|
||||
Optional[tuple]: (DataConfig, Workspace) tuple, None if not found
|
||||
Optional[tuple]: (MemoryConfig, Workspace) tuple, None if not found
|
||||
|
||||
Raises:
|
||||
ValueError: Raised when config exists but workspace doesn't
|
||||
@@ -541,19 +541,19 @@ class DataConfigRepository:
|
||||
}
|
||||
)
|
||||
|
||||
db_logger.debug(f"Querying data config and workspace: config_id={config_id}")
|
||||
db_logger.debug(f"Querying memory config and workspace: config_id={config_id}")
|
||||
|
||||
try:
|
||||
# Use join query to get both config and workspace
|
||||
result = db.query(DataConfig, Workspace).join(
|
||||
Workspace, DataConfig.workspace_id == Workspace.id
|
||||
).filter(DataConfig.config_id == config_id).first()
|
||||
result = db.query(MemoryConfig, Workspace).join(
|
||||
Workspace, MemoryConfig.workspace_id == Workspace.id
|
||||
).filter(MemoryConfig.config_id == config_id).first()
|
||||
|
||||
elapsed_ms = (time.time() - start_time) * 1000
|
||||
|
||||
if not result:
|
||||
# Check if config exists but workspace is missing
|
||||
config_only = db.query(DataConfig).filter(DataConfig.config_id == config_id).first()
|
||||
config_only = db.query(MemoryConfig).filter(MemoryConfig.config_id == config_id).first()
|
||||
if config_only:
|
||||
if config_only.workspace_id is None:
|
||||
config_logger.error(
|
||||
@@ -566,7 +566,7 @@ class DataConfigRepository:
|
||||
"elapsed_ms": elapsed_ms
|
||||
}
|
||||
)
|
||||
db_logger.error(f"Data config {config_id} has no associated workspace ID")
|
||||
db_logger.error(f"Memory config {config_id} has no associated workspace ID")
|
||||
raise ValueError(f"Configuration {config_id} has no associated workspace")
|
||||
else:
|
||||
config_logger.error(
|
||||
@@ -579,7 +579,7 @@ class DataConfigRepository:
|
||||
"elapsed_ms": elapsed_ms
|
||||
}
|
||||
)
|
||||
db_logger.error(f"Data config {config_id} references non-existent workspace {config_only.workspace_id}")
|
||||
db_logger.error(f"Memory config {config_id} references non-existent workspace {config_only.workspace_id}")
|
||||
raise ValueError(f"Workspace {config_only.workspace_id} not found for configuration {config_id}")
|
||||
|
||||
config_logger.debug(
|
||||
@@ -591,7 +591,7 @@ class DataConfigRepository:
|
||||
"elapsed_ms": elapsed_ms
|
||||
}
|
||||
)
|
||||
db_logger.debug(f"Data config not found: config_id={config_id}")
|
||||
db_logger.debug(f"Memory config not found: config_id={config_id}")
|
||||
return None
|
||||
|
||||
config, workspace = result
|
||||
@@ -611,7 +611,7 @@ class DataConfigRepository:
|
||||
}
|
||||
)
|
||||
|
||||
db_logger.debug(f"Data config and workspace query successful: config={config.config_name}, workspace={workspace.name}")
|
||||
db_logger.debug(f"Memory config and workspace query successful: config={config.config_name}, workspace={workspace.name}")
|
||||
return (config, workspace)
|
||||
|
||||
except ValueError:
|
||||
@@ -633,10 +633,10 @@ class DataConfigRepository:
|
||||
exc_info=True
|
||||
)
|
||||
|
||||
db_logger.error(f"Failed to query data config and workspace: config_id={config_id} - {str(e)}")
|
||||
db_logger.error(f"Failed to query memory config and workspace: config_id={config_id} - {str(e)}")
|
||||
raise
|
||||
@staticmethod
|
||||
def get_all(db: Session, workspace_id: Optional[uuid.UUID] = None) -> List[DataConfig]:
|
||||
def get_all(db: Session, workspace_id: Optional[uuid.UUID] = None) -> List[MemoryConfig]:
|
||||
"""获取所有配置参数
|
||||
|
||||
Args:
|
||||
@@ -644,17 +644,17 @@ class DataConfigRepository:
|
||||
workspace_id: 工作空间ID,用于过滤查询结果
|
||||
|
||||
Returns:
|
||||
List[DataConfig]: 配置列表
|
||||
List[MemoryConfig]: 配置列表
|
||||
"""
|
||||
db_logger.debug(f"查询所有配置: workspace_id={workspace_id}")
|
||||
|
||||
try:
|
||||
query = db.query(DataConfig)
|
||||
query = db.query(MemoryConfig)
|
||||
|
||||
if workspace_id:
|
||||
query = query.filter(DataConfig.workspace_id == workspace_id)
|
||||
query = query.filter(MemoryConfig.workspace_id == workspace_id)
|
||||
|
||||
configs = query.order_by(desc(DataConfig.updated_at)).all()
|
||||
configs = query.order_by(desc(MemoryConfig.updated_at)).all()
|
||||
|
||||
db_logger.debug(f"配置列表查询成功: 数量={len(configs)}")
|
||||
return configs
|
||||
@@ -665,7 +665,7 @@ class DataConfigRepository:
|
||||
|
||||
@staticmethod
|
||||
def delete(db: Session, config_id: int) -> bool:
|
||||
"""删除数据配置
|
||||
"""删除记忆配置
|
||||
|
||||
Args:
|
||||
db: 数据库会话
|
||||
@@ -674,22 +674,22 @@ class DataConfigRepository:
|
||||
Returns:
|
||||
bool: 删除成功返回True,配置不存在返回False
|
||||
"""
|
||||
db_logger.debug(f"删除数据配置: config_id={config_id}")
|
||||
db_logger.debug(f"删除记忆配置: config_id={config_id}")
|
||||
|
||||
try:
|
||||
db_config = db.query(DataConfig).filter(DataConfig.config_id == config_id).first()
|
||||
db_config = db.query(MemoryConfig).filter(MemoryConfig.config_id == config_id).first()
|
||||
if not db_config:
|
||||
db_logger.warning(f"数据配置不存在: config_id={config_id}")
|
||||
db_logger.warning(f"记忆配置不存在: config_id={config_id}")
|
||||
return False
|
||||
|
||||
db.delete(db_config)
|
||||
db.commit()
|
||||
|
||||
db_logger.info(f"数据配置删除成功: config_id={config_id}")
|
||||
db_logger.info(f"记忆配置删除成功: config_id={config_id}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
db_logger.error(f"删除数据配置失败: config_id={config_id} - {str(e)}")
|
||||
db_logger.error(f"删除记忆配置失败: config_id={config_id} - {str(e)}")
|
||||
raise
|
||||
|
||||
@@ -299,6 +299,18 @@ class AppRelease(BaseModel):
|
||||
created_at: datetime.datetime
|
||||
updated_at: datetime.datetime
|
||||
|
||||
@field_validator("config", mode="before")
|
||||
@classmethod
|
||||
def parse_config(cls, v):
|
||||
"""处理 config 字段,如果是字符串则解析为字典"""
|
||||
if isinstance(v, str):
|
||||
import json
|
||||
try:
|
||||
return json.loads(v)
|
||||
except json.JSONDecodeError:
|
||||
return {}
|
||||
return v if v is not None else {}
|
||||
|
||||
@field_serializer("created_at", when_used="json")
|
||||
def _serialize_created_at(self, dt: datetime.datetime):
|
||||
return int(dt.timestamp() * 1000) if dt else None
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from pydantic import BaseModel, Field, field_serializer, ConfigDict
|
||||
from pydantic import BaseModel, Field, field_serializer, field_validator, ConfigDict
|
||||
from typing import Optional, List, Dict, Any
|
||||
import datetime
|
||||
import uuid
|
||||
@@ -91,6 +91,18 @@ class ModelApiKey(ModelApiKeyBase):
|
||||
created_at: datetime.datetime
|
||||
updated_at: datetime.datetime
|
||||
|
||||
@field_validator("config", mode="before")
|
||||
@classmethod
|
||||
def parse_config(cls, v):
|
||||
"""处理 config 字段,如果是字符串则解析为字典"""
|
||||
if isinstance(v, str):
|
||||
import json
|
||||
try:
|
||||
return json.loads(v)
|
||||
except json.JSONDecodeError:
|
||||
return {}
|
||||
return v
|
||||
|
||||
@field_serializer("created_at", when_used="json")
|
||||
def _serialize_created_at(self, dt: datetime.datetime):
|
||||
return int(dt.timestamp() * 1000) if dt else None
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import uuid
|
||||
import datetime
|
||||
from typing import Optional, List, Dict, Any
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer
|
||||
from pydantic import BaseModel, Field, ConfigDict, field_serializer, field_validator
|
||||
|
||||
|
||||
# ---------- Input Schemas ----------
|
||||
@@ -88,6 +88,18 @@ class SharedReleaseInfo(BaseModel):
|
||||
# 嵌入配置
|
||||
allow_embed: bool
|
||||
|
||||
@field_validator("config", mode="before")
|
||||
@classmethod
|
||||
def parse_config(cls, v):
|
||||
"""处理 config 字段,如果是字符串则解析为字典"""
|
||||
if isinstance(v, str):
|
||||
import json
|
||||
try:
|
||||
return json.loads(v)
|
||||
except json.JSONDecodeError:
|
||||
return {}
|
||||
return v if v is not None else {}
|
||||
|
||||
|
||||
class EmbedCode(BaseModel):
|
||||
"""嵌入代码"""
|
||||
|
||||
@@ -10,7 +10,7 @@ Classes:
|
||||
from typing import Dict, Any
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.data_config_model import DataConfig
|
||||
from app.models.memory_config_model import MemoryConfig
|
||||
from app.core.logging_config import get_business_logger
|
||||
|
||||
logger = get_business_logger()
|
||||
@@ -61,8 +61,8 @@ class EmotionConfigService:
|
||||
logger.info(f"获取情绪配置: config_id={config_id}")
|
||||
|
||||
# 查询配置
|
||||
config = self.db.query(DataConfig).filter(
|
||||
DataConfig.config_id == config_id
|
||||
config = self.db.query(MemoryConfig).filter(
|
||||
MemoryConfig.config_id == config_id
|
||||
).first()
|
||||
|
||||
if not config:
|
||||
@@ -173,8 +173,8 @@ class EmotionConfigService:
|
||||
self.validate_emotion_config(config_data)
|
||||
|
||||
# 查询配置
|
||||
config = self.db.query(DataConfig).filter(
|
||||
DataConfig.config_id == config_id
|
||||
config = self.db.query(MemoryConfig).filter(
|
||||
MemoryConfig.config_id == config_id
|
||||
).first()
|
||||
|
||||
if not config:
|
||||
|
||||
@@ -14,7 +14,7 @@ from app.core.memory.llm_tools.llm_client import LLMClientException
|
||||
from app.core.memory.models.emotion_models import EmotionExtraction
|
||||
from app.core.memory.utils.llm.llm_utils import MemoryClientFactory
|
||||
from app.db import get_db_context
|
||||
from app.models.data_config_model import DataConfig
|
||||
from app.models.memory_config_model import MemoryConfig
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -60,7 +60,7 @@ class EmotionExtractionService:
|
||||
async def extract_emotion(
|
||||
self,
|
||||
statement: str,
|
||||
config: DataConfig
|
||||
config: MemoryConfig
|
||||
) -> Optional[EmotionExtraction]:
|
||||
"""Extract emotion information from a statement.
|
||||
|
||||
|
||||
@@ -1249,7 +1249,7 @@ def get_end_users_connected_configs_batch(end_user_ids: List[str], db: Session)
|
||||
"""
|
||||
from app.models.app_release_model import AppRelease
|
||||
from app.models.end_user_model import EndUser
|
||||
from app.models.data_config_model import DataConfig
|
||||
from app.models.memory_config_model import MemoryConfig
|
||||
from sqlalchemy import select
|
||||
|
||||
logger.info(f"Batch getting connected configs for {len(end_user_ids)} end_users")
|
||||
|
||||
@@ -14,7 +14,7 @@ from app.core.validators.memory_config_validators import (
|
||||
validate_embedding_model,
|
||||
validate_model_exists_and_active,
|
||||
)
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.schemas.memory_config_schema import (
|
||||
ConfigurationError,
|
||||
InvalidConfigError,
|
||||
@@ -127,7 +127,7 @@ class MemoryConfigService:
|
||||
|
||||
# Step 1: Get config and workspace
|
||||
db_query_start = time.time()
|
||||
result = DataConfigRepository.get_config_with_workspace(self.db, validated_config_id)
|
||||
result = MemoryConfigRepository.get_config_with_workspace(self.db, validated_config_id)
|
||||
db_query_time = time.time() - db_query_start
|
||||
logger.info(f"[PERF] Config+Workspace query: {db_query_time:.4f}s")
|
||||
if not result:
|
||||
|
||||
@@ -23,7 +23,7 @@ from app.core.memory.storage_services.forgetting_engine.config_utils import (
|
||||
load_actr_config_from_db,
|
||||
)
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.repositories.forgetting_cycle_history_repository import ForgettingCycleHistoryRepository
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class MemoryForgetService:
|
||||
|
||||
def __init__(self):
|
||||
"""初始化服务"""
|
||||
self.config_repository = DataConfigRepository()
|
||||
self.config_repository = MemoryConfigRepository()
|
||||
self.history_repository = ForgettingCycleHistoryRepository()
|
||||
|
||||
def _get_neo4j_connector(self) -> Neo4jConnector:
|
||||
|
||||
@@ -13,7 +13,7 @@ from app.db import get_db
|
||||
from app.core.logging_config import get_api_logger
|
||||
from app.core.memory.storage_services.reflection_engine import ReflectionConfig, ReflectionEngine
|
||||
from app.core.memory.storage_services.reflection_engine.self_reflexion import ReflectionRange, ReflectionBaseline
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.models.app_model import App
|
||||
from app.models.app_release_model import AppRelease
|
||||
@@ -70,7 +70,7 @@ class WorkspaceAppService:
|
||||
"created_at": app.created_at.isoformat() if app.created_at else None,
|
||||
"updated_at": app.updated_at.isoformat() if app.updated_at else None,
|
||||
"releases": [],
|
||||
"data_configs": [],
|
||||
"memory_configs": [],
|
||||
"end_users": []
|
||||
}
|
||||
|
||||
@@ -98,11 +98,11 @@ class WorkspaceAppService:
|
||||
|
||||
if memory_content:
|
||||
processed_configs.add(memory_content)
|
||||
data_config_info = self._get_data_config(memory_content)
|
||||
memory_config_info = self._get_memory_config(memory_content)
|
||||
|
||||
if data_config_info:
|
||||
if not any(dc["config_id"] == data_config_info["config_id"] for dc in app_info["data_configs"]):
|
||||
app_info["data_configs"].append(data_config_info)
|
||||
if memory_config_info:
|
||||
if not any(dc["config_id"] == memory_config_info["config_id"] for dc in app_info["memory_configs"]):
|
||||
app_info["memory_configs"].append(memory_config_info)
|
||||
|
||||
app_info["releases"].append(release_info)
|
||||
|
||||
@@ -117,30 +117,30 @@ class WorkspaceAppService:
|
||||
|
||||
return None
|
||||
|
||||
def _get_data_config(self, memory_content: str) -> Dict[str, Any]:
|
||||
"""Retrieve data_comfig information based on memory_comtent"""
|
||||
def _get_memory_config(self, memory_content: str) -> Dict[str, Any]:
|
||||
"""Retrieve memory_config information based on memory_content"""
|
||||
try:
|
||||
data_config_result = DataConfigRepository.query_reflection_config_by_id(self.db, int(memory_content))
|
||||
memory_config_result = MemoryConfigRepository.query_reflection_config_by_id(self.db, int(memory_content))
|
||||
|
||||
# data_config_query, data_config_params = DataConfigRepository.build_select_reflection(memory_content)
|
||||
# data_config_result = self.db.execute(text(data_config_query), data_config_params).fetchone()
|
||||
# if data_config_result is None:
|
||||
# memory_config_query, memory_config_params = MemoryConfigRepository.build_select_reflection(memory_content)
|
||||
# memory_config_result = self.db.execute(text(memory_config_query), memory_config_params).fetchone()
|
||||
# if memory_config_result is None:
|
||||
# return None
|
||||
|
||||
if data_config_result:
|
||||
if memory_config_result:
|
||||
return {
|
||||
"config_id": data_config_result.config_id,
|
||||
"enable_self_reflexion": data_config_result.enable_self_reflexion,
|
||||
"iteration_period": data_config_result.iteration_period,
|
||||
"reflexion_range": data_config_result.reflexion_range,
|
||||
"baseline": data_config_result.baseline,
|
||||
"reflection_model_id": data_config_result.reflection_model_id,
|
||||
"memory_verify": data_config_result.memory_verify,
|
||||
"quality_assessment": data_config_result.quality_assessment,
|
||||
"user_id": data_config_result.user_id
|
||||
"config_id": memory_config_result.config_id,
|
||||
"enable_self_reflexion": memory_config_result.enable_self_reflexion,
|
||||
"iteration_period": memory_config_result.iteration_period,
|
||||
"reflexion_range": memory_config_result.reflexion_range,
|
||||
"baseline": memory_config_result.baseline,
|
||||
"reflection_model_id": memory_config_result.reflection_model_id,
|
||||
"memory_verify": memory_config_result.memory_verify,
|
||||
"quality_assessment": memory_config_result.quality_assessment,
|
||||
"user_id": memory_config_result.user_id
|
||||
}
|
||||
except Exception as e:
|
||||
api_logger.warning(f"查询data_config失败,memory_content: {memory_content}, 错误: {str(e)}")
|
||||
api_logger.warning(f"查询memory_config失败,memory_content: {memory_content}, 错误: {str(e)}")
|
||||
|
||||
return None
|
||||
|
||||
@@ -223,7 +223,7 @@ class MemoryReflectionService:
|
||||
}
|
||||
|
||||
config_data_id = config_data['config_id']
|
||||
reflection_config = WorkspaceAppService(self.db)._get_data_config(config_data_id)
|
||||
reflection_config = WorkspaceAppService(self.db)._get_memory_config(config_data_id)
|
||||
if reflection_config is not None and reflection_config['enable_self_reflexion']:
|
||||
reflection_config = self._create_reflection_config_from_data(reflection_config)
|
||||
# 3. 执行反思引擎
|
||||
@@ -277,7 +277,7 @@ class MemoryReflectionService:
|
||||
|
||||
|
||||
config_data_id=config_data['config_id']
|
||||
reflection_config=WorkspaceAppService(self.db)._get_data_config(config_data_id)
|
||||
reflection_config=WorkspaceAppService(self.db)._get_memory_config(config_data_id)
|
||||
if reflection_config is not None and reflection_config['enable_self_reflexion']:
|
||||
reflection_config= self._create_reflection_config_from_data(reflection_config)
|
||||
iteration_period = int(reflection_config.iteration_period)
|
||||
|
||||
@@ -15,7 +15,7 @@ from app.core.logging_config import get_config_logger, get_logger
|
||||
from app.core.memory.analytics.hot_memory_tags import get_hot_memory_tags
|
||||
from app.core.memory.analytics.recent_activity_stats import get_recent_activity_stats
|
||||
from app.models.user_model import User
|
||||
from app.repositories.data_config_repository import DataConfigRepository
|
||||
from app.repositories.memory_config_repository import MemoryConfigRepository
|
||||
from app.repositories.neo4j.neo4j_connector import Neo4jConnector
|
||||
from app.schemas.memory_config_schema import ConfigurationError
|
||||
from app.schemas.memory_storage_schema import (
|
||||
@@ -125,7 +125,7 @@ class DataConfigService: # 数据配置服务类(PostgreSQL)
|
||||
if not params.rerank_id:
|
||||
params.rerank_id = configs.get('rerank')
|
||||
|
||||
config = DataConfigRepository.create(self.db, params)
|
||||
config = MemoryConfigRepository.create(self.db, params)
|
||||
self.db.commit()
|
||||
return {"affected": 1, "config_id": config.config_id}
|
||||
|
||||
@@ -142,20 +142,20 @@ class DataConfigService: # 数据配置服务类(PostgreSQL)
|
||||
|
||||
# --- Delete ---
|
||||
def delete(self, key: ConfigParamsDelete) -> Dict[str, Any]: # 删除配置参数(按配置ID)
|
||||
success = DataConfigRepository.delete(self.db, key.config_id)
|
||||
success = MemoryConfigRepository.delete(self.db, key.config_id)
|
||||
if not success:
|
||||
raise ValueError("未找到配置")
|
||||
return {"affected": 1}
|
||||
|
||||
# --- Update ---
|
||||
def update(self, update: ConfigUpdate) -> Dict[str, Any]: # 部分更新配置参数
|
||||
config = DataConfigRepository.update(self.db, update)
|
||||
config = MemoryConfigRepository.update(self.db, update)
|
||||
if not config:
|
||||
raise ValueError("未找到配置")
|
||||
return {"affected": 1}
|
||||
|
||||
def update_extracted(self, update: ConfigUpdateExtracted) -> Dict[str, Any]: # 更新记忆萃取引擎配置参数
|
||||
config = DataConfigRepository.update_extracted(self.db, update)
|
||||
config = MemoryConfigRepository.update_extracted(self.db, update)
|
||||
if not config:
|
||||
raise ValueError("未找到配置")
|
||||
return {"affected": 1}
|
||||
@@ -166,14 +166,14 @@ class DataConfigService: # 数据配置服务类(PostgreSQL)
|
||||
|
||||
# --- Read ---
|
||||
def get_extracted(self, key: ConfigKey) -> Dict[str, Any]: # 获取萃取配置参数
|
||||
result = DataConfigRepository.get_extracted_config(self.db, key.config_id)
|
||||
result = MemoryConfigRepository.get_extracted_config(self.db, key.config_id)
|
||||
if not result:
|
||||
raise ValueError("未找到配置")
|
||||
return result
|
||||
|
||||
# --- Read All ---
|
||||
def get_all(self, workspace_id = None) -> List[Dict[str, Any]]: # 获取所有配置参数
|
||||
configs = DataConfigRepository.get_all(self.db, workspace_id)
|
||||
configs = MemoryConfigRepository.get_all(self.db, workspace_id)
|
||||
|
||||
# 将 ORM 对象转换为字典列表
|
||||
data_list = []
|
||||
@@ -390,7 +390,7 @@ _neo4j_connector = Neo4jConnector()
|
||||
|
||||
async def search_dialogue(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_DIALOGUE,
|
||||
MemoryConfigRepository.SEARCH_FOR_DIALOGUE,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
data = {"search_for": "dialogue", "num": result[0]["num"]}
|
||||
@@ -399,7 +399,7 @@ async def search_dialogue(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
|
||||
async def search_chunk(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_CHUNK,
|
||||
MemoryConfigRepository.SEARCH_FOR_CHUNK,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
data = {"search_for": "chunk", "num": result[0]["num"]}
|
||||
@@ -408,7 +408,7 @@ async def search_chunk(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
|
||||
async def search_statement(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_STATEMENT,
|
||||
MemoryConfigRepository.SEARCH_FOR_STATEMENT,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
data = {"search_for": "statement", "num": result[0]["num"]}
|
||||
@@ -417,7 +417,7 @@ async def search_statement(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
|
||||
async def search_entity(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_ENTITY,
|
||||
MemoryConfigRepository.SEARCH_FOR_ENTITY,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
data = {"search_for": "entity", "num": result[0]["num"]}
|
||||
@@ -426,7 +426,7 @@ async def search_entity(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
|
||||
async def search_all(end_user_id: Optional[str] = None) -> Dict[str, Any]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_ALL,
|
||||
MemoryConfigRepository.SEARCH_FOR_ALL,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
|
||||
@@ -461,7 +461,7 @@ async def kb_type_distribution(end_user_id: Optional[str] = None) -> Dict[str, A
|
||||
聚合 dialogue/chunk/statement/entity 四类计数,返回统一的分布结构,便于前端一次性消费。
|
||||
"""
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_ALL,
|
||||
MemoryConfigRepository.SEARCH_FOR_ALL,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
|
||||
@@ -492,7 +492,7 @@ async def kb_type_distribution(end_user_id: Optional[str] = None) -> Dict[str, A
|
||||
|
||||
async def search_detials(end_user_id: Optional[str] = None) -> List[Dict[str, Any]]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_DETIALS,
|
||||
MemoryConfigRepository.SEARCH_FOR_DETIALS,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
return result
|
||||
@@ -500,7 +500,7 @@ async def search_detials(end_user_id: Optional[str] = None) -> List[Dict[str, An
|
||||
|
||||
async def search_edges(end_user_id: Optional[str] = None) -> List[Dict[str, Any]]:
|
||||
result = await _neo4j_connector.execute_query(
|
||||
DataConfigRepository.SEARCH_FOR_EDGES,
|
||||
MemoryConfigRepository.SEARCH_FOR_EDGES,
|
||||
end_user_id=end_user_id,
|
||||
)
|
||||
return result
|
||||
|
||||
@@ -83,6 +83,13 @@ class AgentConfigProxy:
|
||||
|
||||
def agent_config_4_app_release(release: AppRelease) -> AgentConfig:
|
||||
config_dict = release.config
|
||||
# 如果 config 是字符串,解析为字典
|
||||
if isinstance(config_dict, str):
|
||||
import json
|
||||
try:
|
||||
config_dict = json.loads(config_dict)
|
||||
except json.JSONDecodeError:
|
||||
config_dict = {}
|
||||
|
||||
agent_config = AgentConfig(
|
||||
app_id=release.app_id,
|
||||
@@ -100,6 +107,14 @@ def agent_config_4_app_release(release: AppRelease) -> AgentConfig:
|
||||
|
||||
def multi_agent_config_4_app_release(release: AppRelease) -> MultiAgentConfig:
|
||||
config_dict = release.config
|
||||
|
||||
# 如果 config 是字符串,解析为字典
|
||||
if isinstance(config_dict, str):
|
||||
import json
|
||||
try:
|
||||
config_dict = json.loads(config_dict)
|
||||
except json.JSONDecodeError:
|
||||
config_dict = {}
|
||||
|
||||
agent_config = MultiAgentConfig(
|
||||
app_id=release.app_id,
|
||||
@@ -120,6 +135,14 @@ def multi_agent_config_4_app_release(release: AppRelease) -> MultiAgentConfig:
|
||||
|
||||
def workflow_config_4_app_release(release: AppRelease) -> WorkflowConfig:
|
||||
config_dict = release.config
|
||||
|
||||
# 如果 config 是字符串,解析为字典
|
||||
if isinstance(config_dict, str):
|
||||
import json
|
||||
try:
|
||||
config_dict = json.loads(config_dict)
|
||||
except json.JSONDecodeError:
|
||||
config_dict = {}
|
||||
|
||||
config = WorkflowConfig(
|
||||
id=config_dict.get("id"),
|
||||
|
||||
Reference in New Issue
Block a user