| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except services.errors.conversation.ConversationNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Conversation Not Exists.")).get_json()) + "\n\n" | |||||
| except services.errors.conversation.ConversationCompletedError: | |||||
| yield "data: " + json.dumps(api.handle_error(ConversationCompletedError()).get_json()) + "\n\n" | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| yield "data: " + json.dumps(api.handle_error(AppUnavailableError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except MessageNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Message Not Exists.")).get_json()) + "\n\n" | |||||
| except MoreLikeThisDisabledError: | |||||
| yield "data: " + json.dumps(api.handle_error(AppMoreLikeThisDisabledError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps( | |||||
| api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except services.errors.conversation.ConversationNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Conversation Not Exists.")).get_json()) + "\n\n" | |||||
| except services.errors.conversation.ConversationCompletedError: | |||||
| yield "data: " + json.dumps(api.handle_error(ConversationCompletedError()).get_json()) + "\n\n" | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| yield "data: " + json.dumps(api.handle_error(AppUnavailableError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except MessageNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Message Not Exists.")).get_json()) + "\n\n" | |||||
| except MoreLikeThisDisabledError: | |||||
| yield "data: " + json.dumps(api.handle_error(AppMoreLikeThisDisabledError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except services.errors.conversation.ConversationNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Conversation Not Exists.")).get_json()) + "\n\n" | |||||
| except services.errors.conversation.ConversationCompletedError: | |||||
| yield "data: " + json.dumps(api.handle_error(ConversationCompletedError()).get_json()) + "\n\n" | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| yield "data: " + json.dumps(api.handle_error(AppUnavailableError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError()).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| api = ExternalApi(bp) | api = ExternalApi(bp) | ||||
| from . import index | |||||
| from .app import app, audio, completion, conversation, file, message | from .app import app, audio, completion, conversation, file, message | ||||
| from .dataset import dataset, document, segment | from .dataset import dataset, document, segment |
| if app_model.mode != 'completion': | if app_model.mode != 'completion': | ||||
| raise AppUnavailableError() | raise AppUnavailableError() | ||||
| end_user_id = request.get_json().get('user') | |||||
| parser = reqparse.RequestParser() | |||||
| parser.add_argument('user', required=True, nullable=False, type=str, location='json') | |||||
| args = parser.parse_args() | |||||
| end_user_id = args.get('user') | |||||
| ApplicationQueueManager.set_stop_flag(task_id, InvokeFrom.SERVICE_API, end_user_id) | ApplicationQueueManager.set_stop_flag(task_id, InvokeFrom.SERVICE_API, end_user_id) | ||||
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except services.errors.conversation.ConversationNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Conversation Not Exists.")).get_json()) + "\n\n" | |||||
| except services.errors.conversation.ConversationCompletedError: | |||||
| yield "data: " + json.dumps(api.handle_error(ConversationCompletedError()).get_json()) + "\n\n" | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| yield "data: " + json.dumps(api.handle_error(AppUnavailableError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| api.add_resource(ConversationRenameApi, '/conversations/<uuid:c_id>/name', endpoint='conversation_name') | api.add_resource(ConversationRenameApi, '/conversations/<uuid:c_id>/name', endpoint='conversation_name') | ||||
| api.add_resource(ConversationApi, '/conversations') | api.add_resource(ConversationApi, '/conversations') | ||||
| api.add_resource(ConversationApi, '/conversations/<uuid:c_id>', endpoint='conversation') | |||||
| api.add_resource(ConversationDetailApi, '/conversations/<uuid:c_id>', endpoint='conversation_detail') | api.add_resource(ConversationDetailApi, '/conversations/<uuid:c_id>', endpoint='conversation_detail') |
| from flask import current_app | |||||
| from flask_restful import Resource | |||||
| from controllers.service_api import api | |||||
| class IndexApi(Resource): | |||||
| def get(self): | |||||
| return { | |||||
| "welcome": "Dify OpenAPI", | |||||
| "api_version": "v1", | |||||
| "server_version": current_app.config['CURRENT_VERSION'] | |||||
| } | |||||
| api.add_resource(IndexApi, '/') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except services.errors.conversation.ConversationNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Conversation Not Exists.")).get_json()) + "\n\n" | |||||
| except services.errors.conversation.ConversationCompletedError: | |||||
| yield "data: " + json.dumps(api.handle_error(ConversationCompletedError()).get_json()) + "\n\n" | |||||
| except services.errors.app_model_config.AppModelConfigBrokenError: | |||||
| logging.exception("App model config broken.") | |||||
| yield "data: " + json.dumps(api.handle_error(AppUnavailableError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| return Response(response=json.dumps(response), status=200, mimetype='application/json') | return Response(response=json.dumps(response), status=200, mimetype='application/json') | ||||
| else: | else: | ||||
| def generate() -> Generator: | def generate() -> Generator: | ||||
| try: | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| except MessageNotExistsError: | |||||
| yield "data: " + json.dumps(api.handle_error(NotFound("Message Not Exists.")).get_json()) + "\n\n" | |||||
| except MoreLikeThisDisabledError: | |||||
| yield "data: " + json.dumps(api.handle_error(AppMoreLikeThisDisabledError()).get_json()) + "\n\n" | |||||
| except ProviderTokenNotInitError as ex: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderNotInitializeError(ex.description)).get_json()) + "\n\n" | |||||
| except QuotaExceededError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderQuotaExceededError()).get_json()) + "\n\n" | |||||
| except ModelCurrentlyNotSupportError: | |||||
| yield "data: " + json.dumps(api.handle_error(ProviderModelCurrentlyNotSupportError()).get_json()) + "\n\n" | |||||
| except InvokeError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(CompletionRequestError(e.description)).get_json()) + "\n\n" | |||||
| except ValueError as e: | |||||
| yield "data: " + json.dumps(api.handle_error(e).get_json()) + "\n\n" | |||||
| except Exception: | |||||
| logging.exception("internal server error.") | |||||
| yield "data: " + json.dumps(api.handle_error(InternalServerError()).get_json()) + "\n\n" | |||||
| for chunk in response: | |||||
| yield chunk | |||||
| return Response(stream_with_context(generate()), status=200, | return Response(stream_with_context(generate()), status=200, | ||||
| mimetype='text/event-stream') | mimetype='text/event-stream') |
| from core.app_runner.moderation_handler import ModerationRule, OutputModerationHandler | from core.app_runner.moderation_handler import ModerationRule, OutputModerationHandler | ||||
| from core.application_queue_manager import ApplicationQueueManager, PublishFrom | from core.application_queue_manager import ApplicationQueueManager, PublishFrom | ||||
| from core.entities.application_entities import ApplicationGenerateEntity | |||||
| from core.entities.application_entities import ApplicationGenerateEntity, InvokeFrom | |||||
| from core.entities.queue_entities import (AnnotationReplyEvent, QueueAgentThoughtEvent, QueueErrorEvent, | from core.entities.queue_entities import (AnnotationReplyEvent, QueueAgentThoughtEvent, QueueErrorEvent, | ||||
| QueueMessageEndEvent, QueueMessageEvent, QueueMessageReplaceEvent, | QueueMessageEndEvent, QueueMessageEvent, QueueMessageReplaceEvent, | ||||
| QueuePingEvent, QueueRetrieverResourcesEvent, QueueStopEvent) | QueuePingEvent, QueueRetrieverResourcesEvent, QueueStopEvent) | ||||
| from core.errors.error import ProviderTokenNotInitError, QuotaExceededError, ModelCurrentlyNotSupportError | |||||
| from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta, LLMUsage | from core.model_runtime.entities.llm_entities import LLMResult, LLMResultChunk, LLMResultChunkDelta, LLMUsage | ||||
| from core.model_runtime.entities.message_entities import (AssistantPromptMessage, ImagePromptMessageContent, | from core.model_runtime.entities.message_entities import (AssistantPromptMessage, ImagePromptMessageContent, | ||||
| PromptMessage, PromptMessageContentType, PromptMessageRole, | PromptMessage, PromptMessageContentType, PromptMessageRole, | ||||
| TextPromptMessageContent) | TextPromptMessageContent) | ||||
| from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError | from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError | ||||
| from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel | from core.model_runtime.model_providers.__base.large_language_model import LargeLanguageModel | ||||
| from core.model_runtime.utils.encoders import jsonable_encoder | |||||
| from core.prompt.prompt_template import PromptTemplateParser | from core.prompt.prompt_template import PromptTemplateParser | ||||
| from events.message_event import message_was_created | from events.message_event import message_was_created | ||||
| from extensions.ext_database import db | from extensions.ext_database import db | ||||
| completion_tokens | completion_tokens | ||||
| ) | ) | ||||
| self._task_state.metadata['usage'] = jsonable_encoder(self._task_state.llm_result.usage) | |||||
| # response moderation | # response moderation | ||||
| if self._output_moderation_handler: | if self._output_moderation_handler: | ||||
| self._output_moderation_handler.stop_thread() | self._output_moderation_handler.stop_thread() | ||||
| ) | ) | ||||
| # Save message | # Save message | ||||
| self._save_message(event.llm_result) | |||||
| self._save_message(self._task_state.llm_result) | |||||
| response = { | response = { | ||||
| 'event': 'message', | 'event': 'message', | ||||
| 'task_id': self._application_generate_entity.task_id, | 'task_id': self._application_generate_entity.task_id, | ||||
| 'id': self._message.id, | 'id': self._message.id, | ||||
| 'message_id': self._message.id, | |||||
| 'mode': self._conversation.mode, | 'mode': self._conversation.mode, | ||||
| 'answer': event.llm_result.message.content, | 'answer': event.llm_result.message.content, | ||||
| 'metadata': {}, | 'metadata': {}, | ||||
| response['conversation_id'] = self._conversation.id | response['conversation_id'] = self._conversation.id | ||||
| if self._task_state.metadata: | if self._task_state.metadata: | ||||
| response['metadata'] = self._task_state.metadata | |||||
| response['metadata'] = self._get_response_metadata() | |||||
| return response | return response | ||||
| else: | else: | ||||
| event = message.event | event = message.event | ||||
| if isinstance(event, QueueErrorEvent): | if isinstance(event, QueueErrorEvent): | ||||
| raise self._handle_error(event) | |||||
| data = self._error_to_stream_response_data(self._handle_error(event)) | |||||
| yield self._yield_response(data) | |||||
| break | |||||
| elif isinstance(event, (QueueStopEvent, QueueMessageEndEvent)): | elif isinstance(event, (QueueStopEvent, QueueMessageEndEvent)): | ||||
| if isinstance(event, QueueMessageEndEvent): | if isinstance(event, QueueMessageEndEvent): | ||||
| self._task_state.llm_result = event.llm_result | self._task_state.llm_result = event.llm_result | ||||
| completion_tokens | completion_tokens | ||||
| ) | ) | ||||
| self._task_state.metadata['usage'] = jsonable_encoder(self._task_state.llm_result.usage) | |||||
| # response moderation | # response moderation | ||||
| if self._output_moderation_handler: | if self._output_moderation_handler: | ||||
| self._output_moderation_handler.stop_thread() | self._output_moderation_handler.stop_thread() | ||||
| 'event': 'message_end', | 'event': 'message_end', | ||||
| 'task_id': self._application_generate_entity.task_id, | 'task_id': self._application_generate_entity.task_id, | ||||
| 'id': self._message.id, | 'id': self._message.id, | ||||
| 'message_id': self._message.id, | |||||
| } | } | ||||
| if self._conversation.mode == 'chat': | if self._conversation.mode == 'chat': | ||||
| response['conversation_id'] = self._conversation.id | response['conversation_id'] = self._conversation.id | ||||
| if self._task_state.metadata: | if self._task_state.metadata: | ||||
| response['metadata'] = self._task_state.metadata | |||||
| response['metadata'] = self._get_response_metadata() | |||||
| yield self._yield_response(response) | yield self._yield_response(response) | ||||
| elif isinstance(event, QueueRetrieverResourcesEvent): | elif isinstance(event, QueueRetrieverResourcesEvent): | ||||
| else: | else: | ||||
| return Exception(e.description if getattr(e, 'description', None) is not None else str(e)) | return Exception(e.description if getattr(e, 'description', None) is not None else str(e)) | ||||
| def _error_to_stream_response_data(self, e: Exception) -> dict: | |||||
| """ | |||||
| Error to stream response. | |||||
| :param e: exception | |||||
| :return: | |||||
| """ | |||||
| if isinstance(e, ValueError): | |||||
| data = { | |||||
| 'code': 'invalid_param', | |||||
| 'message': str(e), | |||||
| 'status': 400 | |||||
| } | |||||
| elif isinstance(e, ProviderTokenNotInitError): | |||||
| data = { | |||||
| 'code': 'provider_not_initialize', | |||||
| 'message': e.description, | |||||
| 'status': 400 | |||||
| } | |||||
| elif isinstance(e, QuotaExceededError): | |||||
| data = { | |||||
| 'code': 'provider_quota_exceeded', | |||||
| 'message': "Your quota for Dify Hosted Model Provider has been exhausted. " | |||||
| "Please go to Settings -> Model Provider to complete your own provider credentials.", | |||||
| 'status': 400 | |||||
| } | |||||
| elif isinstance(e, ModelCurrentlyNotSupportError): | |||||
| data = { | |||||
| 'code': 'model_currently_not_support', | |||||
| 'message': e.description, | |||||
| 'status': 400 | |||||
| } | |||||
| elif isinstance(e, InvokeError): | |||||
| data = { | |||||
| 'code': 'completion_request_error', | |||||
| 'message': e.description, | |||||
| 'status': 400 | |||||
| } | |||||
| else: | |||||
| logging.error(e) | |||||
| data = { | |||||
| 'code': 'internal_server_error', | |||||
| 'message': 'Internal Server Error, please contact support.', | |||||
| 'status': 500 | |||||
| } | |||||
| return { | |||||
| 'event': 'error', | |||||
| 'task_id': self._application_generate_entity.task_id, | |||||
| 'message_id': self._message.id, | |||||
| **data | |||||
| } | |||||
| def _get_response_metadata(self) -> dict: | |||||
| """ | |||||
| Get response metadata by invoke from. | |||||
| :return: | |||||
| """ | |||||
| metadata = {} | |||||
| # show_retrieve_source | |||||
| if 'retriever_resources' in self._task_state.metadata: | |||||
| if self._application_generate_entity.invoke_from in [InvokeFrom.DEBUGGER, InvokeFrom.SERVICE_API]: | |||||
| metadata['retriever_resources'] = self._task_state.metadata['retriever_resources'] | |||||
| else: | |||||
| metadata['retriever_resources'] = [] | |||||
| for resource in self._task_state.metadata['retriever_resources']: | |||||
| metadata['retriever_resources'].append({ | |||||
| 'segment_id': resource['segment_id'], | |||||
| 'position': resource['position'], | |||||
| 'document_name': resource['document_name'], | |||||
| 'score': resource['score'], | |||||
| 'content': resource['content'], | |||||
| }) | |||||
| # show usage | |||||
| if self._application_generate_entity.invoke_from in [InvokeFrom.DEBUGGER, InvokeFrom.SERVICE_API]: | |||||
| metadata['usage'] = self._task_state.metadata['usage'] | |||||
| return metadata | |||||
| def _yield_response(self, response: dict) -> str: | def _yield_response(self, response: dict) -> str: | ||||
| """ | """ | ||||
| Yield response. | Yield response. |
| return str(obj) | return str(obj) | ||||
| if isinstance(obj, (str, int, float, type(None))): | if isinstance(obj, (str, int, float, type(None))): | ||||
| return obj | return obj | ||||
| if isinstance(obj, Decimal): | |||||
| return format(obj, 'f') | |||||
| if isinstance(obj, dict): | if isinstance(obj, dict): | ||||
| encoded_dict = {} | encoded_dict = {} | ||||
| allowed_keys = set(obj.keys()) | allowed_keys = set(obj.keys()) |
| 'message': getattr(e, 'description', http_status_message(status_code)), | 'message': getattr(e, 'description', http_status_message(status_code)), | ||||
| 'status': status_code | 'status': status_code | ||||
| } | } | ||||
| if default_data['message'] and default_data['message'] == 'Failed to decode JSON object: Expecting value: line 1 column 1 (char 0)': | |||||
| default_data['message'] = 'Invalid JSON payload received or JSON payload is empty.' | |||||
| headers = e.get_response().headers | headers = e.get_response().headers | ||||
| elif isinstance(e, ValueError): | elif isinstance(e, ValueError): | ||||
| status_code = 400 | status_code = 400 |
| auto_generate_name = args['auto_generate_name'] \ | auto_generate_name = args['auto_generate_name'] \ | ||||
| if 'auto_generate_name' in args else True | if 'auto_generate_name' in args else True | ||||
| if app_model.mode != 'completion' and not query: | |||||
| raise ValueError('query is required') | |||||
| if app_model.mode != 'completion': | |||||
| if not query: | |||||
| raise ValueError('query is required') | |||||
| query = query.replace('\x00', '') | |||||
| if query: | |||||
| if not isinstance(query, str): | |||||
| raise ValueError('query must be a string') | |||||
| query = query.replace('\x00', '') | |||||
| conversation_id = args['conversation_id'] if 'conversation_id' in args else None | conversation_id = args['conversation_id'] if 'conversation_id' in args else None | ||||
| value = user_inputs[variable] | value = user_inputs[variable] | ||||
| if value: | |||||
| if not isinstance(value, str): | |||||
| raise ValueError(f"{variable} in input form must be a string") | |||||
| if input_type == "select": | if input_type == "select": | ||||
| options = input_config["options"] if "options" in input_config else [] | options = input_config["options"] if "options" in input_config else [] | ||||
| if value not in options: | if value not in options: | ||||
| filtered_inputs[variable] = value.replace('\x00', '') if value else None | filtered_inputs[variable] = value.replace('\x00', '') if value else None | ||||
| return filtered_inputs | return filtered_inputs | ||||