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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. import logging
  2. from typing import Optional
  3. from core.entities.model_entities import ModelStatus, 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. provider_response = ProviderResponse(
  61. tenant_id=tenant_id,
  62. provider=provider_configuration.provider.provider,
  63. label=provider_configuration.provider.label,
  64. description=provider_configuration.provider.description,
  65. icon_small=provider_configuration.provider.icon_small,
  66. icon_large=provider_configuration.provider.icon_large,
  67. background=provider_configuration.provider.background,
  68. help=provider_configuration.provider.help,
  69. supported_model_types=provider_configuration.provider.supported_model_types,
  70. configurate_methods=provider_configuration.provider.configurate_methods,
  71. provider_credential_schema=provider_configuration.provider.provider_credential_schema,
  72. model_credential_schema=provider_configuration.provider.model_credential_schema,
  73. preferred_provider_type=provider_configuration.preferred_provider_type,
  74. custom_configuration=CustomConfigurationResponse(
  75. status=CustomConfigurationStatus.ACTIVE
  76. if provider_configuration.is_custom_configuration_available()
  77. else CustomConfigurationStatus.NO_CONFIGURE,
  78. current_credential_id=getattr(provider_config, "current_credential_id", None),
  79. current_credential_name=getattr(provider_config, "current_credential_name", None),
  80. available_credentials=getattr(provider_config, "available_credentials", []),
  81. custom_models=model_config,
  82. ),
  83. system_configuration=SystemConfigurationResponse(
  84. enabled=provider_configuration.system_configuration.enabled,
  85. current_quota_type=provider_configuration.system_configuration.current_quota_type,
  86. quota_configurations=provider_configuration.system_configuration.quota_configurations,
  87. ),
  88. )
  89. provider_responses.append(provider_response)
  90. return provider_responses
  91. def get_models_by_provider(self, tenant_id: str, provider: str) -> list[ModelWithProviderEntityResponse]:
  92. """
  93. get provider models.
  94. For the model provider page,
  95. only supports passing in a single provider to query the list of supported models.
  96. :param tenant_id: workspace id
  97. :param provider: provider name
  98. :return:
  99. """
  100. # Get all provider configurations of the current workspace
  101. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  102. # Get provider available models
  103. return [
  104. ModelWithProviderEntityResponse(tenant_id=tenant_id, model=model)
  105. for model in provider_configurations.get_models(provider=provider)
  106. ]
  107. def get_provider_credential(
  108. self, tenant_id: str, provider: str, credential_id: Optional[str] = None
  109. ) -> Optional[dict]:
  110. """
  111. get provider credentials.
  112. :param tenant_id: workspace id
  113. :param provider: provider name
  114. :param credential_id: credential id, if not provided, return current used credentials
  115. :return:
  116. """
  117. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  118. return provider_configuration.get_provider_credential(credential_id=credential_id) # type: ignore
  119. def validate_provider_credentials(self, tenant_id: str, provider: str, credentials: dict) -> None:
  120. """
  121. validate provider credentials before saving.
  122. :param tenant_id: workspace id
  123. :param provider: provider name
  124. :param credentials: provider credentials dict
  125. """
  126. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  127. provider_configuration.validate_provider_credentials(credentials)
  128. def create_provider_credential(
  129. self, tenant_id: str, provider: str, credentials: dict, credential_name: str
  130. ) -> None:
  131. """
  132. Create and save new provider credentials.
  133. :param tenant_id: workspace id
  134. :param provider: provider name
  135. :param credentials: provider credentials dict
  136. :param credential_name: credential name
  137. :return:
  138. """
  139. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  140. provider_configuration.create_provider_credential(credentials, credential_name)
  141. def update_provider_credential(
  142. self,
  143. tenant_id: str,
  144. provider: str,
  145. credentials: dict,
  146. credential_id: str,
  147. credential_name: str,
  148. ) -> None:
  149. """
  150. update a saved provider credential (by credential_id).
  151. :param tenant_id: workspace id
  152. :param provider: provider name
  153. :param credentials: provider credentials dict
  154. :param credential_id: credential id
  155. :param credential_name: credential name
  156. :return:
  157. """
  158. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  159. provider_configuration.update_provider_credential(
  160. credential_id=credential_id,
  161. credentials=credentials,
  162. credential_name=credential_name,
  163. )
  164. def remove_provider_credential(self, tenant_id: str, provider: str, credential_id: str) -> None:
  165. """
  166. remove a saved provider credential (by credential_id).
  167. :param tenant_id: workspace id
  168. :param provider: provider name
  169. :param credential_id: credential id
  170. :return:
  171. """
  172. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  173. provider_configuration.delete_provider_credential(credential_id=credential_id)
  174. def switch_active_provider_credential(self, tenant_id: str, provider: str, credential_id: str) -> None:
  175. """
  176. :param tenant_id: workspace id
  177. :param provider: provider name
  178. :param credential_id: credential id
  179. :return:
  180. """
  181. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  182. provider_configuration.switch_active_provider_credential(credential_id=credential_id)
  183. def get_model_credential(
  184. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str | None
  185. ) -> Optional[dict]:
  186. """
  187. Retrieve model-specific credentials.
  188. :param tenant_id: workspace id
  189. :param provider: provider name
  190. :param model_type: model type
  191. :param model: model name
  192. :param credential_id: Optional credential ID, uses current if not provided
  193. :return:
  194. """
  195. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  196. return provider_configuration.get_custom_model_credential( # type: ignore
  197. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  198. )
  199. def validate_model_credentials(
  200. self, tenant_id: str, provider: str, model_type: str, model: str, credentials: dict
  201. ) -> None:
  202. """
  203. validate model credentials.
  204. :param tenant_id: workspace id
  205. :param provider: provider name
  206. :param model_type: model type
  207. :param model: model name
  208. :param credentials: model credentials dict
  209. :return:
  210. """
  211. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  212. provider_configuration.validate_custom_model_credentials(
  213. model_type=ModelType.value_of(model_type), model=model, credentials=credentials
  214. )
  215. def create_model_credential(
  216. self, tenant_id: str, provider: str, model_type: str, model: str, credentials: dict, credential_name: str
  217. ) -> None:
  218. """
  219. create and save model credentials.
  220. :param tenant_id: workspace id
  221. :param provider: provider name
  222. :param model_type: model type
  223. :param model: model name
  224. :param credentials: model credentials dict
  225. :param credential_name: credential name
  226. :return:
  227. """
  228. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  229. provider_configuration.create_custom_model_credential(
  230. model_type=ModelType.value_of(model_type),
  231. model=model,
  232. credentials=credentials,
  233. credential_name=credential_name,
  234. )
  235. def update_model_credential(
  236. self,
  237. tenant_id: str,
  238. provider: str,
  239. model_type: str,
  240. model: str,
  241. credentials: dict,
  242. credential_id: str,
  243. credential_name: str,
  244. ) -> None:
  245. """
  246. update model credentials.
  247. :param tenant_id: workspace id
  248. :param provider: provider name
  249. :param model_type: model type
  250. :param model: model name
  251. :param credentials: model credentials dict
  252. :param credential_id: credential id
  253. :param credential_name: credential name
  254. :return:
  255. """
  256. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  257. provider_configuration.update_custom_model_credential(
  258. model_type=ModelType.value_of(model_type),
  259. model=model,
  260. credentials=credentials,
  261. credential_id=credential_id,
  262. credential_name=credential_name,
  263. )
  264. def remove_model_credential(
  265. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  266. ) -> None:
  267. """
  268. remove model credentials.
  269. :param tenant_id: workspace id
  270. :param provider: provider name
  271. :param model_type: model type
  272. :param model: model name
  273. :param credential_id: credential id
  274. :return:
  275. """
  276. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  277. provider_configuration.delete_custom_model_credential(
  278. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  279. )
  280. def switch_active_custom_model_credential(
  281. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  282. ) -> None:
  283. """
  284. switch model credentials.
  285. :param tenant_id: workspace id
  286. :param provider: provider name
  287. :param model_type: model type
  288. :param model: model name
  289. :param credential_id: credential id
  290. :return:
  291. """
  292. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  293. provider_configuration.switch_custom_model_credential(
  294. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  295. )
  296. def add_model_credential_to_model_list(
  297. self, tenant_id: str, provider: str, model_type: str, model: str, credential_id: str
  298. ) -> None:
  299. """
  300. add model credentials to model list.
  301. :param tenant_id: workspace id
  302. :param provider: provider name
  303. :param model_type: model type
  304. :param model: model name
  305. :param credential_id: credential id
  306. :return:
  307. """
  308. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  309. provider_configuration.add_model_credential_to_model(
  310. model_type=ModelType.value_of(model_type), model=model, credential_id=credential_id
  311. )
  312. def remove_model(self, tenant_id: str, provider: str, model_type: str, model: str) -> None:
  313. """
  314. remove model credentials.
  315. :param tenant_id: workspace id
  316. :param provider: provider name
  317. :param model_type: model type
  318. :param model: model name
  319. :return:
  320. """
  321. provider_configuration = self._get_provider_configuration(tenant_id, provider)
  322. provider_configuration.delete_custom_model(model_type=ModelType.value_of(model_type), model=model)
  323. def get_models_by_model_type(self, tenant_id: str, model_type: str) -> list[ProviderWithModelsResponse]:
  324. """
  325. get models by model type.
  326. :param tenant_id: workspace id
  327. :param model_type: model type
  328. :return:
  329. """
  330. # Get all provider configurations of the current workspace
  331. provider_configurations = self.provider_manager.get_configurations(tenant_id)
  332. # Get provider available models
  333. models = provider_configurations.get_models(model_type=ModelType.value_of(model_type))
  334. # Group models by provider
  335. provider_models: dict[str, list[ModelWithProviderEntity]] = {}
  336. for model in models:
  337. if model.provider.provider not in provider_models:
  338. provider_models[model.provider.provider] = []
  339. if model.deprecated:
  340. continue
  341. if model.status != ModelStatus.ACTIVE:
  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))