| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303 | from flask_login import current_userfrom core.login.login import login_requiredfrom flask_restful import Resource, reqparsefrom werkzeug.exceptions import Forbiddenfrom controllers.console import apifrom controllers.console.app.error import ProviderNotInitializeErrorfrom controllers.console.setup import setup_requiredfrom controllers.console.wraps import account_initialization_requiredfrom core.model_providers.error import LLMBadRequestErrorfrom core.model_providers.providers.base import CredentialsValidateFailedErrorfrom services.provider_checkout_service import ProviderCheckoutServicefrom services.provider_service import ProviderServiceclass ModelProviderListApi(Resource):    @setup_required    @login_required    @account_initialization_required    def get(self):        tenant_id = current_user.current_tenant_id        provider_service = ProviderService()        provider_list = provider_service.get_provider_list(tenant_id)        return provider_listclass ModelProviderValidateApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        parser = reqparse.RequestParser()        parser.add_argument('config', type=dict, required=True, nullable=False, location='json')        args = parser.parse_args()        provider_service = ProviderService()        result = True        error = None        try:            provider_service.custom_provider_config_validate(                provider_name=provider_name,                config=args['config']            )        except CredentialsValidateFailedError as ex:            result = False            error = str(ex)        response = {'result': 'success' if result else 'error'}        if not result:            response['error'] = error        return responseclass ModelProviderUpdateApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        if current_user.current_tenant.current_role not in ['admin', 'owner']:            raise Forbidden()        parser = reqparse.RequestParser()        parser.add_argument('config', type=dict, required=True, nullable=False, location='json')        args = parser.parse_args()        provider_service = ProviderService()        try:            provider_service.save_custom_provider_config(                tenant_id=current_user.current_tenant_id,                provider_name=provider_name,                config=args['config']            )        except CredentialsValidateFailedError as ex:            raise ValueError(str(ex))        return {'result': 'success'}, 201    @setup_required    @login_required    @account_initialization_required    def delete(self, provider_name: str):        if current_user.current_tenant.current_role not in ['admin', 'owner']:            raise Forbidden()        provider_service = ProviderService()        provider_service.delete_custom_provider(            tenant_id=current_user.current_tenant_id,            provider_name=provider_name        )        return {'result': 'success'}, 204class ModelProviderModelValidateApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        parser = reqparse.RequestParser()        parser.add_argument('model_name', type=str, required=True, nullable=False, location='json')        parser.add_argument('model_type', type=str, required=True, nullable=False,                            choices=['text-generation', 'embeddings', 'speech2text'], location='json')        parser.add_argument('config', type=dict, required=True, nullable=False, location='json')        args = parser.parse_args()        provider_service = ProviderService()        result = True        error = None        try:            provider_service.custom_provider_model_config_validate(                provider_name=provider_name,                model_name=args['model_name'],                model_type=args['model_type'],                config=args['config']            )        except CredentialsValidateFailedError as ex:            result = False            error = str(ex)        response = {'result': 'success' if result else 'error'}        if not result:            response['error'] = error        return responseclass ModelProviderModelUpdateApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        if current_user.current_tenant.current_role not in ['admin', 'owner']:            raise Forbidden()        parser = reqparse.RequestParser()        parser.add_argument('model_name', type=str, required=True, nullable=False, location='json')        parser.add_argument('model_type', type=str, required=True, nullable=False,                            choices=['text-generation', 'embeddings', 'speech2text'], location='json')        parser.add_argument('config', type=dict, required=True, nullable=False, location='json')        args = parser.parse_args()        provider_service = ProviderService()        try:            provider_service.add_or_save_custom_provider_model_config(                tenant_id=current_user.current_tenant_id,                provider_name=provider_name,                model_name=args['model_name'],                model_type=args['model_type'],                config=args['config']            )        except CredentialsValidateFailedError as ex:            raise ValueError(str(ex))        return {'result': 'success'}, 200    @setup_required    @login_required    @account_initialization_required    def delete(self, provider_name: str):        if current_user.current_tenant.current_role not in ['admin', 'owner']:            raise Forbidden()        parser = reqparse.RequestParser()        parser.add_argument('model_name', type=str, required=True, nullable=False, location='args')        parser.add_argument('model_type', type=str, required=True, nullable=False,                            choices=['text-generation', 'embeddings', 'speech2text'], location='args')        args = parser.parse_args()        provider_service = ProviderService()        provider_service.delete_custom_provider_model(            tenant_id=current_user.current_tenant_id,            provider_name=provider_name,            model_name=args['model_name'],            model_type=args['model_type']        )        return {'result': 'success'}, 204class PreferredProviderTypeUpdateApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        if current_user.current_tenant.current_role not in ['admin', 'owner']:            raise Forbidden()        parser = reqparse.RequestParser()        parser.add_argument('preferred_provider_type', type=str, required=True, nullable=False,                            choices=['system', 'custom'], location='json')        args = parser.parse_args()        provider_service = ProviderService()        provider_service.switch_preferred_provider(            tenant_id=current_user.current_tenant_id,            provider_name=provider_name,            preferred_provider_type=args['preferred_provider_type']        )        return {'result': 'success'}class ModelProviderModelParameterRuleApi(Resource):    @setup_required    @login_required    @account_initialization_required    def get(self, provider_name: str):        parser = reqparse.RequestParser()        parser.add_argument('model_name', type=str, required=True, nullable=False, location='args')        args = parser.parse_args()        provider_service = ProviderService()        try:            parameter_rules = provider_service.get_model_parameter_rules(                tenant_id=current_user.current_tenant_id,                model_provider_name=provider_name,                model_name=args['model_name'],                model_type='text-generation'            )        except LLMBadRequestError:            raise ProviderNotInitializeError(                f"Current Text Generation Model is invalid. Please switch to the available model.")        rules = {            k: {                'enabled': v.enabled,                'min': v.min,                'max': v.max,                'default': v.default            }            for k, v in vars(parameter_rules).items()        }        return rulesclass ModelProviderPaymentCheckoutUrlApi(Resource):    @setup_required    @login_required    @account_initialization_required    def get(self, provider_name: str):        provider_service = ProviderCheckoutService()        provider_checkout = provider_service.create_checkout(            tenant_id=current_user.current_tenant_id,            provider_name=provider_name,            account=current_user        )        return {            'url': provider_checkout.get_checkout_url()        }class ModelProviderFreeQuotaSubmitApi(Resource):    @setup_required    @login_required    @account_initialization_required    def post(self, provider_name: str):        provider_service = ProviderService()        result = provider_service.free_quota_submit(            tenant_id=current_user.current_tenant_id,            provider_name=provider_name        )        return resultapi.add_resource(ModelProviderListApi, '/workspaces/current/model-providers')api.add_resource(ModelProviderValidateApi, '/workspaces/current/model-providers/<string:provider_name>/validate')api.add_resource(ModelProviderUpdateApi, '/workspaces/current/model-providers/<string:provider_name>')api.add_resource(ModelProviderModelValidateApi,                 '/workspaces/current/model-providers/<string:provider_name>/models/validate')api.add_resource(ModelProviderModelUpdateApi,                 '/workspaces/current/model-providers/<string:provider_name>/models')api.add_resource(PreferredProviderTypeUpdateApi,                 '/workspaces/current/model-providers/<string:provider_name>/preferred-provider-type')api.add_resource(ModelProviderModelParameterRuleApi,                 '/workspaces/current/model-providers/<string:provider_name>/models/parameter-rules')api.add_resource(ModelProviderPaymentCheckoutUrlApi,                 '/workspaces/current/model-providers/<string:provider_name>/checkout-url')api.add_resource(ModelProviderFreeQuotaSubmitApi,                 '/workspaces/current/model-providers/<string:provider_name>/free-quota-submit')
 |