Feat: optimize error desc (#152)
This commit is contained in:
@@ -17,6 +17,6 @@ def _get_app(app_id, mode=None):
|
|||||||
raise NotFound("App not found")
|
raise NotFound("App not found")
|
||||||
|
|
||||||
if mode and app.mode != mode:
|
if mode and app.mode != mode:
|
||||||
raise AppUnavailableError()
|
raise NotFound("The {} app not found".format(mode))
|
||||||
|
|
||||||
return app
|
return app
|
||||||
|
@@ -9,31 +9,33 @@ class AppNotFoundError(BaseHTTPException):
|
|||||||
|
|
||||||
class ProviderNotInitializeError(BaseHTTPException):
|
class ProviderNotInitializeError(BaseHTTPException):
|
||||||
error_code = 'provider_not_initialize'
|
error_code = 'provider_not_initialize'
|
||||||
description = "Provider Token not initialize."
|
description = "No valid model provider credentials found. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderQuotaExceededError(BaseHTTPException):
|
class ProviderQuotaExceededError(BaseHTTPException):
|
||||||
error_code = 'provider_quota_exceeded'
|
error_code = 'provider_quota_exceeded'
|
||||||
description = "Provider quota exceeded."
|
description = "Your quota for Dify Hosted OpenAI has been exhausted. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your own provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
||||||
error_code = 'model_currently_not_support'
|
error_code = 'model_currently_not_support'
|
||||||
description = "GPT-4 currently not support."
|
description = "Dify Hosted OpenAI trial currently not support the GPT-4 model."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ConversationCompletedError(BaseHTTPException):
|
class ConversationCompletedError(BaseHTTPException):
|
||||||
error_code = 'conversation_completed'
|
error_code = 'conversation_completed'
|
||||||
description = "Conversation was completed."
|
description = "The conversation has ended. Please start a new conversation."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class AppUnavailableError(BaseHTTPException):
|
class AppUnavailableError(BaseHTTPException):
|
||||||
error_code = 'app_unavailable'
|
error_code = 'app_unavailable'
|
||||||
description = "App unavailable."
|
description = "App unavailable, please check your app configurations."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
@@ -45,5 +47,5 @@ class CompletionRequestError(BaseHTTPException):
|
|||||||
|
|
||||||
class AppMoreLikeThisDisabledError(BaseHTTPException):
|
class AppMoreLikeThisDisabledError(BaseHTTPException):
|
||||||
error_code = 'app_more_like_this_disabled'
|
error_code = 'app_more_like_this_disabled'
|
||||||
description = "More like this disabled."
|
description = "The 'More like this' feature is disabled. Please refresh your page."
|
||||||
code = 403
|
code = 403
|
||||||
|
@@ -10,13 +10,14 @@ from werkzeug.exceptions import NotFound, Forbidden
|
|||||||
|
|
||||||
import services
|
import services
|
||||||
from controllers.console import api
|
from controllers.console import api
|
||||||
from controllers.console.app.error import ProviderNotInitializeError
|
from controllers.console.app.error import ProviderNotInitializeError, ProviderQuotaExceededError, \
|
||||||
|
ProviderModelCurrentlyNotSupportError
|
||||||
from controllers.console.datasets.error import DocumentAlreadyFinishedError, InvalidActionError, DocumentIndexingError, \
|
from controllers.console.datasets.error import DocumentAlreadyFinishedError, InvalidActionError, DocumentIndexingError, \
|
||||||
InvalidMetadataError, ArchivedDocumentImmutableError
|
InvalidMetadataError, ArchivedDocumentImmutableError
|
||||||
from controllers.console.setup import setup_required
|
from controllers.console.setup import setup_required
|
||||||
from controllers.console.wraps import account_initialization_required
|
from controllers.console.wraps import account_initialization_required
|
||||||
from core.indexing_runner import IndexingRunner
|
from core.indexing_runner import IndexingRunner
|
||||||
from core.llm.error import ProviderTokenNotInitError
|
from core.llm.error import ProviderTokenNotInitError, QuotaExceededError, ModelCurrentlyNotSupportError
|
||||||
from extensions.ext_redis import redis_client
|
from extensions.ext_redis import redis_client
|
||||||
from libs.helper import TimestampField
|
from libs.helper import TimestampField
|
||||||
from extensions.ext_database import db
|
from extensions.ext_database import db
|
||||||
@@ -222,6 +223,10 @@ class DatasetDocumentListApi(Resource):
|
|||||||
document = DocumentService.save_document_with_dataset_id(dataset, args, current_user)
|
document = DocumentService.save_document_with_dataset_id(dataset, args, current_user)
|
||||||
except ProviderTokenNotInitError:
|
except ProviderTokenNotInitError:
|
||||||
raise ProviderNotInitializeError()
|
raise ProviderNotInitializeError()
|
||||||
|
except QuotaExceededError:
|
||||||
|
raise ProviderQuotaExceededError()
|
||||||
|
except ModelCurrentlyNotSupportError:
|
||||||
|
raise ProviderModelCurrentlyNotSupportError()
|
||||||
|
|
||||||
return document
|
return document
|
||||||
|
|
||||||
@@ -259,6 +264,10 @@ class DatasetInitApi(Resource):
|
|||||||
)
|
)
|
||||||
except ProviderTokenNotInitError:
|
except ProviderTokenNotInitError:
|
||||||
raise ProviderNotInitializeError()
|
raise ProviderNotInitializeError()
|
||||||
|
except QuotaExceededError:
|
||||||
|
raise ProviderQuotaExceededError()
|
||||||
|
except ModelCurrentlyNotSupportError:
|
||||||
|
raise ProviderModelCurrentlyNotSupportError()
|
||||||
|
|
||||||
response = {
|
response = {
|
||||||
'dataset': dataset,
|
'dataset': dataset,
|
||||||
|
@@ -3,7 +3,7 @@ from libs.exception import BaseHTTPException
|
|||||||
|
|
||||||
class NoFileUploadedError(BaseHTTPException):
|
class NoFileUploadedError(BaseHTTPException):
|
||||||
error_code = 'no_file_uploaded'
|
error_code = 'no_file_uploaded'
|
||||||
description = "No file uploaded."
|
description = "Please upload your file."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
@@ -27,25 +27,25 @@ class UnsupportedFileTypeError(BaseHTTPException):
|
|||||||
|
|
||||||
class HighQualityDatasetOnlyError(BaseHTTPException):
|
class HighQualityDatasetOnlyError(BaseHTTPException):
|
||||||
error_code = 'high_quality_dataset_only'
|
error_code = 'high_quality_dataset_only'
|
||||||
description = "High quality dataset only."
|
description = "Current operation only supports 'high-quality' datasets."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class DatasetNotInitializedError(BaseHTTPException):
|
class DatasetNotInitializedError(BaseHTTPException):
|
||||||
error_code = 'dataset_not_initialized'
|
error_code = 'dataset_not_initialized'
|
||||||
description = "Dataset not initialized."
|
description = "The dataset is still being initialized or indexing. Please wait a moment."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ArchivedDocumentImmutableError(BaseHTTPException):
|
class ArchivedDocumentImmutableError(BaseHTTPException):
|
||||||
error_code = 'archived_document_immutable'
|
error_code = 'archived_document_immutable'
|
||||||
description = "Cannot process an archived document."
|
description = "The archived document is not editable."
|
||||||
code = 403
|
code = 403
|
||||||
|
|
||||||
|
|
||||||
class DatasetNameDuplicateError(BaseHTTPException):
|
class DatasetNameDuplicateError(BaseHTTPException):
|
||||||
error_code = 'dataset_name_duplicate'
|
error_code = 'dataset_name_duplicate'
|
||||||
description = "Dataset name already exists."
|
description = "The dataset name already exists. Please modify your dataset name."
|
||||||
code = 409
|
code = 409
|
||||||
|
|
||||||
|
|
||||||
@@ -57,17 +57,17 @@ class InvalidActionError(BaseHTTPException):
|
|||||||
|
|
||||||
class DocumentAlreadyFinishedError(BaseHTTPException):
|
class DocumentAlreadyFinishedError(BaseHTTPException):
|
||||||
error_code = 'document_already_finished'
|
error_code = 'document_already_finished'
|
||||||
description = "Document already finished."
|
description = "The document has been processed. Please refresh the page or go to the document details."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class DocumentIndexingError(BaseHTTPException):
|
class DocumentIndexingError(BaseHTTPException):
|
||||||
error_code = 'document_indexing'
|
error_code = 'document_indexing'
|
||||||
description = "Document indexing."
|
description = "The document is being processed and cannot be edited."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class InvalidMetadataError(BaseHTTPException):
|
class InvalidMetadataError(BaseHTTPException):
|
||||||
error_code = 'invalid_metadata'
|
error_code = 'invalid_metadata'
|
||||||
description = "Invalid metadata."
|
description = "The metadata content is incorrect. Please check and verify."
|
||||||
code = 400
|
code = 400
|
||||||
|
@@ -6,9 +6,12 @@ from werkzeug.exceptions import InternalServerError, NotFound, Forbidden
|
|||||||
|
|
||||||
import services
|
import services
|
||||||
from controllers.console import api
|
from controllers.console import api
|
||||||
|
from controllers.console.app.error import ProviderNotInitializeError, ProviderQuotaExceededError, \
|
||||||
|
ProviderModelCurrentlyNotSupportError
|
||||||
from controllers.console.datasets.error import HighQualityDatasetOnlyError, DatasetNotInitializedError
|
from controllers.console.datasets.error import HighQualityDatasetOnlyError, DatasetNotInitializedError
|
||||||
from controllers.console.setup import setup_required
|
from controllers.console.setup import setup_required
|
||||||
from controllers.console.wraps import account_initialization_required
|
from controllers.console.wraps import account_initialization_required
|
||||||
|
from core.llm.error import ProviderTokenNotInitError, QuotaExceededError, ModelCurrentlyNotSupportError
|
||||||
from libs.helper import TimestampField
|
from libs.helper import TimestampField
|
||||||
from services.dataset_service import DatasetService
|
from services.dataset_service import DatasetService
|
||||||
from services.hit_testing_service import HitTestingService
|
from services.hit_testing_service import HitTestingService
|
||||||
@@ -92,6 +95,12 @@ class HitTestingApi(Resource):
|
|||||||
return {"query": response['query'], 'records': marshal(response['records'], hit_testing_record_fields)}
|
return {"query": response['query'], 'records': marshal(response['records'], hit_testing_record_fields)}
|
||||||
except services.errors.index.IndexNotInitializedError:
|
except services.errors.index.IndexNotInitializedError:
|
||||||
raise DatasetNotInitializedError()
|
raise DatasetNotInitializedError()
|
||||||
|
except ProviderTokenNotInitError:
|
||||||
|
raise ProviderNotInitializeError()
|
||||||
|
except QuotaExceededError:
|
||||||
|
raise ProviderQuotaExceededError()
|
||||||
|
except ModelCurrentlyNotSupportError:
|
||||||
|
raise ProviderModelCurrentlyNotSupportError()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("Hit testing failed.")
|
logging.exception("Hit testing failed.")
|
||||||
raise InternalServerError(str(e))
|
raise InternalServerError(str(e))
|
||||||
|
@@ -3,13 +3,14 @@ from libs.exception import BaseHTTPException
|
|||||||
|
|
||||||
class AlreadySetupError(BaseHTTPException):
|
class AlreadySetupError(BaseHTTPException):
|
||||||
error_code = 'already_setup'
|
error_code = 'already_setup'
|
||||||
description = "Application already setup."
|
description = "Dify has been successfully installed. Please refresh the page or return to the dashboard homepage."
|
||||||
code = 403
|
code = 403
|
||||||
|
|
||||||
|
|
||||||
class NotSetupError(BaseHTTPException):
|
class NotSetupError(BaseHTTPException):
|
||||||
error_code = 'not_setup'
|
error_code = 'not_setup'
|
||||||
description = "Application not setup."
|
description = "Dify has not been initialized and installed yet. " \
|
||||||
|
"Please proceed with the initialization and installation process first."
|
||||||
code = 401
|
code = 401
|
||||||
|
|
||||||
|
|
||||||
|
@@ -21,11 +21,11 @@ class InvalidInvitationCodeError(BaseHTTPException):
|
|||||||
|
|
||||||
class AccountAlreadyInitedError(BaseHTTPException):
|
class AccountAlreadyInitedError(BaseHTTPException):
|
||||||
error_code = 'account_already_inited'
|
error_code = 'account_already_inited'
|
||||||
description = "Account already inited."
|
description = "The account has been initialized. Please refresh the page."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class AccountNotInitializedError(BaseHTTPException):
|
class AccountNotInitializedError(BaseHTTPException):
|
||||||
error_code = 'account_not_initialized'
|
error_code = 'account_not_initialized'
|
||||||
description = "Account not initialized."
|
description = "The account has not been initialized yet. Please proceed with the initialization process first."
|
||||||
code = 400
|
code = 400
|
||||||
|
@@ -90,8 +90,8 @@ class ProviderTokenApi(Resource):
|
|||||||
configs=args['token']
|
configs=args['token']
|
||||||
)
|
)
|
||||||
token_is_valid = True
|
token_is_valid = True
|
||||||
except ValidateFailedError:
|
except ValidateFailedError as ex:
|
||||||
token_is_valid = False
|
raise ValueError(str(ex))
|
||||||
|
|
||||||
base64_encrypted_token = ProviderService.get_encrypted_token(
|
base64_encrypted_token = ProviderService.get_encrypted_token(
|
||||||
tenant=current_user.current_tenant,
|
tenant=current_user.current_tenant,
|
||||||
|
@@ -4,43 +4,45 @@ from libs.exception import BaseHTTPException
|
|||||||
|
|
||||||
class AppUnavailableError(BaseHTTPException):
|
class AppUnavailableError(BaseHTTPException):
|
||||||
error_code = 'app_unavailable'
|
error_code = 'app_unavailable'
|
||||||
description = "App unavailable."
|
description = "App unavailable, please check your app configurations."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class NotCompletionAppError(BaseHTTPException):
|
class NotCompletionAppError(BaseHTTPException):
|
||||||
error_code = 'not_completion_app'
|
error_code = 'not_completion_app'
|
||||||
description = "Not Completion App"
|
description = "Please check if your Completion app mode matches the right API route."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class NotChatAppError(BaseHTTPException):
|
class NotChatAppError(BaseHTTPException):
|
||||||
error_code = 'not_chat_app'
|
error_code = 'not_chat_app'
|
||||||
description = "Not Chat App"
|
description = "Please check if your Chat app mode matches the right API route."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ConversationCompletedError(BaseHTTPException):
|
class ConversationCompletedError(BaseHTTPException):
|
||||||
error_code = 'conversation_completed'
|
error_code = 'conversation_completed'
|
||||||
description = "Conversation Completed."
|
description = "The conversation has ended. Please start a new conversation."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderNotInitializeError(BaseHTTPException):
|
class ProviderNotInitializeError(BaseHTTPException):
|
||||||
error_code = 'provider_not_initialize'
|
error_code = 'provider_not_initialize'
|
||||||
description = "Provider Token not initialize."
|
description = "No valid model provider credentials found. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderQuotaExceededError(BaseHTTPException):
|
class ProviderQuotaExceededError(BaseHTTPException):
|
||||||
error_code = 'provider_quota_exceeded'
|
error_code = 'provider_quota_exceeded'
|
||||||
description = "Provider quota exceeded."
|
description = "Your quota for Dify Hosted OpenAI has been exhausted. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your own provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
||||||
error_code = 'model_currently_not_support'
|
error_code = 'model_currently_not_support'
|
||||||
description = "GPT-4 currently not support."
|
description = "Dify Hosted OpenAI trial currently not support the GPT-4 model."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
|
@@ -16,5 +16,5 @@ class DocumentIndexingError(BaseHTTPException):
|
|||||||
|
|
||||||
class DatasetNotInitedError(BaseHTTPException):
|
class DatasetNotInitedError(BaseHTTPException):
|
||||||
error_code = 'dataset_not_inited'
|
error_code = 'dataset_not_inited'
|
||||||
description = "Dataset not inited."
|
description = "The dataset is still being initialized or indexing. Please wait a moment."
|
||||||
code = 403
|
code = 403
|
||||||
|
@@ -4,43 +4,45 @@ from libs.exception import BaseHTTPException
|
|||||||
|
|
||||||
class AppUnavailableError(BaseHTTPException):
|
class AppUnavailableError(BaseHTTPException):
|
||||||
error_code = 'app_unavailable'
|
error_code = 'app_unavailable'
|
||||||
description = "App unavailable."
|
description = "App unavailable, please check your app configurations."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class NotCompletionAppError(BaseHTTPException):
|
class NotCompletionAppError(BaseHTTPException):
|
||||||
error_code = 'not_completion_app'
|
error_code = 'not_completion_app'
|
||||||
description = "Not Completion App"
|
description = "Please check if your Completion app mode matches the right API route."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class NotChatAppError(BaseHTTPException):
|
class NotChatAppError(BaseHTTPException):
|
||||||
error_code = 'not_chat_app'
|
error_code = 'not_chat_app'
|
||||||
description = "Not Chat App"
|
description = "Please check if your Chat app mode matches the right API route."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ConversationCompletedError(BaseHTTPException):
|
class ConversationCompletedError(BaseHTTPException):
|
||||||
error_code = 'conversation_completed'
|
error_code = 'conversation_completed'
|
||||||
description = "Conversation Completed."
|
description = "The conversation has ended. Please start a new conversation."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderNotInitializeError(BaseHTTPException):
|
class ProviderNotInitializeError(BaseHTTPException):
|
||||||
error_code = 'provider_not_initialize'
|
error_code = 'provider_not_initialize'
|
||||||
description = "Provider Token not initialize."
|
description = "No valid model provider credentials found. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderQuotaExceededError(BaseHTTPException):
|
class ProviderQuotaExceededError(BaseHTTPException):
|
||||||
error_code = 'provider_quota_exceeded'
|
error_code = 'provider_quota_exceeded'
|
||||||
description = "Provider quota exceeded."
|
description = "Your quota for Dify Hosted OpenAI has been exhausted. " \
|
||||||
|
"Please go to Settings -> Model Provider to complete your own provider credentials."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
class ProviderModelCurrentlyNotSupportError(BaseHTTPException):
|
||||||
error_code = 'model_currently_not_support'
|
error_code = 'model_currently_not_support'
|
||||||
description = "GPT-4 currently not support."
|
description = "Dify Hosted OpenAI trial currently not support the GPT-4 model."
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
|
||||||
@@ -52,11 +54,11 @@ class CompletionRequestError(BaseHTTPException):
|
|||||||
|
|
||||||
class AppMoreLikeThisDisabledError(BaseHTTPException):
|
class AppMoreLikeThisDisabledError(BaseHTTPException):
|
||||||
error_code = 'app_more_like_this_disabled'
|
error_code = 'app_more_like_this_disabled'
|
||||||
description = "More like this disabled."
|
description = "The 'More like this' feature is disabled. Please refresh your page."
|
||||||
code = 403
|
code = 403
|
||||||
|
|
||||||
|
|
||||||
class AppSuggestedQuestionsAfterAnswerDisabledError(BaseHTTPException):
|
class AppSuggestedQuestionsAfterAnswerDisabledError(BaseHTTPException):
|
||||||
error_code = 'app_suggested_questions_after_answer_disabled'
|
error_code = 'app_suggested_questions_after_answer_disabled'
|
||||||
description = "Function Suggested questions after answer disabled."
|
description = "The 'Suggested Questions After Answer' feature is disabled. Please refresh your page."
|
||||||
code = 403
|
code = 403
|
||||||
|
@@ -46,3 +46,15 @@ class IndexBuilder:
|
|||||||
prompt_helper=prompt_helper,
|
prompt_helper=prompt_helper,
|
||||||
embed_model=OpenAIEmbedding(**model_credentials),
|
embed_model=OpenAIEmbedding(**model_credentials),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_fake_llm_service_context(cls, tenant_id: str) -> ServiceContext:
|
||||||
|
llm = LLMBuilder.to_llm(
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
model_name='fake'
|
||||||
|
)
|
||||||
|
|
||||||
|
return ServiceContext.from_defaults(
|
||||||
|
llm_predictor=LLMPredictor(llm=llm),
|
||||||
|
embed_model=OpenAIEmbedding()
|
||||||
|
)
|
||||||
|
@@ -83,7 +83,7 @@ class VectorIndex:
|
|||||||
if not self._dataset.index_struct_dict:
|
if not self._dataset.index_struct_dict:
|
||||||
return
|
return
|
||||||
|
|
||||||
service_context = IndexBuilder.get_default_service_context(tenant_id=self._dataset.tenant_id)
|
service_context = IndexBuilder.get_fake_llm_service_context(tenant_id=self._dataset.tenant_id)
|
||||||
|
|
||||||
index = vector_store.get_index(
|
index = vector_store.get_index(
|
||||||
service_context=service_context,
|
service_context=service_context,
|
||||||
@@ -101,7 +101,7 @@ class VectorIndex:
|
|||||||
if not self._dataset.index_struct_dict:
|
if not self._dataset.index_struct_dict:
|
||||||
return
|
return
|
||||||
|
|
||||||
service_context = IndexBuilder.get_default_service_context(tenant_id=self._dataset.tenant_id)
|
service_context = IndexBuilder.get_fake_llm_service_context(tenant_id=self._dataset.tenant_id)
|
||||||
|
|
||||||
index = vector_store.get_index(
|
index = vector_store.get_index(
|
||||||
service_context=service_context,
|
service_context=service_context,
|
||||||
|
@@ -1,22 +1,24 @@
|
|||||||
import json
|
import json
|
||||||
|
import logging
|
||||||
from typing import Optional, Union
|
from typing import Optional, Union
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from core.llm.provider.base import BaseProvider
|
from core.llm.provider.base import BaseProvider
|
||||||
|
from core.llm.provider.errors import ValidateFailedError
|
||||||
from models.provider import ProviderName
|
from models.provider import ProviderName
|
||||||
|
|
||||||
|
|
||||||
class AzureProvider(BaseProvider):
|
class AzureProvider(BaseProvider):
|
||||||
def get_models(self, model_id: Optional[str] = None) -> list[dict]:
|
def get_models(self, model_id: Optional[str] = None, credentials: Optional[dict] = None) -> list[dict]:
|
||||||
credentials = self.get_credentials(model_id)
|
credentials = self.get_credentials(model_id) if not credentials else credentials
|
||||||
url = "{}/openai/deployments?api-version={}".format(
|
url = "{}/openai/deployments?api-version={}".format(
|
||||||
credentials.get('openai_api_base'),
|
str(credentials.get('openai_api_base')),
|
||||||
credentials.get('openai_api_version')
|
str(credentials.get('openai_api_version'))
|
||||||
)
|
)
|
||||||
|
|
||||||
headers = {
|
headers = {
|
||||||
"api-key": credentials.get('openai_api_key'),
|
"api-key": str(credentials.get('openai_api_key')),
|
||||||
"content-type": "application/json; charset=utf-8"
|
"content-type": "application/json; charset=utf-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,8 +31,10 @@ class AzureProvider(BaseProvider):
|
|||||||
'name': '{} ({})'.format(deployment['id'], deployment['model'])
|
'name': '{} ({})'.format(deployment['id'], deployment['model'])
|
||||||
} for deployment in result['data'] if deployment['status'] == 'succeeded']
|
} for deployment in result['data'] if deployment['status'] == 'succeeded']
|
||||||
else:
|
else:
|
||||||
# TODO: optimize in future
|
if response.status_code == 401:
|
||||||
raise Exception('Failed to get deployments from Azure OpenAI. Status code: {}'.format(response.status_code))
|
raise AzureAuthenticationError()
|
||||||
|
else:
|
||||||
|
raise AzureRequestFailedError('Failed to request Azure OpenAI. Status code: {}'.format(response.status_code))
|
||||||
|
|
||||||
def get_credentials(self, model_id: Optional[str] = None) -> dict:
|
def get_credentials(self, model_id: Optional[str] = None) -> dict:
|
||||||
"""
|
"""
|
||||||
@@ -38,7 +42,7 @@ class AzureProvider(BaseProvider):
|
|||||||
"""
|
"""
|
||||||
config = self.get_provider_api_key(model_id=model_id)
|
config = self.get_provider_api_key(model_id=model_id)
|
||||||
config['openai_api_type'] = 'azure'
|
config['openai_api_type'] = 'azure'
|
||||||
config['deployment_name'] = model_id.replace('.', '')
|
config['deployment_name'] = model_id.replace('.', '') if model_id else None
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def get_provider_name(self):
|
def get_provider_name(self):
|
||||||
@@ -54,7 +58,7 @@ class AzureProvider(BaseProvider):
|
|||||||
config = {
|
config = {
|
||||||
'openai_api_type': 'azure',
|
'openai_api_type': 'azure',
|
||||||
'openai_api_version': '2023-03-15-preview',
|
'openai_api_version': '2023-03-15-preview',
|
||||||
'openai_api_base': 'https://<your-domain-prefix>.openai.azure.com/',
|
'openai_api_base': '',
|
||||||
'openai_api_key': ''
|
'openai_api_key': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +67,7 @@ class AzureProvider(BaseProvider):
|
|||||||
config = {
|
config = {
|
||||||
'openai_api_type': 'azure',
|
'openai_api_type': 'azure',
|
||||||
'openai_api_version': '2023-03-15-preview',
|
'openai_api_version': '2023-03-15-preview',
|
||||||
'openai_api_base': 'https://<your-domain-prefix>.openai.azure.com/',
|
'openai_api_base': '',
|
||||||
'openai_api_key': ''
|
'openai_api_key': ''
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,8 +84,23 @@ class AzureProvider(BaseProvider):
|
|||||||
"""
|
"""
|
||||||
Validates the given config.
|
Validates the given config.
|
||||||
"""
|
"""
|
||||||
# TODO: implement
|
try:
|
||||||
pass
|
if not isinstance(config, dict):
|
||||||
|
raise ValueError('Config must be a object.')
|
||||||
|
|
||||||
|
if 'openai_api_version' not in config:
|
||||||
|
config['openai_api_version'] = '2023-03-15-preview'
|
||||||
|
|
||||||
|
self.get_models(credentials=config)
|
||||||
|
except AzureAuthenticationError:
|
||||||
|
raise ValidateFailedError('Azure OpenAI Credentials validation failed, please check your API Key.')
|
||||||
|
except requests.ConnectionError:
|
||||||
|
raise ValidateFailedError('Azure OpenAI Credentials validation failed, please check your API Base Endpoint.')
|
||||||
|
except AzureRequestFailedError as ex:
|
||||||
|
raise ValidateFailedError('Azure OpenAI Credentials validation failed, error: {}.'.format(str(ex)))
|
||||||
|
except Exception as ex:
|
||||||
|
logging.exception('Azure OpenAI Credentials validation failed')
|
||||||
|
raise ex
|
||||||
|
|
||||||
def get_encrypted_token(self, config: Union[dict | str]):
|
def get_encrypted_token(self, config: Union[dict | str]):
|
||||||
"""
|
"""
|
||||||
@@ -101,3 +120,11 @@ class AzureProvider(BaseProvider):
|
|||||||
config = json.loads(token)
|
config = json.loads(token)
|
||||||
config['openai_api_key'] = self.decrypt_token(config['openai_api_key'])
|
config['openai_api_key'] = self.decrypt_token(config['openai_api_key'])
|
||||||
return config
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
class AzureAuthenticationError(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AzureRequestFailedError(Exception):
|
||||||
|
pass
|
||||||
|
@@ -149,7 +149,7 @@ const translation = {
|
|||||||
invalidApiKey: 'Invalid API key',
|
invalidApiKey: 'Invalid API key',
|
||||||
azure: {
|
azure: {
|
||||||
apiBase: 'API Base',
|
apiBase: 'API Base',
|
||||||
apiBasePlaceholder: 'The API Base URL of your Azure OpenAI Resource.',
|
apiBasePlaceholder: 'The API Base URL of your Azure OpenAI Endpoint.',
|
||||||
apiKey: 'API Key',
|
apiKey: 'API Key',
|
||||||
apiKeyPlaceholder: 'Enter your API key here',
|
apiKeyPlaceholder: 'Enter your API key here',
|
||||||
helpTip: 'Learn Azure OpenAI Service',
|
helpTip: 'Learn Azure OpenAI Service',
|
||||||
|
Reference in New Issue
Block a user