diff --git a/api/controllers/service_api/app/completion.py b/api/controllers/service_api/app/completion.py index 5c3601cf23..8d8e356c4c 100644 --- a/api/controllers/service_api/app/completion.py +++ b/api/controllers/service_api/app/completion.py @@ -4,7 +4,6 @@ from flask_restful import Resource, reqparse from werkzeug.exceptions import InternalServerError, NotFound import services -from constants import UUID_NIL from controllers.service_api import api from controllers.service_api.app.error import ( AppUnavailableError, @@ -108,7 +107,6 @@ class ChatApi(Resource): parser.add_argument("conversation_id", type=uuid_value, location="json") parser.add_argument("retriever_from", type=str, required=False, default="dev", location="json") parser.add_argument("auto_generate_name", type=bool, required=False, default=True, location="json") - parser.add_argument("parent_message_id", type=uuid_value, required=False, default=UUID_NIL, location="json") args = parser.parse_args() diff --git a/api/core/app/apps/advanced_chat/app_generator.py b/api/core/app/apps/advanced_chat/app_generator.py index 0d183596f3..7fff925f4b 100644 --- a/api/core/app/apps/advanced_chat/app_generator.py +++ b/api/core/app/apps/advanced_chat/app_generator.py @@ -10,6 +10,7 @@ from flask import Flask, current_app from pydantic import ValidationError import contexts +from constants import UUID_NIL from core.app.app_config.features.file_upload.manager import FileUploadConfigManager from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfigManager from core.app.apps.advanced_chat.app_runner import AdvancedChatAppRunner @@ -122,7 +123,7 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator): inputs=conversation.inputs if conversation else self._get_cleaned_inputs(inputs, app_config), query=query, files=file_objs, - parent_message_id=args.get("parent_message_id"), + parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL, user_id=user.id, stream=stream, invoke_from=invoke_from, diff --git a/api/core/app/apps/agent_chat/app_generator.py b/api/core/app/apps/agent_chat/app_generator.py index 99abccf4f9..81c3c765dc 100644 --- a/api/core/app/apps/agent_chat/app_generator.py +++ b/api/core/app/apps/agent_chat/app_generator.py @@ -8,6 +8,7 @@ from typing import Any, Literal, Union, overload from flask import Flask, current_app from pydantic import ValidationError +from constants import UUID_NIL from core.app.app_config.easy_ui_based_app.model_config.converter import ModelConfigConverter from core.app.app_config.features.file_upload.manager import FileUploadConfigManager from core.app.apps.agent_chat.app_config_manager import AgentChatAppConfigManager @@ -127,7 +128,7 @@ class AgentChatAppGenerator(MessageBasedAppGenerator): inputs=conversation.inputs if conversation else self._get_cleaned_inputs(inputs, app_config), query=query, files=file_objs, - parent_message_id=args.get("parent_message_id"), + parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL, user_id=user.id, stream=stream, invoke_from=invoke_from, diff --git a/api/core/app/apps/chat/app_generator.py b/api/core/app/apps/chat/app_generator.py index 9ef1366a0f..49b56ecc67 100644 --- a/api/core/app/apps/chat/app_generator.py +++ b/api/core/app/apps/chat/app_generator.py @@ -8,6 +8,7 @@ from typing import Any, Literal, Union, overload from flask import Flask, current_app from pydantic import ValidationError +from constants import UUID_NIL from core.app.app_config.easy_ui_based_app.model_config.converter import ModelConfigConverter from core.app.app_config.features.file_upload.manager import FileUploadConfigManager from core.app.apps.base_app_queue_manager import AppQueueManager, GenerateTaskStoppedError, PublishFrom @@ -128,7 +129,7 @@ class ChatAppGenerator(MessageBasedAppGenerator): inputs=conversation.inputs if conversation else self._get_cleaned_inputs(inputs, app_config), query=query, files=file_objs, - parent_message_id=args.get("parent_message_id"), + parent_message_id=args.get("parent_message_id") if invoke_from != InvokeFrom.SERVICE_API else UUID_NIL, user_id=user.id, stream=stream, invoke_from=invoke_from, diff --git a/api/core/app/entities/app_invoke_entities.py b/api/core/app/entities/app_invoke_entities.py index e757c8db75..98685513a3 100644 --- a/api/core/app/entities/app_invoke_entities.py +++ b/api/core/app/entities/app_invoke_entities.py @@ -2,8 +2,9 @@ from collections.abc import Mapping from enum import Enum from typing import Any, Optional -from pydantic import BaseModel, ConfigDict +from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator +from constants import UUID_NIL from core.app.app_config.entities import AppConfig, EasyUIBasedAppConfig, WorkflowUIBasedAppConfig from core.entities.provider_configuration import ProviderModelBundle from core.file.file_obj import FileVar @@ -116,13 +117,36 @@ class EasyUIBasedAppGenerateEntity(AppGenerateEntity): model_config = ConfigDict(protected_namespaces=()) -class ChatAppGenerateEntity(EasyUIBasedAppGenerateEntity): +class ConversationAppGenerateEntity(AppGenerateEntity): + """ + Base entity for conversation-based app generation. + """ + + conversation_id: Optional[str] = None + parent_message_id: Optional[str] = Field( + default=None, + description=( + "Starting from v0.9.0, parent_message_id is used to support message regeneration for internal chat API." + "For service API, we need to ensure its forward compatibility, " + "so passing in the parent_message_id as request arg is not supported for now. " + "It needs to be set to UUID_NIL so that the subsequent processing will treat it as legacy messages." + ), + ) + + @field_validator("parent_message_id") + @classmethod + def validate_parent_message_id(cls, v, info: ValidationInfo): + if info.data.get("invoke_from") == InvokeFrom.SERVICE_API and v != UUID_NIL: + raise ValueError("parent_message_id should be UUID_NIL for service API") + return v + + +class ChatAppGenerateEntity(ConversationAppGenerateEntity, EasyUIBasedAppGenerateEntity): """ Chat Application Generate Entity. """ - conversation_id: Optional[str] = None - parent_message_id: Optional[str] = None + pass class CompletionAppGenerateEntity(EasyUIBasedAppGenerateEntity): @@ -133,16 +157,15 @@ class CompletionAppGenerateEntity(EasyUIBasedAppGenerateEntity): pass -class AgentChatAppGenerateEntity(EasyUIBasedAppGenerateEntity): +class AgentChatAppGenerateEntity(ConversationAppGenerateEntity, EasyUIBasedAppGenerateEntity): """ Agent Chat Application Generate Entity. """ - conversation_id: Optional[str] = None - parent_message_id: Optional[str] = None + pass -class AdvancedChatAppGenerateEntity(AppGenerateEntity): +class AdvancedChatAppGenerateEntity(ConversationAppGenerateEntity): """ Advanced Chat Application Generate Entity. """ @@ -150,8 +173,6 @@ class AdvancedChatAppGenerateEntity(AppGenerateEntity): # app config app_config: WorkflowUIBasedAppConfig - conversation_id: Optional[str] = None - parent_message_id: Optional[str] = None workflow_run_id: Optional[str] = None query: str