diff --git a/api/app/base/type.py b/api/app/base/type.py new file mode 100644 index 00000000..fecbe13a --- /dev/null +++ b/api/app/base/type.py @@ -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 diff --git a/api/app/models/agent_app_config_model.py b/api/app/models/agent_app_config_model.py index a4645791..0a7a5935 100644 --- a/api/app/models/agent_app_config_model.py +++ b/api/app/models/agent_app_config_model.py @@ -3,8 +3,9 @@ import uuid from sqlalchemy import Column, String, Boolean, DateTime, Text, ForeignKey from sqlalchemy.dialects.postgresql import UUID, JSON from sqlalchemy.orm import relationship + +from app.base.type import PydanticType from app.db import Base -from app.models.multi_agent_model import PydanticType from app.schemas import ModelParameters diff --git a/api/app/models/multi_agent_model.py b/api/app/models/multi_agent_model.py index 07134d27..544ddb27 100644 --- a/api/app/models/multi_agent_model.py +++ b/api/app/models/multi_agent_model.py @@ -8,6 +8,7 @@ from sqlalchemy import Column, String, Boolean, DateTime, Integer, Float, Text, from sqlalchemy.dialects.postgresql import UUID, JSON from sqlalchemy.orm import relationship +from app.base.type import PydanticType from app.db import Base from app.schemas import ModelParameters @@ -23,27 +24,27 @@ class AggregationStrategy(StrEnum): VOTE = "vote" PRIORITY = "priority" -class PydanticType(TypeDecorator): - impl = JSON +# class PydanticType(TypeDecorator): +# impl = JSON - def __init__(self, pydantic_model: type[BaseModel]): - super().__init__() - self.model = pydantic_model +# 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_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 +# 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 class MultiAgentConfig(Base): """多 Agent 配置表""" diff --git a/api/app/services/app_service.py b/api/app/services/app_service.py index 7a4e46fb..b97bf874 100644 --- a/api/app/services/app_service.py +++ b/api/app/services/app_service.py @@ -33,6 +33,7 @@ from app.services.agent_config_converter import AgentConfigConverter from app.models import AppShare, Workspace from app.services.model_service import ModelApiKeyService from app.services.workflow_service import WorkflowService +from app.utils.app_config_utils import model_parameters_to_dict # 获取业务日志器 logger = get_business_logger() @@ -1175,7 +1176,7 @@ class AppService: config = { "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, "memory": agent_cfg.memory, "variables": agent_cfg.variables or [], @@ -1204,8 +1205,10 @@ class AppService: default_model_config_id = multi_agent_cfg.default_model_config_id # 4. 构建配置快照 + + 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), "orchestration_mode": multi_agent_cfg.orchestration_mode, "sub_agents": multi_agent_cfg.sub_agents, diff --git a/api/app/utils/app_config_utils.py b/api/app/utils/app_config_utils.py index 97e64214..834d22af 100644 --- a/api/app/utils/app_config_utils.py +++ b/api/app/utils/app_config_utils.py @@ -5,13 +5,66 @@ Utility functions for converting between dict and model objects for different ap """ import uuid -from typing import Dict, Any, Optional +from typing import Dict, Any, Optional, Union from datetime import datetime from app.models import AppRelease, WorkflowConfig from app.models.agent_app_config_model import AgentConfig 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: """Proxy class for AgentConfig (legacy compatibility)"""