您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

datasource.py 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. from collections.abc import Generator
  2. from typing import Any, Optional
  3. from pydantic import BaseModel
  4. from core.plugin.entities.plugin import GenericProviderID, ToolProviderID
  5. from core.plugin.entities.plugin_daemon import PluginBasicBooleanResponse, PluginToolProviderEntity
  6. from core.plugin.manager.base import BasePluginManager
  7. from core.tools.entities.tool_entities import ToolInvokeMessage, ToolParameter
  8. class PluginDatasourceManager(BasePluginManager):
  9. def fetch_datasource_providers(self, tenant_id: str) -> list[PluginToolProviderEntity]:
  10. """
  11. Fetch datasource providers for the given tenant.
  12. """
  13. def transformer(json_response: dict[str, Any]) -> dict:
  14. for provider in json_response.get("data", []):
  15. declaration = provider.get("declaration", {}) or {}
  16. provider_name = declaration.get("identity", {}).get("name")
  17. for tool in declaration.get("tools", []):
  18. tool["identity"]["provider"] = provider_name
  19. return json_response
  20. response = self._request_with_plugin_daemon_response(
  21. "GET",
  22. f"plugin/{tenant_id}/management/datasources",
  23. list[PluginToolProviderEntity],
  24. params={"page": 1, "page_size": 256},
  25. transformer=transformer,
  26. )
  27. for provider in response:
  28. provider.declaration.identity.name = f"{provider.plugin_id}/{provider.declaration.identity.name}"
  29. # override the provider name for each tool to plugin_id/provider_name
  30. for tool in provider.declaration.tools:
  31. tool.identity.provider = provider.declaration.identity.name
  32. return response
  33. def fetch_datasource_provider(self, tenant_id: str, provider: str) -> PluginToolProviderEntity:
  34. """
  35. Fetch datasource provider for the given tenant and plugin.
  36. """
  37. tool_provider_id = ToolProviderID(provider)
  38. def transformer(json_response: dict[str, Any]) -> dict:
  39. data = json_response.get("data")
  40. if data:
  41. for datasource in data.get("declaration", {}).get("datasources", []):
  42. datasource["identity"]["provider"] = tool_provider_id.provider_name
  43. return json_response
  44. response = self._request_with_plugin_daemon_response(
  45. "GET",
  46. f"plugin/{tenant_id}/management/datasources",
  47. PluginToolProviderEntity,
  48. params={"provider": tool_provider_id.provider_name, "plugin_id": tool_provider_id.plugin_id},
  49. transformer=transformer,
  50. )
  51. response.declaration.identity.name = f"{response.plugin_id}/{response.declaration.identity.name}"
  52. # override the provider name for each tool to plugin_id/provider_name
  53. for tool in response.declaration.tools:
  54. tool.identity.provider = response.declaration.identity.name
  55. return response
  56. def invoke_first_step(
  57. self,
  58. tenant_id: str,
  59. user_id: str,
  60. datasource_provider: str,
  61. datasource_name: str,
  62. credentials: dict[str, Any],
  63. datasource_parameters: dict[str, Any],
  64. ) -> Generator[ToolInvokeMessage, None, None]:
  65. """
  66. Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
  67. """
  68. datasource_provider_id = GenericProviderID(datasource_provider)
  69. response = self._request_with_plugin_daemon_response_stream(
  70. "POST",
  71. f"plugin/{tenant_id}/dispatch/datasource/{online_document}/pages",
  72. ToolInvokeMessage,
  73. data={
  74. "user_id": user_id,
  75. "data": {
  76. "provider": datasource_provider_id.provider_name,
  77. "datasource": datasource_name,
  78. "credentials": credentials,
  79. "datasource_parameters": datasource_parameters,
  80. },
  81. },
  82. headers={
  83. "X-Plugin-ID": datasource_provider_id.plugin_id,
  84. "Content-Type": "application/json",
  85. },
  86. )
  87. return response
  88. def invoke_second_step(
  89. self,
  90. tenant_id: str,
  91. user_id: str,
  92. datasource_provider: str,
  93. datasource_name: str,
  94. credentials: dict[str, Any],
  95. datasource_parameters: dict[str, Any],
  96. ) -> Generator[ToolInvokeMessage, None, None]:
  97. """
  98. Invoke the datasource with the given tenant, user, plugin, provider, name, credentials and parameters.
  99. """
  100. datasource_provider_id = GenericProviderID(datasource_provider)
  101. response = self._request_with_plugin_daemon_response_stream(
  102. "POST",
  103. f"plugin/{tenant_id}/dispatch/datasource/invoke_second_step",
  104. ToolInvokeMessage,
  105. data={
  106. "user_id": user_id,
  107. "data": {
  108. "provider": datasource_provider_id.provider_name,
  109. "datasource": datasource_name,
  110. "credentials": credentials,
  111. "datasource_parameters": datasource_parameters,
  112. },
  113. },
  114. headers={
  115. "X-Plugin-ID": datasource_provider_id.plugin_id,
  116. "Content-Type": "application/json",
  117. },
  118. )
  119. return response
  120. def validate_provider_credentials(
  121. self, tenant_id: str, user_id: str, provider: str, credentials: dict[str, Any]
  122. ) -> bool:
  123. """
  124. validate the credentials of the provider
  125. """
  126. tool_provider_id = GenericProviderID(provider)
  127. response = self._request_with_plugin_daemon_response_stream(
  128. "POST",
  129. f"plugin/{tenant_id}/dispatch/tool/validate_credentials",
  130. PluginBasicBooleanResponse,
  131. data={
  132. "user_id": user_id,
  133. "data": {
  134. "provider": tool_provider_id.provider_name,
  135. "credentials": credentials,
  136. },
  137. },
  138. headers={
  139. "X-Plugin-ID": tool_provider_id.plugin_id,
  140. "Content-Type": "application/json",
  141. },
  142. )
  143. for resp in response:
  144. return resp.result
  145. return False
  146. def get_runtime_parameters(
  147. self,
  148. tenant_id: str,
  149. user_id: str,
  150. provider: str,
  151. credentials: dict[str, Any],
  152. datasource: str,
  153. conversation_id: Optional[str] = None,
  154. app_id: Optional[str] = None,
  155. message_id: Optional[str] = None,
  156. ) -> list[ToolParameter]:
  157. """
  158. get the runtime parameters of the datasource
  159. """
  160. datasource_provider_id = GenericProviderID(provider)
  161. class RuntimeParametersResponse(BaseModel):
  162. parameters: list[ToolParameter]
  163. response = self._request_with_plugin_daemon_response_stream(
  164. "POST",
  165. f"plugin/{tenant_id}/dispatch/datasource/get_runtime_parameters",
  166. RuntimeParametersResponse,
  167. data={
  168. "user_id": user_id,
  169. "conversation_id": conversation_id,
  170. "app_id": app_id,
  171. "message_id": message_id,
  172. "data": {
  173. "provider": datasource_provider_id.provider_name,
  174. "datasource": datasource,
  175. "credentials": credentials,
  176. },
  177. },
  178. headers={
  179. "X-Plugin-ID": datasource_provider_id.plugin_id,
  180. "Content-Type": "application/json",
  181. },
  182. )
  183. for resp in response:
  184. return resp.parameters
  185. return []