model_providers.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. from flask_login import login_required, current_user
  2. from flask_restful import Resource, reqparse
  3. from werkzeug.exceptions import Forbidden
  4. from controllers.console import api
  5. from controllers.console.app.error import ProviderNotInitializeError
  6. from controllers.console.setup import setup_required
  7. from controllers.console.wraps import account_initialization_required
  8. from core.model_providers.error import LLMBadRequestError
  9. from core.model_providers.providers.base import CredentialsValidateFailedError
  10. from services.provider_checkout_service import ProviderCheckoutService
  11. from services.provider_service import ProviderService
  12. class ModelProviderListApi(Resource):
  13. @setup_required
  14. @login_required
  15. @account_initialization_required
  16. def get(self):
  17. tenant_id = current_user.current_tenant_id
  18. provider_service = ProviderService()
  19. provider_list = provider_service.get_provider_list(tenant_id)
  20. return provider_list
  21. class ModelProviderValidateApi(Resource):
  22. @setup_required
  23. @login_required
  24. @account_initialization_required
  25. def post(self, provider_name: str):
  26. parser = reqparse.RequestParser()
  27. parser.add_argument('config', type=dict, required=True, nullable=False, location='json')
  28. args = parser.parse_args()
  29. provider_service = ProviderService()
  30. result = True
  31. error = None
  32. try:
  33. provider_service.custom_provider_config_validate(
  34. provider_name=provider_name,
  35. config=args['config']
  36. )
  37. except CredentialsValidateFailedError as ex:
  38. result = False
  39. error = str(ex)
  40. response = {'result': 'success' if result else 'error'}
  41. if not result:
  42. response['error'] = error
  43. return response
  44. class ModelProviderUpdateApi(Resource):
  45. @setup_required
  46. @login_required
  47. @account_initialization_required
  48. def post(self, provider_name: str):
  49. if current_user.current_tenant.current_role not in ['admin', 'owner']:
  50. raise Forbidden()
  51. parser = reqparse.RequestParser()
  52. parser.add_argument('config', type=dict, required=True, nullable=False, location='json')
  53. args = parser.parse_args()
  54. provider_service = ProviderService()
  55. try:
  56. provider_service.save_custom_provider_config(
  57. tenant_id=current_user.current_tenant_id,
  58. provider_name=provider_name,
  59. config=args['config']
  60. )
  61. except CredentialsValidateFailedError as ex:
  62. raise ValueError(str(ex))
  63. return {'result': 'success'}, 201
  64. @setup_required
  65. @login_required
  66. @account_initialization_required
  67. def delete(self, provider_name: str):
  68. if current_user.current_tenant.current_role not in ['admin', 'owner']:
  69. raise Forbidden()
  70. provider_service = ProviderService()
  71. provider_service.delete_custom_provider(
  72. tenant_id=current_user.current_tenant_id,
  73. provider_name=provider_name
  74. )
  75. return {'result': 'success'}, 204
  76. class ModelProviderModelValidateApi(Resource):
  77. @setup_required
  78. @login_required
  79. @account_initialization_required
  80. def post(self, provider_name: str):
  81. parser = reqparse.RequestParser()
  82. parser.add_argument('model_name', type=str, required=True, nullable=False, location='json')
  83. parser.add_argument('model_type', type=str, required=True, nullable=False,
  84. choices=['text-generation', 'embeddings', 'speech2text'], location='json')
  85. parser.add_argument('config', type=dict, required=True, nullable=False, location='json')
  86. args = parser.parse_args()
  87. provider_service = ProviderService()
  88. result = True
  89. error = None
  90. try:
  91. provider_service.custom_provider_model_config_validate(
  92. provider_name=provider_name,
  93. model_name=args['model_name'],
  94. model_type=args['model_type'],
  95. config=args['config']
  96. )
  97. except CredentialsValidateFailedError as ex:
  98. result = False
  99. error = str(ex)
  100. response = {'result': 'success' if result else 'error'}
  101. if not result:
  102. response['error'] = error
  103. return response
  104. class ModelProviderModelUpdateApi(Resource):
  105. @setup_required
  106. @login_required
  107. @account_initialization_required
  108. def post(self, provider_name: str):
  109. if current_user.current_tenant.current_role not in ['admin', 'owner']:
  110. raise Forbidden()
  111. parser = reqparse.RequestParser()
  112. parser.add_argument('model_name', type=str, required=True, nullable=False, location='json')
  113. parser.add_argument('model_type', type=str, required=True, nullable=False,
  114. choices=['text-generation', 'embeddings', 'speech2text'], location='json')
  115. parser.add_argument('config', type=dict, required=True, nullable=False, location='json')
  116. args = parser.parse_args()
  117. provider_service = ProviderService()
  118. try:
  119. provider_service.add_or_save_custom_provider_model_config(
  120. tenant_id=current_user.current_tenant_id,
  121. provider_name=provider_name,
  122. model_name=args['model_name'],
  123. model_type=args['model_type'],
  124. config=args['config']
  125. )
  126. except CredentialsValidateFailedError as ex:
  127. raise ValueError(str(ex))
  128. return {'result': 'success'}, 200
  129. @setup_required
  130. @login_required
  131. @account_initialization_required
  132. def delete(self, provider_name: str):
  133. if current_user.current_tenant.current_role not in ['admin', 'owner']:
  134. raise Forbidden()
  135. parser = reqparse.RequestParser()
  136. parser.add_argument('model_name', type=str, required=True, nullable=False, location='args')
  137. parser.add_argument('model_type', type=str, required=True, nullable=False,
  138. choices=['text-generation', 'embeddings', 'speech2text'], location='args')
  139. args = parser.parse_args()
  140. provider_service = ProviderService()
  141. provider_service.delete_custom_provider_model(
  142. tenant_id=current_user.current_tenant_id,
  143. provider_name=provider_name,
  144. model_name=args['model_name'],
  145. model_type=args['model_type']
  146. )
  147. return {'result': 'success'}, 204
  148. class PreferredProviderTypeUpdateApi(Resource):
  149. @setup_required
  150. @login_required
  151. @account_initialization_required
  152. def post(self, provider_name: str):
  153. if current_user.current_tenant.current_role not in ['admin', 'owner']:
  154. raise Forbidden()
  155. parser = reqparse.RequestParser()
  156. parser.add_argument('preferred_provider_type', type=str, required=True, nullable=False,
  157. choices=['system', 'custom'], location='json')
  158. args = parser.parse_args()
  159. provider_service = ProviderService()
  160. provider_service.switch_preferred_provider(
  161. tenant_id=current_user.current_tenant_id,
  162. provider_name=provider_name,
  163. preferred_provider_type=args['preferred_provider_type']
  164. )
  165. return {'result': 'success'}
  166. class ModelProviderModelParameterRuleApi(Resource):
  167. @setup_required
  168. @login_required
  169. @account_initialization_required
  170. def get(self, provider_name: str):
  171. parser = reqparse.RequestParser()
  172. parser.add_argument('model_name', type=str, required=True, nullable=False, location='args')
  173. args = parser.parse_args()
  174. provider_service = ProviderService()
  175. try:
  176. parameter_rules = provider_service.get_model_parameter_rules(
  177. tenant_id=current_user.current_tenant_id,
  178. model_provider_name=provider_name,
  179. model_name=args['model_name'],
  180. model_type='text-generation'
  181. )
  182. except LLMBadRequestError:
  183. raise ProviderNotInitializeError(
  184. f"Current Text Generation Model is invalid. Please switch to the available model.")
  185. rules = {
  186. k: {
  187. 'enabled': v.enabled,
  188. 'min': v.min,
  189. 'max': v.max,
  190. 'default': v.default
  191. }
  192. for k, v in vars(parameter_rules).items()
  193. }
  194. return rules
  195. class ModelProviderPaymentCheckoutUrlApi(Resource):
  196. @setup_required
  197. @login_required
  198. @account_initialization_required
  199. def get(self, provider_name: str):
  200. provider_service = ProviderCheckoutService()
  201. provider_checkout = provider_service.create_checkout(
  202. tenant_id=current_user.current_tenant_id,
  203. provider_name=provider_name,
  204. account=current_user
  205. )
  206. return {
  207. 'url': provider_checkout.get_checkout_url()
  208. }
  209. class ModelProviderFreeQuotaSubmitApi(Resource):
  210. @setup_required
  211. @login_required
  212. @account_initialization_required
  213. def post(self, provider_name: str):
  214. provider_service = ProviderService()
  215. result = provider_service.free_quota_submit(
  216. tenant_id=current_user.current_tenant_id,
  217. provider_name=provider_name
  218. )
  219. return result
  220. api.add_resource(ModelProviderListApi, '/workspaces/current/model-providers')
  221. api.add_resource(ModelProviderValidateApi, '/workspaces/current/model-providers/<string:provider_name>/validate')
  222. api.add_resource(ModelProviderUpdateApi, '/workspaces/current/model-providers/<string:provider_name>')
  223. api.add_resource(ModelProviderModelValidateApi,
  224. '/workspaces/current/model-providers/<string:provider_name>/models/validate')
  225. api.add_resource(ModelProviderModelUpdateApi,
  226. '/workspaces/current/model-providers/<string:provider_name>/models')
  227. api.add_resource(PreferredProviderTypeUpdateApi,
  228. '/workspaces/current/model-providers/<string:provider_name>/preferred-provider-type')
  229. api.add_resource(ModelProviderModelParameterRuleApi,
  230. '/workspaces/current/model-providers/<string:provider_name>/models/parameter-rules')
  231. api.add_resource(ModelProviderPaymentCheckoutUrlApi,
  232. '/workspaces/current/model-providers/<string:provider_name>/checkout-url')
  233. api.add_resource(ModelProviderFreeQuotaSubmitApi,
  234. '/workspaces/current/model-providers/<string:provider_name>/free-quota-submit')