diff --git a/api/core/app/apps/advanced_chat/app_generator.py b/api/core/app/apps/advanced_chat/app_generator.py index cc7bc64439..571d5b66c0 100644 --- a/api/core/app/apps/advanced_chat/app_generator.py +++ b/api/core/app/apps/advanced_chat/app_generator.py @@ -55,6 +55,7 @@ from libs.flask_utils import preserve_flask_contexts from models import Account, App, Conversation, EndUser, Message, Workflow, WorkflowNodeExecutionTriggeredFrom from models.enums import WorkflowRunTriggeredFrom from services.conversation_service import ConversationService +from services.errors.conversation import ConversationNotExistsError from services.workflow_draft_variable_service import ( DraftVarLoader, WorkflowDraftVariableService, @@ -145,9 +146,15 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator): conversation = None conversation_id = args.get("conversation_id") if conversation_id: - conversation = ConversationService.get_conversation( - app_model=app_model, conversation_id=conversation_id, user=user - ) + try: + conversation = ConversationService.get_conversation( + app_model=app_model, conversation_id=conversation_id, user=user + ) + except ConversationNotExistsError: + if invoke_from == InvokeFrom.SERVICE_API: + conversation = None + else: + raise # parse files # TODO(QuantumGhost): Move file parsing logic to the API controller layer diff --git a/api/tests/unit_tests/core/app/apps/test_advanced_chat_app_generator.py b/api/tests/unit_tests/core/app/apps/test_advanced_chat_app_generator.py index 835c9a8576..9b89b10820 100644 --- a/api/tests/unit_tests/core/app/apps/test_advanced_chat_app_generator.py +++ b/api/tests/unit_tests/core/app/apps/test_advanced_chat_app_generator.py @@ -11,8 +11,10 @@ from core.app.apps.advanced_chat.app_generator import AdvancedChatAppGenerator from core.app.entities.app_invoke_entities import AdvancedChatAppGenerateEntity, InvokeFrom from core.app.task_pipeline import message_cycle_manager from core.app.task_pipeline.message_cycle_manager import MessageCycleManager +from core.ops.ops_trace_manager import TraceQueueManager from models.enums import ConversationFromSource from models.model import AppMode, Conversation, Message +from services.errors.conversation import ConversationNotExistsError def _make_app_config() -> WorkflowUIBasedAppConfig: @@ -108,6 +110,75 @@ def test_init_generate_records_marks_existing_conversation(): assert entity.is_new_conversation is False +def test_generate_falls_back_to_new_conversation_when_conversation_missing(monkeypatch: pytest.MonkeyPatch): + app_config = _make_app_config() + workflow = SimpleNamespace( + features_dict={}, + tenant_id="tenant-id", + app_id="app-id", + id="workflow-id", + ) + app_model = SimpleNamespace(id="app-id", tenant_id="tenant-id") + user = SimpleNamespace(id="user-id", session_id="session-id") + + def raise_conversation_not_exists(**_kwargs): + raise ConversationNotExistsError() + + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.ConversationService.get_conversation", + raise_conversation_not_exists, + ) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.FileUploadConfigManager.convert", + lambda *_args, **_kwargs: None, + ) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.AdvancedChatAppConfigManager.get_app_config", + lambda **_kwargs: app_config, + ) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.db", + SimpleNamespace(engine=object()), + ) + trace_manager = object.__new__(TraceQueueManager) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.TraceQueueManager", + lambda **_kwargs: trace_manager, + ) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.DifyCoreRepositoryFactory.create_workflow_execution_repository", + lambda **_kwargs: SimpleNamespace(), + ) + monkeypatch.setattr( + "core.app.apps.advanced_chat.app_generator.DifyCoreRepositoryFactory.create_workflow_node_execution_repository", + lambda **_kwargs: SimpleNamespace(), + ) + + captured: dict[str, object] = {} + + def fake_generate(self, **kwargs): + captured.update(kwargs) + return {"status": "ok"} + + monkeypatch.setattr(AdvancedChatAppGenerator, "_generate", fake_generate) + + result = AdvancedChatAppGenerator().generate( + app_model=app_model, + workflow=workflow, + user=user, + args={"inputs": {}, "query": "hello", "conversation_id": "missing-conversation-id"}, + invoke_from=InvokeFrom.SERVICE_API, + workflow_run_id="workflow-run-id", + streaming=False, + ) + + assert result == {"status": "ok"} + assert captured["conversation"] is None + application_generate_entity = captured["application_generate_entity"] + assert isinstance(application_generate_entity, AdvancedChatAppGenerateEntity) + assert application_generate_entity.conversation_id is None + + def test_message_cycle_manager_uses_new_conversation_flag(monkeypatch: pytest.MonkeyPatch): app_config = _make_app_config() entity = _make_generate_entity(app_config)