Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

model_provider_service.py 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. import logging
  2. from typing import Optional
  3. from core.entities.model_entities import ModelWithProviderEntity, ProviderModelWithStatusEntity
  4. from core.model_runtime.entities.model_entities import ModelType, ParameterRule
  5. from core.model_runtime.model_providers.model_provider_factory import ModelProviderFactory
  6. from core.provider_manager import ProviderManager
  7. from models.provider import ProviderType
  8. from services.entities.model_provider_entities import (
  9. CustomConfigurationResponse,
  10. CustomConfigurationStatus,
  11. DefaultModelResponse,
  12. ModelWithProviderEntityResponse,
  13. ProviderResponse,
  14. ProviderWithModelsResponse,
  15. SimpleProviderEntityResponse,
  16. SystemConfigurationResponse,
  17. )
  18. from services.errors.app_model_config import ProviderNotFoundError
  19. logger = logging.getLogger(__name__)
  20. class ModelProviderService:
  21. """
  22. Model Provider Service
  23. """
  24. def __init__(self) -> None:
  25. self.provider_manager = ProviderManager()
  26. def _get_provider_configuration(self, tenant_id: str, provider: str):
  27. """
  28. Get provider configuration or raise exception if not found.
  29. Args:
  30. tenant_id: Workspace identifier
  31. provider: Provider name
  32. Returns:
  33. Provider configuration instance
  34. Raises:
  35. ProviderNotFoundError: If provider doesn't exist
  36. """
  37. # Get all provider configurations of the current workspace
  38. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  39. provider_configuration = provider_configurations.get(provider)
  40. if not provider_configuration:
  41. raise ProviderNotFoundError(f"Provider {provider} does not exist.")
  42. return provider_configuration
  43. def get_provider_list(self, tenant_id: str, model_type: Optional[str] = None) -> list[ProviderResponse]:
  44. """
  45. get provider list.
  46. :param tenant_id: workspace id
  47. :param model_type: model type
  48. :return:
  49. """
  50. # Get all provider configurations of the current workspace
  51. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  52. provider_responses = []
  53. for provider_configuration in provider_configurations.values():
  54. if model_type:
  55. model_type_entity = ModelType.value_of(model_type)
  56. if model_type_entity not in provider_configuration.provider.supported_model_types:
  57. continue
  58. provider_config = provider_configuration.custom_configuration.provider
  59. model_config = provider_configuration.custom_configuration.models
  60. can_added_models = provider_configuration.custom_configuration.can_added_models
  61. provider_response = ProviderResponse(
  62. tenant_id=tenant_id,
  63. provider=provider_configuration.provider.provider,
  64. label=provider_configuration.provider.label,
  65. description=provider_configuration.provider.description,
  66. icon_small=provider_configuration.provider.icon_small,
  67. icon_large=provider_configuration.provider.icon_large,
  68. background=provider_configuration.provider.background,
  69. help=provider_configuration.provider.help,
  70. supported_model_types=provider_configuration.provider.supported_model_types,
  71. configurate_methods=provider_configuration.provider.configurate_methods,
  72. provider_credential_schema=provider_configuration.provider.provider_credential_schema,
  73. model_credential_schema=provider_configuration.provider.model_credential_schema,
  74. preferred_provider_type=provider_configuration.preferred_provider_type,
  75. custom_configuration=CustomConfigurationResponse(
  76. status=CustomConfigurationStatus.ACTIVE
  77. if provider_configuration.is_custom_configuration_available()
  78. else CustomConfigurationStatus.NO_CONFIGURE,
  79. current_credential_id=getattr(provider_config, "current_credential_id", None),
  80. current_credential_name=getattr(provider_config, "current_credential_name", None),
  81. available_credentials=getattr(provider_config, "available_credentials", []),
  82. custom_models=model_config,
  83. can_added_models=can_added_models,
  84. ),
  85. system_configuration=SystemConfigurationResponse(
  86. enabled=provider_configuration.system_configuration.enabled,
  87. current_quota_type=provider_configuration.system_configuration.current_quota_type,
  88. quota_configurations=provider_configuration.system_configuration.quota_configurations,
  89. ),
  90. )
  91. provider_responses.append(provider_response)
  92. return provider_responses
  93. def get_models_by_provider(self, tenant_id: str, provider: str) -> list[ModelWithProviderEntityResponse]:
  94. """
  95. get provider models.
  96. For the model provider page,
  97. only supports passing in a single provider to query the list of supported models.
  98. :param tenant_id: workspace id
  99. :param provider: provider name
  100. :return:
  101. """
  102. # Get all provider configurations of the current workspace
  103. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  104. # Get provider available models
  105. return [
  106. ModelWithProviderEntityResponse(tenant_id=tenant_id, model=model)
  107. for model in provider_configurations.get_models(provider=provider)
  108. ]
  109. def get_provider_credential(
  110. self, tenant_id: str, provider: str, credential_id: Optional[str] = None
  111. ) -> Optional[dict]:
  112. """
  113. get provider credentials.
  114. :param tenant_id: workspace id
  115. :param provider: provider name
  116. :param credential_id: credential id, if not provided, return current used credentials
  117. :return:
  118. """
  119. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  120. return provider_configuration.get_provider_credential(credential_id=credential_id) # type: ignore
  121. def validate_provider_credentials(self, tenant_id: str, provider: str, credentials: dict) -> None:
  122. """
  123. validate provider credentials before saving.
  124. :param tenant_id: workspace id
  125. :param provider: provider name
  126. :param credentials: provider credentials dict
  127. """
  128. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  129. provider_configuration.validate_provider_credentials(credentials)
  130. def create_provider_credential(
  131. self, tenant_id: str, provider: str, credentials: dict, credential_name: str | None
  132. ) -> None:
  133. """
  134. Create and save new provider credentials.
  135. :param tenant_id: workspace id
  136. :param provider: provider name
  137. :param credentials: provider credentials dict
  138. :param credential_name: credential name
  139. :return:
  140. """
  141. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  142. provider_configuration.create_provider_credential(credentials, credential_name)
  143. def update_provider_credential(
  144. self,
  145. tenant_id: str,
  146. provider: str,
  147. credentials: dict,
  148. credential_id: str,
  149. credential_name: str | None,
  150. ) -> None:
  151. """
  152. update a saved provider credential (by credential_id).
  153. :param tenant_id: workspace id
  154. :param provider: provider name
  155. :param credentials: provider credentials dict
  156. :param credential_id: credential id
  157. :param credential_name: credential name
  158. :return:
  159. """
  160. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  161. provider_configuration.update_provider_credential(
  162. credential_id=credential_id,
  163. credentials=credentials,
  164. credential_name=credential_name,
  165. )
  166. def remove_provider_credential(self, tenant_id: str, provider: str, credential_id: str) -> None:
  167. """
  168. remove a saved provider credential (by credential_id).
  169. :param tenant_id: workspace id
  170. :param provider: provider name
  171. :param credential_id: credential id
  172. :return:
  173. """
  174. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  175. provider_configuration.delete_provider_credential(credential_id=credential_id)
  176. def switch_active_provider_credential(self, tenant_id: str, provider: str, credential_id: str) -> None:
  177. """
  178. :param tenant_id: workspace id
  179. :param provider: provider name
  180. :param credential_id: credential id
  181. :return:
  182. """
  183. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  184. provider_configuration.switch_active_provider_credential(credential_id=credential_id)
  185. def get_model_credential(
  186. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str | None
  187. ) -> Optional[dict]:
  188. """
  189. Retrieve model-specific credentials.
  190. :param tenant_id: workspace id
  191. :param provider: provider name
  192. :param model_type: model type
  193. :param model: model name
  194. :param credential_id: Optional credential ID, uses current if not provided
  195. :return:
  196. """
  197. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  198. return provider_configuration.get_custom_model_credential( # type: ignore
  199. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  200. )
  201. def validate_model_credentials(
  202. self, tenant_id: str, provider: str, model_type: str, model: str, credentials: dict
  203. ) -> None:
  204. """
  205. validate model credentials.
  206. :param tenant_id: workspace id
  207. :param provider: provider name
  208. :param model_type: model type
  209. :param model: model name
  210. :param credentials: model credentials dict
  211. :return:
  212. """
  213. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  214. provider_configuration.validate_custom_model_credentials(
  215. model_type=ModelType.value_of(model_type), model=model, credentials=credentials
  216. )
  217. def create_model_credential(
  218. self, tenant_id: str, provider: str, model_type: str, model: str, credentials: dict, credential_name: str | None
  219. ) -> None:
  220. """
  221. create and save model credentials.
  222. :param tenant_id: workspace id
  223. :param provider: provider name
  224. :param model_type: model type
  225. :param model: model name
  226. :param credentials: model credentials dict
  227. :param credential_name: credential name
  228. :return:
  229. """
  230. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  231. provider_configuration.create_custom_model_credential(
  232. model_type=ModelType.value_of(model_type),
  233. model=model,
  234. credentials=credentials,
  235. credential_name=credential_name,
  236. )
  237. def update_model_credential(
  238. self,
  239. tenant_id: str,
  240. provider: str,
  241. model_type: str,
  242. model: str,
  243. credentials: dict,
  244. credential_id: str,
  245. credential_name: str | None,
  246. ) -> None:
  247. """
  248. update model credentials.
  249. :param tenant_id: workspace id
  250. :param provider: provider name
  251. :param model_type: model type
  252. :param model: model name
  253. :param credentials: model credentials dict
  254. :param credential_id: credential id
  255. :param credential_name: credential name
  256. :return:
  257. """
  258. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  259. provider_configuration.update_custom_model_credential(
  260. model_type=ModelType.value_of(model_type),
  261. model=model,
  262. credentials=credentials,
  263. credential_id=credential_id,
  264. credential_name=credential_name,
  265. )
  266. def remove_model_credential(
  267. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  268. ) -> None:
  269. """
  270. remove model credentials.
  271. :param tenant_id: workspace id
  272. :param provider: provider name
  273. :param model_type: model type
  274. :param model: model name
  275. :param credential_id: credential id
  276. :return:
  277. """
  278. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  279. provider_configuration.delete_custom_model_credential(
  280. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  281. )
  282. def switch_active_custom_model_credential(
  283. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  284. ) -> None:
  285. """
  286. switch model credentials.
  287. :param tenant_id: workspace id
  288. :param provider: provider name
  289. :param model_type: model type
  290. :param model: model name
  291. :param credential_id: credential id
  292. :return:
  293. """
  294. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  295. provider_configuration.switch_custom_model_credential(
  296. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  297. )
  298. def add_model_credential_to_model_list(
  299. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  300. ) -> None:
  301. """
  302. add model credentials to model list.
  303. :param tenant_id: workspace id
  304. :param provider: provider name
  305. :param model_type: model type
  306. :param model: model name
  307. :param credential_id: credential id
  308. :return:
  309. """
  310. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  311. provider_configuration.add_model_credential_to_model(
  312. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  313. )
  314. def remove_model(self, tenant_id: str, provider: str, model_type: str, model: str) -> None:
  315. """
  316. remove model credentials.
  317. :param tenant_id: workspace id
  318. :param provider: provider name
  319. :param model_type: model type
  320. :param model: model name
  321. :return:
  322. """
  323. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  324. provider_configuration.delete_custom_model(model_type=ModelType.value_of(model_type), model=model)
  325. def get_models_by_model_type(self, tenant_id: str, model_type: str) -> list[ProviderWithModelsResponse]:
  326. """
  327. get models by model type.
  328. :param tenant_id: workspace id
  329. :param model_type: model type
  330. :return:
  331. """
  332. # Get all provider configurations of the current workspace
  333. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  334. # Get provider available models
  335. models = provider_configurations.get_models(model_type=ModelType.value_of(model_type), only_active=True)
  336. # Group models by provider
  337. provider_models: dict[str, list[ModelWithProviderEntity]] = {}
  338. for model in models:
  339. if model.provider.provider not in provider_models:
  340. provider_models[model.provider.provider] = []
  341. if model.deprecated:
  342. continue
  343. provider_models[model.provider.provider].append(model)
  344. # convert to ProviderWithModelsResponse list
  345. providers_with_models: list[ProviderWithModelsResponse] = []
  346. for provider, models in provider_models.items():
  347. if not models:
  348. continue
  349. first_model = models[0]
  350. providers_with_models.append(
  351. ProviderWithModelsResponse(
  352. tenant_id=tenant_id,
  353. provider=provider,
  354. label=first_model.provider.label,
  355. icon_small=first_model.provider.icon_small,
  356. icon_large=first_model.provider.icon_large,
  357. status=CustomConfigurationStatus.ACTIVE,
  358. models=[
  359. ProviderModelWithStatusEntity(
  360. model=model.model,
  361. label=model.label,
  362. model_type=model.model_type,
  363. features=model.features,
  364. fetch_from=model.fetch_from,
  365. model_properties=model.model_properties,
  366. status=model.status,
  367. load_balancing_enabled=model.load_balancing_enabled,
  368. )
  369. for model in models
  370. ],
  371. )
  372. )
  373. return providers_with_models
  374. def get_model_parameter_rules(self, tenant_id: str, provider: str, model: str) -> list[ParameterRule]:
  375. """
  376. get model parameter rules.
  377. Only supports LLM.
  378. :param tenant_id: workspace id
  379. :param provider: provider name
  380. :param model: model name
  381. :return:
  382. """
  383. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  384. # fetch credentials
  385. credentials = provider_configuration.get_current_credentials(model_type=ModelType.LLM, model=model)
  386. if not credentials:
  387. return []
  388. model_schema = provider_configuration.get_model_schema(
  389. model_type=ModelType.LLM, model=model, credentials=credentials
  390. )
  391. return model_schema.parameter_rules if model_schema else []
  392. def get_default_model_of_model_type(self, tenant_id: str, model_type: str) -> Optional[DefaultModelResponse]:
  393. """
  394. get default model of model type.
  395. :param tenant_id: workspace id
  396. :param model_type: model type
  397. :return:
  398. """
  399. model_type_enum = ModelType.value_of(model_type)
  400. try:
  401. result = self.provider_manager.get_default_model(tenant_id=tenant_id, model_type=model_type_enum)
  402. return (
  403. DefaultModelResponse(
  404. model=result.model,
  405. model_type=result.model_type,
  406. provider=SimpleProviderEntityResponse(
  407. tenant_id=tenant_id,
  408. provider=result.provider.provider,
  409. label=result.provider.label,
  410. icon_small=result.provider.icon_small,
  411. icon_large=result.provider.icon_large,
  412. supported_model_types=result.provider.supported_model_types,
  413. ),
  414. )
  415. if result
  416. else None
  417. )
  418. except Exception as e:
  419. logger.debug("get_default_model_of_model_type error: %s", e)
  420. return None
  421. def update_default_model_of_model_type(self, tenant_id: str, model_type: str, provider: str, model: str) -> None:
  422. """
  423. update default model of model type.
  424. :param tenant_id: workspace id
  425. :param model_type: model type
  426. :param provider: provider name
  427. :param model: model name
  428. :return:
  429. """
  430. model_type_enum = ModelType.value_of(model_type)
  431. self.provider_manager.update_default_model_record(
  432. tenant_id=tenant_id, model_type=model_type_enum, provider=provider, model=model
  433. )
  434. def get_model_provider_icon(
  435. self, tenant_id: str, provider: str, icon_type: str, lang: str
  436. ) -> tuple[Optional[bytes], Optional[str]]:
  437. """
  438. get model provider icon.
  439. :param tenant_id: workspace id
  440. :param provider: provider name
  441. :param icon_type: icon type (icon_small or icon_large)
  442. :param lang: language (zh_Hans or en_US)
  443. :return:
  444. """
  445. model_provider_factory = ModelProviderFactory(tenant_id)
  446. byte_data, mime_type = model_provider_factory.get_provider_icon(provider, icon_type, lang)
  447. return byte_data, mime_type
  448. def switch_preferred_provider(self, tenant_id: str, provider: str, preferred_provider_type: str) -> None:
  449. """
  450. switch preferred provider.
  451. :param tenant_id: workspace id
  452. :param provider: provider name
  453. :param preferred_provider_type: preferred provider type
  454. :return:
  455. """
  456. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  457. # Convert preferred_provider_type to ProviderType
  458. preferred_provider_type_enum = ProviderType.value_of(preferred_provider_type)
  459. # Switch preferred provider type
  460. provider_configuration.switch_preferred_provider_type(preferred_provider_type_enum)
  461. def enable_model(self, tenant_id: str, provider: str, model: str, model_type: str) -> None:
  462. """
  463. enable model.
  464. :param tenant_id: workspace id
  465. :param provider: provider name
  466. :param model: model name
  467. :param model_type: model type
  468. :return:
  469. """
  470. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  471. provider_configuration.enable_model(model=model, model_type=ModelType.value_of(model_type))
  472. def disable_model(self, tenant_id: str, provider: str, model: str, model_type: str) -> None:
  473. """
  474. disable model.
  475. :param tenant_id: workspace id
  476. :param provider: provider name
  477. :param model: model name
  478. :param model_type: model type
  479. :return:
  480. """
  481. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  482. provider_configuration.disable_model(model=model, model_type=ModelType.value_of(model_type))