provider_service.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. import datetime
  2. import json
  3. from collections import defaultdict
  4. from typing import Optional
  5. from core.model_providers.model_factory import ModelFactory
  6. from extensions.ext_database import db
  7. from core.model_providers.model_provider_factory import ModelProviderFactory
  8. from core.model_providers.models.entity.model_params import ModelType, ModelKwargsRules
  9. from models.provider import Provider, ProviderModel, TenantPreferredModelProvider, ProviderType, ProviderQuotaType, \
  10. TenantDefaultModel
  11. class ProviderService:
  12. def get_provider_list(self, tenant_id: str):
  13. """
  14. get provider list of tenant.
  15. :param tenant_id:
  16. :return:
  17. """
  18. # get rules for all providers
  19. model_provider_rules = ModelProviderFactory.get_provider_rules()
  20. model_provider_names = [model_provider_name for model_provider_name, _ in model_provider_rules.items()]
  21. for model_provider_name, model_provider_rule in model_provider_rules.items():
  22. if ProviderType.SYSTEM.value in model_provider_rule['support_provider_types'] \
  23. and 'system_config' in model_provider_rule and model_provider_rule['system_config'] \
  24. and 'supported_quota_types' in model_provider_rule['system_config'] \
  25. and 'trial' in model_provider_rule['system_config']['supported_quota_types']:
  26. ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  27. configurable_model_provider_names = [
  28. model_provider_name
  29. for model_provider_name, model_provider_rules in model_provider_rules.items()
  30. if 'custom' in model_provider_rules['support_provider_types']
  31. and model_provider_rules['model_flexibility'] == 'configurable'
  32. ]
  33. # get all providers for the tenant
  34. providers = db.session.query(Provider) \
  35. .filter(
  36. Provider.tenant_id == tenant_id,
  37. Provider.provider_name.in_(model_provider_names),
  38. Provider.is_valid == True
  39. ).order_by(Provider.created_at.desc()).all()
  40. provider_name_to_provider_dict = defaultdict(list)
  41. for provider in providers:
  42. provider_name_to_provider_dict[provider.provider_name].append(provider)
  43. # get all configurable provider models for the tenant
  44. provider_models = db.session.query(ProviderModel) \
  45. .filter(
  46. ProviderModel.tenant_id == tenant_id,
  47. ProviderModel.provider_name.in_(configurable_model_provider_names),
  48. ProviderModel.is_valid == True
  49. ).order_by(ProviderModel.created_at.desc()).all()
  50. provider_name_to_provider_model_dict = defaultdict(list)
  51. for provider_model in provider_models:
  52. provider_name_to_provider_model_dict[provider_model.provider_name].append(provider_model)
  53. # get all preferred provider type for the tenant
  54. preferred_provider_types = db.session.query(TenantPreferredModelProvider) \
  55. .filter(
  56. TenantPreferredModelProvider.tenant_id == tenant_id,
  57. TenantPreferredModelProvider.provider_name.in_(model_provider_names)
  58. ).all()
  59. provider_name_to_preferred_provider_type_dict = {preferred_provider_type.provider_name: preferred_provider_type
  60. for preferred_provider_type in preferred_provider_types}
  61. providers_list = {}
  62. for model_provider_name, model_provider_rule in model_provider_rules.items():
  63. # get preferred provider type
  64. preferred_model_provider = provider_name_to_preferred_provider_type_dict.get(model_provider_name)
  65. preferred_provider_type = ModelProviderFactory.get_preferred_type_by_preferred_model_provider(
  66. tenant_id,
  67. model_provider_name,
  68. preferred_model_provider
  69. )
  70. provider_config_dict = {
  71. "preferred_provider_type": preferred_provider_type,
  72. "model_flexibility": model_provider_rule['model_flexibility'],
  73. }
  74. provider_parameter_dict = {}
  75. if ProviderType.SYSTEM.value in model_provider_rule['support_provider_types']:
  76. for quota_type_enum in ProviderQuotaType:
  77. quota_type = quota_type_enum.value
  78. if quota_type in model_provider_rule['system_config']['supported_quota_types']:
  79. key = ProviderType.SYSTEM.value + ':' + quota_type
  80. provider_parameter_dict[key] = {
  81. "provider_name": model_provider_name,
  82. "provider_type": ProviderType.SYSTEM.value,
  83. "config": None,
  84. "is_valid": False, # need update
  85. "quota_type": quota_type,
  86. "quota_unit": model_provider_rule['system_config']['quota_unit'], # need update
  87. "quota_limit": 0 if quota_type != ProviderQuotaType.TRIAL.value else
  88. model_provider_rule['system_config']['quota_limit'], # need update
  89. "quota_used": 0, # need update
  90. "last_used": None # need update
  91. }
  92. if ProviderType.CUSTOM.value in model_provider_rule['support_provider_types']:
  93. provider_parameter_dict[ProviderType.CUSTOM.value] = {
  94. "provider_name": model_provider_name,
  95. "provider_type": ProviderType.CUSTOM.value,
  96. "config": None, # need update
  97. "models": [], # need update
  98. "is_valid": False,
  99. "last_used": None # need update
  100. }
  101. model_provider_class = ModelProviderFactory.get_model_provider_class(model_provider_name)
  102. current_providers = provider_name_to_provider_dict[model_provider_name]
  103. for provider in current_providers:
  104. if provider.provider_type == ProviderType.SYSTEM.value:
  105. quota_type = provider.quota_type
  106. key = f'{ProviderType.SYSTEM.value}:{quota_type}'
  107. if key in provider_parameter_dict:
  108. provider_parameter_dict[key]['is_valid'] = provider.is_valid
  109. provider_parameter_dict[key]['quota_used'] = provider.quota_used
  110. provider_parameter_dict[key]['quota_limit'] = provider.quota_limit
  111. provider_parameter_dict[key]['last_used'] = provider.last_used
  112. elif provider.provider_type == ProviderType.CUSTOM.value \
  113. and ProviderType.CUSTOM.value in provider_parameter_dict:
  114. # if custom
  115. key = ProviderType.CUSTOM.value
  116. provider_parameter_dict[key]['last_used'] = provider.last_used
  117. provider_parameter_dict[key]['is_valid'] = provider.is_valid
  118. if model_provider_rule['model_flexibility'] == 'fixed':
  119. provider_parameter_dict[key]['config'] = model_provider_class(provider=provider) \
  120. .get_provider_credentials(obfuscated=True)
  121. else:
  122. models = []
  123. provider_models = provider_name_to_provider_model_dict[model_provider_name]
  124. for provider_model in provider_models:
  125. models.append({
  126. "model_name": provider_model.model_name,
  127. "model_type": provider_model.model_type,
  128. "config": model_provider_class(provider=provider) \
  129. .get_model_credentials(provider_model.model_name,
  130. ModelType.value_of(provider_model.model_type),
  131. obfuscated=True),
  132. "is_valid": provider_model.is_valid
  133. })
  134. provider_parameter_dict[key]['models'] = models
  135. provider_config_dict['providers'] = list(provider_parameter_dict.values())
  136. providers_list[model_provider_name] = provider_config_dict
  137. return providers_list
  138. def custom_provider_config_validate(self, provider_name: str, config: dict) -> None:
  139. """
  140. validate custom provider config.
  141. :param provider_name:
  142. :param config:
  143. :return:
  144. :raises CredentialsValidateFailedError: When the config credential verification fails.
  145. """
  146. # get model provider rules
  147. model_provider_rules = ModelProviderFactory.get_provider_rule(provider_name)
  148. if model_provider_rules['model_flexibility'] != 'fixed':
  149. raise ValueError('Only support fixed model provider')
  150. # only support provider type CUSTOM
  151. if ProviderType.CUSTOM.value not in model_provider_rules['support_provider_types']:
  152. raise ValueError('Only support provider type CUSTOM')
  153. # validate provider config
  154. model_provider_class = ModelProviderFactory.get_model_provider_class(provider_name)
  155. model_provider_class.is_provider_credentials_valid_or_raise(config)
  156. def save_custom_provider_config(self, tenant_id: str, provider_name: str, config: dict) -> None:
  157. """
  158. save custom provider config.
  159. :param tenant_id:
  160. :param provider_name:
  161. :param config:
  162. :return:
  163. """
  164. # validate custom provider config
  165. self.custom_provider_config_validate(provider_name, config)
  166. # get provider
  167. provider = db.session.query(Provider) \
  168. .filter(
  169. Provider.tenant_id == tenant_id,
  170. Provider.provider_name == provider_name,
  171. Provider.provider_type == ProviderType.CUSTOM.value
  172. ).first()
  173. model_provider_class = ModelProviderFactory.get_model_provider_class(provider_name)
  174. encrypted_config = model_provider_class.encrypt_provider_credentials(tenant_id, config)
  175. # save provider
  176. if provider:
  177. provider.encrypted_config = json.dumps(encrypted_config)
  178. provider.is_valid = True
  179. provider.updated_at = datetime.datetime.utcnow()
  180. db.session.commit()
  181. else:
  182. provider = Provider(
  183. tenant_id=tenant_id,
  184. provider_name=provider_name,
  185. provider_type=ProviderType.CUSTOM.value,
  186. encrypted_config=json.dumps(encrypted_config),
  187. is_valid=True
  188. )
  189. db.session.add(provider)
  190. db.session.commit()
  191. def delete_custom_provider(self, tenant_id: str, provider_name: str) -> None:
  192. """
  193. delete custom provider.
  194. :param tenant_id:
  195. :param provider_name:
  196. :return:
  197. """
  198. # get provider
  199. provider = db.session.query(Provider) \
  200. .filter(
  201. Provider.tenant_id == tenant_id,
  202. Provider.provider_name == provider_name,
  203. Provider.provider_type == ProviderType.CUSTOM.value
  204. ).first()
  205. if provider:
  206. try:
  207. self.switch_preferred_provider(tenant_id, provider_name, ProviderType.SYSTEM.value)
  208. except ValueError:
  209. pass
  210. db.session.delete(provider)
  211. db.session.commit()
  212. def custom_provider_model_config_validate(self,
  213. provider_name: str,
  214. model_name: str,
  215. model_type: str,
  216. config: dict) -> None:
  217. """
  218. validate custom provider model config.
  219. :param provider_name:
  220. :param model_name:
  221. :param model_type:
  222. :param config:
  223. :return:
  224. :raises CredentialsValidateFailedError: When the config credential verification fails.
  225. """
  226. # get model provider rules
  227. model_provider_rules = ModelProviderFactory.get_provider_rule(provider_name)
  228. if model_provider_rules['model_flexibility'] != 'configurable':
  229. raise ValueError('Only support configurable model provider')
  230. # only support provider type CUSTOM
  231. if ProviderType.CUSTOM.value not in model_provider_rules['support_provider_types']:
  232. raise ValueError('Only support provider type CUSTOM')
  233. # validate provider model config
  234. model_type = ModelType.value_of(model_type)
  235. model_provider_class = ModelProviderFactory.get_model_provider_class(provider_name)
  236. model_provider_class.is_model_credentials_valid_or_raise(model_name, model_type, config)
  237. def add_or_save_custom_provider_model_config(self,
  238. tenant_id: str,
  239. provider_name: str,
  240. model_name: str,
  241. model_type: str,
  242. config: dict) -> None:
  243. """
  244. Add or save custom provider model config.
  245. :param tenant_id:
  246. :param provider_name:
  247. :param model_name:
  248. :param model_type:
  249. :param config:
  250. :return:
  251. """
  252. # validate custom provider model config
  253. self.custom_provider_model_config_validate(provider_name, model_name, model_type, config)
  254. # get provider
  255. provider = db.session.query(Provider) \
  256. .filter(
  257. Provider.tenant_id == tenant_id,
  258. Provider.provider_name == provider_name,
  259. Provider.provider_type == ProviderType.CUSTOM.value
  260. ).first()
  261. if not provider:
  262. provider = Provider(
  263. tenant_id=tenant_id,
  264. provider_name=provider_name,
  265. provider_type=ProviderType.CUSTOM.value,
  266. is_valid=True
  267. )
  268. db.session.add(provider)
  269. db.session.commit()
  270. elif not provider.is_valid:
  271. provider.is_valid = True
  272. provider.encrypted_config = None
  273. db.session.commit()
  274. model_provider_class = ModelProviderFactory.get_model_provider_class(provider_name)
  275. encrypted_config = model_provider_class.encrypt_model_credentials(
  276. tenant_id,
  277. model_name,
  278. ModelType.value_of(model_type),
  279. config
  280. )
  281. # get provider model
  282. provider_model = db.session.query(ProviderModel) \
  283. .filter(
  284. ProviderModel.tenant_id == tenant_id,
  285. ProviderModel.provider_name == provider_name,
  286. ProviderModel.model_name == model_name,
  287. ProviderModel.model_type == model_type
  288. ).first()
  289. if provider_model:
  290. provider_model.encrypted_config = json.dumps(encrypted_config)
  291. provider_model.is_valid = True
  292. db.session.commit()
  293. else:
  294. provider_model = ProviderModel(
  295. tenant_id=tenant_id,
  296. provider_name=provider_name,
  297. model_name=model_name,
  298. model_type=model_type,
  299. encrypted_config=json.dumps(encrypted_config),
  300. is_valid=True
  301. )
  302. db.session.add(provider_model)
  303. db.session.commit()
  304. def delete_custom_provider_model(self,
  305. tenant_id: str,
  306. provider_name: str,
  307. model_name: str,
  308. model_type: str) -> None:
  309. """
  310. delete custom provider model.
  311. :param tenant_id:
  312. :param provider_name:
  313. :param model_name:
  314. :param model_type:
  315. :return:
  316. """
  317. # get provider model
  318. provider_model = db.session.query(ProviderModel) \
  319. .filter(
  320. ProviderModel.tenant_id == tenant_id,
  321. ProviderModel.provider_name == provider_name,
  322. ProviderModel.model_name == model_name,
  323. ProviderModel.model_type == model_type
  324. ).first()
  325. if provider_model:
  326. db.session.delete(provider_model)
  327. db.session.commit()
  328. def switch_preferred_provider(self, tenant_id: str, provider_name: str, preferred_provider_type: str) -> None:
  329. """
  330. switch preferred provider.
  331. :param tenant_id:
  332. :param provider_name:
  333. :param preferred_provider_type:
  334. :return:
  335. """
  336. provider_type = ProviderType.value_of(preferred_provider_type)
  337. if not provider_type:
  338. raise ValueError(f'Invalid preferred provider type: {preferred_provider_type}')
  339. model_provider_rules = ModelProviderFactory.get_provider_rule(provider_name)
  340. if preferred_provider_type not in model_provider_rules['support_provider_types']:
  341. raise ValueError(f'Not support provider type: {preferred_provider_type}')
  342. model_provider = ModelProviderFactory.get_model_provider_class(provider_name)
  343. if not model_provider.is_provider_type_system_supported():
  344. return
  345. # get preferred provider
  346. preferred_model_provider = db.session.query(TenantPreferredModelProvider) \
  347. .filter(
  348. TenantPreferredModelProvider.tenant_id == tenant_id,
  349. TenantPreferredModelProvider.provider_name == provider_name
  350. ).first()
  351. if preferred_model_provider:
  352. preferred_model_provider.preferred_provider_type = preferred_provider_type
  353. else:
  354. preferred_model_provider = TenantPreferredModelProvider(
  355. tenant_id=tenant_id,
  356. provider_name=provider_name,
  357. preferred_provider_type=preferred_provider_type
  358. )
  359. db.session.add(preferred_model_provider)
  360. db.session.commit()
  361. def get_default_model_of_model_type(self, tenant_id: str, model_type: str) -> Optional[TenantDefaultModel]:
  362. """
  363. get default model of model type.
  364. :param tenant_id:
  365. :param model_type:
  366. :return:
  367. """
  368. return ModelFactory.get_default_model(tenant_id, ModelType.value_of(model_type))
  369. def update_default_model_of_model_type(self,
  370. tenant_id: str,
  371. model_type: str,
  372. provider_name: str,
  373. model_name: str) -> TenantDefaultModel:
  374. """
  375. update default model of model type.
  376. :param tenant_id:
  377. :param model_type:
  378. :param provider_name:
  379. :param model_name:
  380. :return:
  381. """
  382. return ModelFactory.update_default_model(tenant_id, ModelType.value_of(model_type), provider_name, model_name)
  383. def get_valid_model_list(self, tenant_id: str, model_type: str) -> list:
  384. """
  385. get valid model list.
  386. :param tenant_id:
  387. :param model_type:
  388. :return:
  389. """
  390. valid_model_list = []
  391. # get model provider rules
  392. model_provider_rules = ModelProviderFactory.get_provider_rules()
  393. for model_provider_name, model_provider_rule in model_provider_rules.items():
  394. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  395. if not model_provider:
  396. continue
  397. model_list = model_provider.get_supported_model_list(ModelType.value_of(model_type))
  398. provider = model_provider.provider
  399. for model in model_list:
  400. valid_model_dict = {
  401. "model_name": model['id'],
  402. "model_type": model_type,
  403. "model_provider": {
  404. "provider_name": provider.provider_name,
  405. "provider_type": provider.provider_type
  406. },
  407. 'features': []
  408. }
  409. if 'features' in model:
  410. valid_model_dict['features'] = model['features']
  411. if provider.provider_type == ProviderType.SYSTEM.value:
  412. valid_model_dict['model_provider']['quota_type'] = provider.quota_type
  413. valid_model_dict['model_provider']['quota_unit'] = model_provider_rule['system_config']['quota_unit']
  414. valid_model_dict['model_provider']['quota_limit'] = provider.quota_limit
  415. valid_model_dict['model_provider']['quota_used'] = provider.quota_used
  416. valid_model_list.append(valid_model_dict)
  417. return valid_model_list
  418. def get_model_parameter_rules(self, tenant_id: str, model_provider_name: str, model_name: str, model_type: str) \
  419. -> ModelKwargsRules:
  420. """
  421. get model parameter rules.
  422. It depends on preferred provider in use.
  423. :param tenant_id:
  424. :param model_provider_name:
  425. :param model_name:
  426. :param model_type:
  427. :return:
  428. """
  429. # get model provider
  430. model_provider = ModelProviderFactory.get_preferred_model_provider(tenant_id, model_provider_name)
  431. if not model_provider:
  432. # get empty model provider
  433. return ModelKwargsRules()
  434. # get model parameter rules
  435. return model_provider.get_model_parameter_rules(model_name, ModelType.value_of(model_type))