[fix] Pydantic save json error
This commit is contained in:
25
api/app/base/type.py
Normal file
25
api/app/base/type.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from sqlalchemy import TypeDecorator, JSON
|
||||||
|
|
||||||
|
|
||||||
|
class PydanticType(TypeDecorator):
|
||||||
|
impl = JSON
|
||||||
|
|
||||||
|
def __init__(self, pydantic_model: type[BaseModel]):
|
||||||
|
super().__init__()
|
||||||
|
self.model = pydantic_model
|
||||||
|
|
||||||
|
def process_bind_param(self, value, dialect):
|
||||||
|
# 入库:Model -> dict
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if isinstance(value, self.model):
|
||||||
|
return value.dict()
|
||||||
|
return value # 已经是 dict 也放行
|
||||||
|
|
||||||
|
def process_result_value(self, value, dialect):
|
||||||
|
# 出库:dict -> Model
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
# return self.model.parse_obj(value) # pydantic v1
|
||||||
|
return self.model.model_validate(value) # pydantic v2
|
||||||
@@ -3,8 +3,9 @@ import uuid
|
|||||||
from sqlalchemy import Column, String, Boolean, DateTime, Text, ForeignKey
|
from sqlalchemy import Column, String, Boolean, DateTime, Text, ForeignKey
|
||||||
from sqlalchemy.dialects.postgresql import UUID, JSON
|
from sqlalchemy.dialects.postgresql import UUID, JSON
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from app.base.type import PydanticType
|
||||||
from app.db import Base
|
from app.db import Base
|
||||||
from app.models.multi_agent_model import PydanticType
|
|
||||||
from app.schemas import ModelParameters
|
from app.schemas import ModelParameters
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from sqlalchemy import Column, String, Boolean, DateTime, Integer, Float, Text,
|
|||||||
from sqlalchemy.dialects.postgresql import UUID, JSON
|
from sqlalchemy.dialects.postgresql import UUID, JSON
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
|
from app.base.type import PydanticType
|
||||||
from app.db import Base
|
from app.db import Base
|
||||||
from app.schemas import ModelParameters
|
from app.schemas import ModelParameters
|
||||||
|
|
||||||
@@ -23,27 +24,27 @@ class AggregationStrategy(StrEnum):
|
|||||||
VOTE = "vote"
|
VOTE = "vote"
|
||||||
PRIORITY = "priority"
|
PRIORITY = "priority"
|
||||||
|
|
||||||
class PydanticType(TypeDecorator):
|
# class PydanticType(TypeDecorator):
|
||||||
impl = JSON
|
# impl = JSON
|
||||||
|
|
||||||
def __init__(self, pydantic_model: type[BaseModel]):
|
# def __init__(self, pydantic_model: type[BaseModel]):
|
||||||
super().__init__()
|
# super().__init__()
|
||||||
self.model = pydantic_model
|
# self.model = pydantic_model
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
# def process_bind_param(self, value, dialect):
|
||||||
# 入库:Model -> dict
|
# # 入库:Model -> dict
|
||||||
if value is None:
|
# if value is None:
|
||||||
return None
|
# return None
|
||||||
if isinstance(value, self.model):
|
# if isinstance(value, self.model):
|
||||||
return value.dict()
|
# return value.dict()
|
||||||
return value # 已经是 dict 也放行
|
# return value # 已经是 dict 也放行
|
||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
# def process_result_value(self, value, dialect):
|
||||||
# 出库:dict -> Model
|
# # 出库:dict -> Model
|
||||||
if value is None:
|
# if value is None:
|
||||||
return None
|
# return None
|
||||||
# return self.model.parse_obj(value) # pydantic v1
|
# # return self.model.parse_obj(value) # pydantic v1
|
||||||
return self.model.model_validate(value) # pydantic v2
|
# return self.model.model_validate(value) # pydantic v2
|
||||||
|
|
||||||
class MultiAgentConfig(Base):
|
class MultiAgentConfig(Base):
|
||||||
"""多 Agent 配置表"""
|
"""多 Agent 配置表"""
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ from app.services.agent_config_converter import AgentConfigConverter
|
|||||||
from app.models import AppShare, Workspace
|
from app.models import AppShare, Workspace
|
||||||
from app.services.model_service import ModelApiKeyService
|
from app.services.model_service import ModelApiKeyService
|
||||||
from app.services.workflow_service import WorkflowService
|
from app.services.workflow_service import WorkflowService
|
||||||
|
from app.utils.app_config_utils import model_parameters_to_dict
|
||||||
|
|
||||||
# 获取业务日志器
|
# 获取业务日志器
|
||||||
logger = get_business_logger()
|
logger = get_business_logger()
|
||||||
@@ -1175,7 +1176,7 @@ class AppService:
|
|||||||
|
|
||||||
config = {
|
config = {
|
||||||
"system_prompt": agent_cfg.system_prompt,
|
"system_prompt": agent_cfg.system_prompt,
|
||||||
"model_parameters": agent_cfg.model_parameters,
|
"model_parameters": model_parameters_to_dict(agent_cfg.model_parameters),
|
||||||
"knowledge_retrieval": agent_cfg.knowledge_retrieval,
|
"knowledge_retrieval": agent_cfg.knowledge_retrieval,
|
||||||
"memory": agent_cfg.memory,
|
"memory": agent_cfg.memory,
|
||||||
"variables": agent_cfg.variables or [],
|
"variables": agent_cfg.variables or [],
|
||||||
@@ -1204,8 +1205,10 @@ class AppService:
|
|||||||
default_model_config_id = multi_agent_cfg.default_model_config_id
|
default_model_config_id = multi_agent_cfg.default_model_config_id
|
||||||
|
|
||||||
# 4. 构建配置快照
|
# 4. 构建配置快照
|
||||||
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
"model_parameters":multi_agent_cfg.model_parameters,
|
"model_parameters": model_parameters_to_dict(multi_agent_cfg.model_parameters),
|
||||||
"master_agent_id": str(multi_agent_cfg.master_agent_id),
|
"master_agent_id": str(multi_agent_cfg.master_agent_id),
|
||||||
"orchestration_mode": multi_agent_cfg.orchestration_mode,
|
"orchestration_mode": multi_agent_cfg.orchestration_mode,
|
||||||
"sub_agents": multi_agent_cfg.sub_agents,
|
"sub_agents": multi_agent_cfg.sub_agents,
|
||||||
|
|||||||
@@ -5,13 +5,66 @@ Utility functions for converting between dict and model objects for different ap
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import uuid
|
import uuid
|
||||||
from typing import Dict, Any, Optional
|
from typing import Dict, Any, Optional, Union
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from app.models import AppRelease, WorkflowConfig
|
from app.models import AppRelease, WorkflowConfig
|
||||||
from app.models.agent_app_config_model import AgentConfig
|
from app.models.agent_app_config_model import AgentConfig
|
||||||
from app.models.multi_agent_model import MultiAgentConfig
|
from app.models.multi_agent_model import MultiAgentConfig
|
||||||
|
|
||||||
|
|
||||||
|
def model_parameters_to_dict(model_parameters: Any) -> Optional[Dict[str, Any]]:
|
||||||
|
"""将 ModelParameters 对象转换为字典
|
||||||
|
|
||||||
|
Args:
|
||||||
|
model_parameters: ModelParameters 对象、字典或 None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
字典格式的模型参数,如果输入为 None 则返回 None
|
||||||
|
"""
|
||||||
|
if model_parameters is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if isinstance(model_parameters, dict):
|
||||||
|
return model_parameters
|
||||||
|
|
||||||
|
# Pydantic v2
|
||||||
|
if hasattr(model_parameters, 'model_dump'):
|
||||||
|
return model_parameters.model_dump()
|
||||||
|
|
||||||
|
# Pydantic v1
|
||||||
|
if hasattr(model_parameters, 'dict'):
|
||||||
|
return model_parameters.dict()
|
||||||
|
|
||||||
|
# 其他情况尝试转换
|
||||||
|
try:
|
||||||
|
return dict(model_parameters)
|
||||||
|
except (TypeError, ValueError):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def dict_to_model_parameters(data: Optional[Dict[str, Any]]) -> Optional[Any]:
|
||||||
|
"""将字典转换为 ModelParameters 对象
|
||||||
|
|
||||||
|
Args:
|
||||||
|
data: 字典格式的模型参数或 None
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ModelParameters 对象,如果输入为 None 则返回 None
|
||||||
|
"""
|
||||||
|
if data is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
from app.schemas import ModelParameters
|
||||||
|
|
||||||
|
if isinstance(data, ModelParameters):
|
||||||
|
return data
|
||||||
|
|
||||||
|
if isinstance(data, dict):
|
||||||
|
return ModelParameters(**data)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
class AgentConfigProxy:
|
class AgentConfigProxy:
|
||||||
"""Proxy class for AgentConfig (legacy compatibility)"""
|
"""Proxy class for AgentConfig (legacy compatibility)"""
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user