diff --git a/api/app/controllers/service/app_api_controller.py b/api/app/controllers/service/app_api_controller.py index d621caf9..eb22548f 100644 --- a/api/app/controllers/service/app_api_controller.py +++ b/api/app/controllers/service/app_api_controller.py @@ -11,6 +11,7 @@ from app.db import get_db from app.core.response_utils import success from app.core.logging_config import get_business_logger from app.dependencies import get_app_or_workspace +from app.models import AppRelease from app.repositories import knowledge_repository from app.schemas import AppChatRequest, conversation_schema from app.models.app_model import App @@ -23,7 +24,7 @@ from app.services.app_chat_service import AppChatService, get_app_chat_service from app.services.app_service import AppService from app.services.conversation_service import ConversationService, get_conversation_service from app.services.workflow_service import WorkflowService, get_workflow_service -from app.utils.app_config_utils import dict_to_multi_agent_config,dict_to_agent_config,dict_to_workflow_config +from app.utils.app_config_utils import dict_to_multi_agent_config,dict_to_workflow_config,agent_config_4_app_release router = APIRouter(prefix="/app", tags=["V1 - App API"]) logger = get_business_logger() @@ -93,7 +94,8 @@ async def chat( original_user_id=other_id # Save original user_id to other_id ) end_user_id = str(new_end_user.id) - + web_search=True + memory=True # 提前验证和准备(在流式响应开始前完成) storage_type = workspace_service.get_workspace_storage_type_without_auth( db=db, @@ -131,7 +133,11 @@ async def chat( ) if app_type == AppType.AGENT: - agent_config = dict_to_agent_config(app.current_release.config) + + print("="*50) + print(app.current_release.default_model_config_id) + agent_config = agent_config_4_app_release(app.current_release) + print(agent_config.default_model_config_id) # 流式返回 if payload.stream: async def event_generator(): @@ -140,9 +146,9 @@ async def chat( conversation_id=conversation.id, # 使用已创建的会话 ID user_id= end_user_id, # 转换为字符串 variables=payload.variables, - web_search=payload.web_search, - config=app.current_release.config, - memory=payload.memory, + web_search=web_search, + config=agent_config, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ): @@ -165,15 +171,15 @@ async def chat( user_id=end_user_id, # 转换为字符串 variables=payload.variables, config= agent_config, - web_search=payload.web_search, - memory=payload.memory, + web_search=web_search, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ) return success(data=conversation_schema.ChatResponse(**result)) elif app_type == AppType.MULTI_AGENT: # 多 Agent 流式返回 - config = dict_to_multi_agent_config(app.current_release.config) + config = dict_to_multi_agent_config(app.current_release.config,app.id) if payload.stream: async def event_generator(): async for event in app_chat_service.multi_agent_chat_stream( @@ -183,8 +189,8 @@ async def chat( user_id=end_user_id, # 转换为字符串 variables=payload.variables, config=config, - web_search=payload.web_search, - memory=payload.memory, + web_search=web_search, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ): @@ -208,8 +214,8 @@ async def chat( user_id=end_user_id, # 转换为字符串 variables=payload.variables, config=config, - web_search=payload.web_search, - memory=payload.memory, + web_search=web_search, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ) @@ -217,7 +223,7 @@ async def chat( return success(data=conversation_schema.ChatResponse(**result)) elif app_type == AppType.WORKFLOW: # 多 Agent 流式返回 - config = dict_to_workflow_config(app.current_release.config) + config = dict_to_workflow_config(app.current_release.config,app.id) if payload.stream: async def event_generator(): async for event in app_chat_service.workflow_chat_stream( @@ -227,8 +233,8 @@ async def chat( user_id=end_user_id, # 转换为字符串 variables=payload.variables, config=config, - web_search=payload.web_search, - memory=payload.memory, + web_search=web_search, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ): @@ -252,8 +258,8 @@ async def chat( user_id=end_user_id, # 转换为字符串 variables=payload.variables, config=config, - web_search=payload.web_search, - memory=payload.memory, + web_search=web_search, + memory=memory, storage_type=storage_type, user_rag_memory_id=user_rag_memory_id ) diff --git a/api/app/services/app_chat_service.py b/api/app/services/app_chat_service.py index be593068..efcf318d 100644 --- a/api/app/services/app_chat_service.py +++ b/api/app/services/app_chat_service.py @@ -51,9 +51,9 @@ class AppChatService: # 获取模型配置ID model_config_id = config.default_model_config_id - api_key_obj = ModelApiKeyService.get_a_api_key(model_config_id) + api_key_obj = ModelApiKeyService.get_a_api_key(self.db ,model_config_id) # 处理系统提示词(支持变量替换) - system_prompt = config.get("system_prompt", "") + system_prompt = config.system_prompt if variables: system_prompt_rendered = render_prompt_message( system_prompt, @@ -66,7 +66,7 @@ class AppChatService: tools = [] # 添加知识库检索工具 - knowledge_retrieval = config.get("knowledge_retrieval") + knowledge_retrieval = config.knowledge_retrieval if knowledge_retrieval: knowledge_bases = knowledge_retrieval.get("knowledge_bases", []) kb_ids = [kb.get("kb_id") for kb in knowledge_bases if kb.get("kb_id")] @@ -77,29 +77,29 @@ class AppChatService: # 添加长期记忆工具 memory_flag = False if memory == True: - memory_config = config.get("memory", {}) + memory_config = config.memory if memory_config.get("enabled") and user_id: memory_flag = True memory_tool = create_long_term_memory_tool(memory_config, user_id) tools.append(memory_tool) - web_tools = config.get("tools") - web_search_choice = web_tools.get("web_search", {}) - web_search_enable = web_search_choice.get("enabled", False) - if web_search == True: - if web_search_enable == True: - search_tool = create_web_search_tool({}) - tools.append(search_tool) - - logger.debug( - "已添加网络搜索工具", - extra={ - "tool_count": len(tools) - } - ) + web_tools = config.tools + # web_search_choice = web_tools.get("web_search", {}) + # web_search_enable = web_search_choice.get("enabled", False) + # if web_search == True: + # if web_search_enable == True: + # search_tool = create_web_search_tool({}) + # tools.append(search_tool) + # + # logger.debug( + # "已添加网络搜索工具", + # extra={ + # "tool_count": len(tools) + # } + # ) # 获取模型参数 - model_parameters = config.get("model_parameters", {}) + model_parameters = config.model_parameters # 创建 LangChain Agent agent = LangChainAgent( @@ -182,7 +182,7 @@ class AppChatService: # 获取模型配置ID model_config_id = config.default_model_config_id - api_key_obj = ModelApiKeyService.get_a_api_key(model_config_id) + api_key_obj = ModelApiKeyService.get_a_api_key(self.db ,model_config_id) # 处理系统提示词(支持变量替换) system_prompt = config.get("system_prompt", "") if variables: @@ -497,7 +497,7 @@ class AppChatService: # 获取模型配置ID model_config_id = config.default_model_config_id - api_key_obj = ModelApiKeyService.get_a_api_key(model_config_id) + api_key_obj = ModelApiKeyService.get_a_api_key(self.db ,model_config_id) # 处理系统提示词(支持变量替换) system_prompt = config.get("system_prompt", "") if variables: @@ -628,7 +628,7 @@ class AppChatService: # 获取模型配置ID model_config_id = config.default_model_config_id - api_key_obj = ModelApiKeyService.get_a_api_key(model_config_id) + api_key_obj = ModelApiKeyService.get_a_api_key(self.db ,model_config_id) # 处理系统提示词(支持变量替换) system_prompt = config.get("system_prompt", "") if variables: diff --git a/api/app/utils/app_config_utils.py b/api/app/utils/app_config_utils.py index 4202644a..85f2e7c7 100644 --- a/api/app/utils/app_config_utils.py +++ b/api/app/utils/app_config_utils.py @@ -8,10 +8,12 @@ import uuid from typing import Dict, Any, Optional from datetime import datetime +from app.models import AppRelease + class AgentConfigProxy: """Proxy class for AgentConfig (legacy compatibility)""" - + def __init__(self, release, app, config_data): self.id = release.id self.app_id = release.app_id @@ -22,86 +24,44 @@ class AgentConfigProxy: self.default_model_config_id = release.default_model_config_id -def dict_to_agent_config(config_dict: Dict[str, Any], app_id: Optional[uuid.UUID] = None): - """Convert dict to AgentConfig model object - - Args: - config_dict: Configuration dictionary - app_id: Optional app ID (if not provided in dict) - - Returns: - AgentConfig model instance (not yet persisted to database) - - Example: - >>> config_dict = { - ... "app_id": "uuid-here", - ... "system_prompt": "You are a helpful assistant", - ... "default_model_config_id": "model-uuid", - ... "model_parameters": {"temperature": 0.7, "max_tokens": 2000}, - ... "knowledge_retrieval": {"enabled": True, "top_k": 5}, - ... "memory": {"enabled": True, "window_size": 10}, - ... "variables": [{"name": "user_name", "type": "string"}], - ... "tools": {"enabled_tools": ["web_search", "calculator"]}, - ... "agent_role": "standalone", - ... "agent_domain": "customer_service", - ... "capabilities": ["chat", "search"] - ... } - >>> agent_config = dict_to_agent_config(config_dict) - """ +def agent_config_4_app_release(release: AppRelease ): from app.models.agent_app_config_model import AgentConfig - - # Extract app_id - final_app_id = config_dict.get("app_id") or app_id - if not final_app_id: - raise ValueError("app_id is required") - - # Convert string UUID to UUID object if needed - if isinstance(final_app_id, str): - final_app_id = uuid.UUID(final_app_id) - - # Convert default_model_config_id if present - default_model_config_id = config_dict.get("default_model_config_id") - if default_model_config_id and isinstance(default_model_config_id, str): - default_model_config_id = uuid.UUID(default_model_config_id) - - # Convert parent_agent_id if present - parent_agent_id = config_dict.get("parent_agent_id") - if parent_agent_id and isinstance(parent_agent_id, str): - parent_agent_id = uuid.UUID(parent_agent_id) - # Create AgentConfig instance + # config = { + # "system_prompt": agent_cfg.system_prompt, + # "model_parameters": agent_cfg.model_parameters, + # "knowledge_retrieval": agent_cfg.knowledge_retrieval, + # "memory": agent_cfg.memory, + # "variables": agent_cfg.variables or [], + # "tools": agent_cfg.tools or {}, + # } + # + config_dict = release.config + agent_config = AgentConfig( - id=uuid.UUID(config_dict["id"]) if "id" in config_dict else uuid.uuid4(), - app_id=final_app_id, + app_id=release.app_id, system_prompt=config_dict.get("system_prompt"), - default_model_config_id=default_model_config_id, + default_model_config_id=release.default_model_config_id, model_parameters=config_dict.get("model_parameters"), knowledge_retrieval=config_dict.get("knowledge_retrieval"), memory=config_dict.get("memory"), variables=config_dict.get("variables", []), tools=config_dict.get("tools", {}), - agent_role=config_dict.get("agent_role"), - agent_domain=config_dict.get("agent_domain"), - parent_agent_id=parent_agent_id, - capabilities=config_dict.get("capabilities", []), - is_active=config_dict.get("is_active", True), - created_at=config_dict.get("created_at", datetime.now()), - updated_at=config_dict.get("updated_at", datetime.now()) ) - + return agent_config def dict_to_multi_agent_config(config_dict: Dict[str, Any], app_id: Optional[uuid.UUID] = None): """Convert dict to MultiAgentConfig model object - + Args: config_dict: Configuration dictionary app_id: Optional app ID (if not provided in dict) - + Returns: MultiAgentConfig model instance (not yet persisted to database) - + Example: >>> config_dict = { ... "app_id": "uuid-here", @@ -121,23 +81,23 @@ def dict_to_multi_agent_config(config_dict: Dict[str, Any], app_id: Optional[uui >>> multi_agent_config = dict_to_multi_agent_config(config_dict) """ from app.models.multi_agent_model import MultiAgentConfig - + # Extract app_id final_app_id = config_dict.get("app_id") or app_id if not final_app_id: raise ValueError("app_id is required") - + # Convert string UUID to UUID object if needed if isinstance(final_app_id, str): final_app_id = uuid.UUID(final_app_id) - + # Convert master_agent_id master_agent_id = config_dict.get("master_agent_id") if not master_agent_id: raise ValueError("master_agent_id is required") if isinstance(master_agent_id, str): master_agent_id = uuid.UUID(master_agent_id) - + # Create MultiAgentConfig instance multi_agent_config = MultiAgentConfig( id=uuid.UUID(config_dict["id"]) if "id" in config_dict else uuid.uuid4(), @@ -153,20 +113,20 @@ def dict_to_multi_agent_config(config_dict: Dict[str, Any], app_id: Optional[uui created_at=config_dict.get("created_at", datetime.now()), updated_at=config_dict.get("updated_at", datetime.now()) ) - + return multi_agent_config def dict_to_workflow_config(config_dict: Dict[str, Any], app_id: Optional[uuid.UUID] = None): """Convert dict to WorkflowConfig model object - + Args: config_dict: Configuration dictionary app_id: Optional app ID (if not provided in dict) - + Returns: WorkflowConfig model instance (not yet persisted to database) - + Example: >>> config_dict = { ... "app_id": "uuid-here", @@ -194,16 +154,16 @@ def dict_to_workflow_config(config_dict: Dict[str, Any], app_id: Optional[uuid.U >>> workflow_config = dict_to_workflow_config(config_dict) """ from app.models.workflow_model import WorkflowConfig - + # Extract app_id final_app_id = config_dict.get("app_id") or app_id if not final_app_id: raise ValueError("app_id is required") - + # Convert string UUID to UUID object if needed if isinstance(final_app_id, str): final_app_id = uuid.UUID(final_app_id) - + # Create WorkflowConfig instance workflow_config = WorkflowConfig( id=uuid.UUID(config_dict["id"]) if "id" in config_dict else uuid.uuid4(), @@ -217,16 +177,16 @@ def dict_to_workflow_config(config_dict: Dict[str, Any], app_id: Optional[uuid.U created_at=config_dict.get("created_at", datetime.now()), updated_at=config_dict.get("updated_at", datetime.now()) ) - + return workflow_config def agent_config_to_dict(agent_config) -> Dict[str, Any]: """Convert AgentConfig model to dict - + Args: agent_config: AgentConfig model instance - + Returns: Configuration dictionary """ @@ -252,10 +212,10 @@ def agent_config_to_dict(agent_config) -> Dict[str, Any]: def multi_agent_config_to_dict(multi_agent_config) -> Dict[str, Any]: """Convert MultiAgentConfig model to dict - + Args: multi_agent_config: MultiAgentConfig model instance - + Returns: Configuration dictionary """ @@ -277,10 +237,10 @@ def multi_agent_config_to_dict(multi_agent_config) -> Dict[str, Any]: def workflow_config_to_dict(workflow_config) -> Dict[str, Any]: """Convert WorkflowConfig model to dict - + Args: workflow_config: WorkflowConfig model instance - + Returns: Configuration dictionary """