mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-13 03:09:01 +08:00
feat: service api add llm usage (#2051)
This commit is contained in:
parent
1d91535ba6
commit
1a6ad05a23
@ -163,29 +163,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -241,27 +241,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -158,29 +158,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -117,26 +117,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -109,29 +109,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -6,5 +6,6 @@ bp = Blueprint('service_api', __name__, url_prefix='/v1')
|
|||||||
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
|
||||||
|
@ -79,7 +79,12 @@ class CompletionStopApi(AppApiResource):
|
|||||||
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)
|
||||||
|
|
||||||
@ -157,29 +162,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -86,5 +86,4 @@ class ConversationRenameApi(AppApiResource):
|
|||||||
|
|
||||||
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')
|
||||||
|
16
api/controllers/service_api/index.py
Normal file
16
api/controllers/service_api/index.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
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, '/')
|
@ -146,29 +146,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -151,26 +151,8 @@ def compact_response(response: Union[dict, Generator]) -> Response:
|
|||||||
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:
|
||||||
for chunk in response:
|
yield chunk
|
||||||
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"
|
|
||||||
|
|
||||||
return Response(stream_with_context(generate()), status=200,
|
return Response(stream_with_context(generate()), status=200,
|
||||||
mimetype='text/event-stream')
|
mimetype='text/event-stream')
|
||||||
|
@ -5,16 +5,18 @@ from typing import Generator, Optional, Union, cast
|
|||||||
|
|
||||||
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
|
||||||
@ -135,6 +137,8 @@ class GenerateTaskPipeline:
|
|||||||
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()
|
||||||
@ -145,12 +149,13 @@ class GenerateTaskPipeline:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# 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': {},
|
||||||
@ -161,7 +166,7 @@ class GenerateTaskPipeline:
|
|||||||
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:
|
||||||
@ -176,7 +181,9 @@ class GenerateTaskPipeline:
|
|||||||
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
|
||||||
@ -213,6 +220,8 @@ class GenerateTaskPipeline:
|
|||||||
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()
|
||||||
@ -244,13 +253,14 @@ class GenerateTaskPipeline:
|
|||||||
'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):
|
||||||
@ -410,6 +420,86 @@ class GenerateTaskPipeline:
|
|||||||
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.
|
||||||
|
@ -151,6 +151,8 @@ def jsonable_encoder(
|
|||||||
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())
|
||||||
|
@ -31,6 +31,10 @@ class ExternalApi(Api):
|
|||||||
'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
|
||||||
|
@ -27,10 +27,15 @@ class CompletionService:
|
|||||||
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:
|
if app_model.mode != 'completion':
|
||||||
raise ValueError('query is required')
|
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
|
||||||
|
|
||||||
@ -230,6 +235,10 @@ class CompletionService:
|
|||||||
|
|
||||||
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:
|
||||||
@ -243,4 +252,3 @@ class CompletionService:
|
|||||||
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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user