Merge branch 'develop' into refactor/memory_search
# Conflicts: # api/app/core/memory/storage_services/search/__init__.py
This commit is contained in:
@@ -5,16 +5,9 @@ Implicit Emotions Storage Repository
|
||||
事务由调用方控制,仓储层只使用 flush/refresh
|
||||
"""
|
||||
import logging
|
||||
from datetime import date, datetime, timezone
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from typing import Generator, Optional
|
||||
|
||||
|
||||
class TimeFilterUnavailableError(Exception):
|
||||
"""redis_client 不可用,无法执行时间轴筛选。
|
||||
|
||||
调用方捕获此异常后可选择回退到 get_all_user_ids 进行全量处理。
|
||||
"""
|
||||
|
||||
import redis
|
||||
from sqlalchemy import exists, not_, select
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -25,6 +18,13 @@ from app.models.implicit_emotions_storage_model import ImplicitEmotionsStorage
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TimeFilterUnavailableError(Exception):
|
||||
"""redis_client 不可用,无法执行时间轴筛选。
|
||||
|
||||
调用方捕获此异常后可选择回退到 get_all_user_ids 进行全量处理。
|
||||
"""
|
||||
|
||||
|
||||
class ImplicitEmotionsStorageRepository:
|
||||
"""隐性记忆和情绪存储仓储类"""
|
||||
|
||||
@@ -216,9 +216,7 @@ class ImplicitEmotionsStorageRepository:
|
||||
"""
|
||||
from sqlalchemy import String as SAString
|
||||
from sqlalchemy import cast
|
||||
CST = timezone(timedelta(hours=8))
|
||||
now_cst = datetime.now(CST)
|
||||
today_start = now_cst.replace(hour=0, minute=0, second=0, microsecond=0).astimezone(timezone.utc).replace(tzinfo=None)
|
||||
today_start = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
tomorrow_start = today_start + timedelta(days=1)
|
||||
offset = 0
|
||||
while True:
|
||||
|
||||
@@ -328,7 +328,7 @@ class MemoryConfigRepository:
|
||||
if not db_config:
|
||||
db_logger.warning(f"记忆配置不存在: config_id={update.config_id}")
|
||||
return None
|
||||
|
||||
#TODO:部分更新没有用patch请求,是在Repository层中用先查再部分更新的方式实现的,后续可以考虑改成patch请求更符合RESTful设计原则
|
||||
update_data = update.model_dump(exclude_unset=True)
|
||||
update_data.pop("config_id", None)
|
||||
|
||||
|
||||
@@ -263,16 +263,15 @@ class ModelConfigRepository:
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
def get_by_type(db: Session, model_type: ModelType, tenant_id: uuid.UUID | None = None, is_active: bool = True) -> List[ModelConfig]:
|
||||
"""根据类型获取模型配置"""
|
||||
db_logger.debug(f"根据类型查询模型配置: type={model_type}, tenant_id={tenant_id}, is_active={is_active}")
|
||||
|
||||
def get_by_type(db: Session, model_types: List[ModelType], tenant_id: uuid.UUID | None = None, is_active: bool = True) -> List[ModelConfig]:
|
||||
"""根据类型获取模型配置,支持多类型查询"""
|
||||
db_logger.debug(f"根据类型查询模型配置: types={[t.value for t in model_types]}, tenant_id={tenant_id}, is_active={is_active}")
|
||||
|
||||
try:
|
||||
query = db.query(ModelConfig).options(
|
||||
joinedload(ModelConfig.api_keys)
|
||||
).filter(ModelConfig.type == model_type)
|
||||
|
||||
# 添加租户过滤
|
||||
).filter(ModelConfig.type.in_([t.value for t in model_types]))
|
||||
|
||||
if tenant_id:
|
||||
query = query.filter(
|
||||
or_(
|
||||
@@ -280,16 +279,18 @@ class ModelConfigRepository:
|
||||
ModelConfig.is_public
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
if is_active:
|
||||
query = query.filter(ModelConfig.is_active)
|
||||
|
||||
models = query.order_by(ModelConfig.name).all()
|
||||
|
||||
query = query.filter(ModelConfig.is_composite == False)
|
||||
|
||||
models = query.order_by(ModelConfig.created_at.desc()).all()
|
||||
db_logger.debug(f"根据类型查询模型配置成功: 数量={len(models)}")
|
||||
return models
|
||||
|
||||
|
||||
except Exception as e:
|
||||
db_logger.error(f"根据类型查询模型配置失败: type={model_type} - {str(e)}")
|
||||
db_logger.error(f"根据类型查询模型配置失败: types={model_types} - {str(e)}")
|
||||
raise
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -94,6 +94,8 @@ SET e.name = CASE WHEN entity.name IS NOT NULL AND entity.name <> '' THEN entity
|
||||
END,
|
||||
e.statement_id = CASE WHEN entity.statement_id IS NOT NULL AND entity.statement_id <> '' THEN entity.statement_id ELSE e.statement_id END,
|
||||
e.aliases = CASE
|
||||
// 用户实体的 aliases 由 PgSQL end_user_info 作为唯一权威源,知识抽取完全不写入
|
||||
WHEN entity.name IN ['用户', '我', 'User', 'I'] THEN e.aliases
|
||||
WHEN entity.aliases IS NOT NULL AND size(entity.aliases) > 0
|
||||
THEN CASE
|
||||
WHEN e.aliases IS NULL THEN entity.aliases
|
||||
|
||||
@@ -297,6 +297,10 @@ def get_user_by_id(db: Session, user_id: uuid.UUID) -> Optional[User]:
|
||||
"""根据ID获取用户"""
|
||||
return UserRepository(db).get_user_by_id(user_id)
|
||||
|
||||
def get_user_by_id_regardless_active(db: Session, user_id: uuid.UUID) -> Optional[User]:
|
||||
"""根据ID获取用户(不过滤 is_active,用于启用/禁用场景)"""
|
||||
return db.query(User).filter(User.id == user_id).first()
|
||||
|
||||
def get_user_by_email(db: Session, email: str) -> Optional[User]:
|
||||
"""根据邮箱获取用户"""
|
||||
return UserRepository(db).get_user_by_email(email)
|
||||
|
||||
Reference in New Issue
Block a user